Skip to main content
Glama

Medplum

Official
by medplum
MedplumCodeBlock.tsx4.37 kB
import CodeBlock, { Props } from '@theme/CodeBlock'; import { JSX } from 'react'; const BLOCK_START_PATTERN = /^\s*\/\/\s*start-block\s+([A-Za-z_-]*)/; const BLOCK_END_PATTERN = /^\s*\/\/\s*end-block\s+([A-Za-z_-]*)/; interface MedplumCodeBlockProps extends Props { readonly selectLines?: number[][]; readonly selectBlocks?: string; } export default function MedplumCodeBlock({ children, selectLines, selectBlocks, ...props }: MedplumCodeBlockProps): JSX.Element { let code = children as string; if (selectLines && selectBlocks) { throw new Error("Only one of 'selectLines' or 'selectBlocks' can be specified"); } let codeLines: string[] = code.split('\n'); // Get the line ranges for all the blocks that have been selected. const linesToRemove = new Set<number>(); const blockRanges = extractBlocks(codeLines); // Save the line numbers of the magic comments, so that they can be removed later Object.values(blockRanges) .flat() .forEach((lineNumber) => linesToRemove.add(lineNumber)); if (selectBlocks) { const selectBlockNames = selectBlocks.split(',').map((s) => s.trim()); selectLines = selectBlockNames.map((block) => { if (!(block in blockRanges)) { throw new Error(`No such code block: '${block}'`); } return blockRanges[block]; }); } // Set all the magic comment lines to 'null' to be filtered out later // We do this to preserve line numbers before slicing codeLines linesToRemove.forEach((lineNumber) => (codeLines[lineNumber - 1] = null)); // For each line range to be selected, grab the slice from the original code if (selectLines) { codeLines = selectLines.flatMap((range) => range.length === 1 ? codeLines[range[0] - 1] : codeLines.slice(range[0] - 1, range[1]) ); } // Filter out lines that were set to null codeLines = codeLines.filter((line) => line !== null); // Find the minimum indentation const minIndent = findMinimumIndentation(codeLines); // Remove the minimum indentation from all lines codeLines = codeLines.map((line) => removeIndentation(line, minIndent)); code = codeLines.join('\n'); return <CodeBlock {...props}>{code}</CodeBlock>; } /** * Returns an map from the block name to the start and stop lines for that block * @param codeLines - Array of code lines. * @returns The code blocks. */ function extractBlocks(codeLines: string[]): Record<string, [number, number]> { const results: Record<string, [number, number | undefined]> = {}; for (let i = 0; i < codeLines.length; i++) { const line = codeLines[i]; // If we are beginning a new block, save the starting line number const startMatch = BLOCK_START_PATTERN.exec(line); if (startMatch) { const blockName = startMatch[1]; if (blockName in results) { throw new Error(`Block ${blockName} declared more than once`); } results[blockName] = [i + 1, undefined]; } const endMatch = BLOCK_END_PATTERN.exec(line); if (endMatch) { const blockName = endMatch[1]; if (!(blockName in results)) { throw new Error(`Block ${blockName} is closed on line ${i + 1} before it is started`); } if (results[blockName][1]) { throw new Error( `Block ${blockName} closed more than once. First on line ${results[blockName][1]} and then on line ${i + 1})` ); } results[blockName][1] = i + 1; } } const unterminatedBlocks = Object.entries(results).filter(([_, range]) => !range[1]); if (unterminatedBlocks.length > 0) { throw new Error(`Unterminated blocks: ${unterminatedBlocks.map((e) => e[0]).join(', ')}`); } return results; } /** * Finds the minimum indentation across all non-empty lines * @param lines - Array of code lines. * @returns The minimum indentation. */ function findMinimumIndentation(lines: string[]): number { const indentations = lines.filter((line) => line.trim().length > 0).map((line) => line.match(/^\s*/)[0].length); return Math.min(...indentations); } /** * Removes a specified amount of indentation from a line * @param line - The line to remove indentation from. * @param indent - The amount of indentation to remove. * @returns The line with reduced indentation. */ function removeIndentation(line: string, indent: number): string { return line.slice(indent); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/medplum/medplum'

If you have feedback or need assistance with the MCP directory API, please join our Discord server