123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- // Copyright (c) Jupyter Development Team.
- // Distributed under the terms of the Modified BSD License.
- /**
- * The namespace for code block functions which help
- * in extract code from markdown text
- */
- export
- namespace MarkdownCodeBlocks {
- export
- const markdownMarkers: string[] = ["```", "~~~~", "`"]
- const markdownExtensions: string[] = [
- '.markdown',
- '.mdown',
- '.mkdn',
- '.md',
- '.mkd',
- '.mdwn',
- '.mdtxt',
- '.mdtext',
- '.text',
- '.txt',
- '.Rmd'
- ];
- export
- class MarkdownCodeBlock {
- startLine: number;
- endLine: number;
- code: string;
- constructor(startLine: number) {
- this.startLine = startLine;
- this.code = "";
- this.endLine = -1;
- }
- }
- /**
- * Check whether the given file extension is a markdown extension
- * @param extension - A file extension
- *
- * @returns true/false depending on whether this is a supported markdown extension
- */
- export
- function isMarkdown(extension: string): boolean {
- return markdownExtensions.indexOf(extension) > -1
- }
- /**
- * Construct all code snippets from current text
- * (this could be potentially optimized if we can cache and detect differences)
- * @param text - A string to parse codeblocks from
- *
- * @returns An array of MarkdownCodeBlocks.
- */
- export
- function findMarkdownCodeBlocks(text: string): MarkdownCodeBlock[] {
- if (!text || text == '') {
- return [];
- }
- const lines = text.split("\n");
- const codeSnippets: MarkdownCodeBlock[] = [];
- var currentCode = null;
- for (var lineIndex = 0; lineIndex < lines.length; lineIndex++) {
- const line = lines[lineIndex];
- const marker = findNextMarker(line);
- const lineContainsMarker = marker != '';
- const constructingSnippet = currentCode != null;
- //skip this line if it is not part of any code snippet and doesn't contain a marker
- if (!lineContainsMarker && !constructingSnippet) {
- continue;
- }
- //check if we are already constructing a code snippet
- if (!constructingSnippet) {
- //start constructing
- currentCode = new MarkdownCodeBlock(lineIndex);
- //check whether this is a single line code snippet
- const firstIndex = line.indexOf(marker);
- const lastIndex = line.lastIndexOf(marker);
- const isSingleLine = firstIndex != lastIndex
- if (isSingleLine) {
- currentCode.code = line.substring(firstIndex + marker.length, lastIndex);
- currentCode.endLine = lineIndex;
- codeSnippets.push(currentCode);
- currentCode = null;
- } else {
- currentCode.code = line.substring(firstIndex + marker.length);
- }
- } else {
- //already constructing
- if (lineContainsMarker) {
- currentCode.code += "\n" + line.substring(0, line.indexOf(marker));
- currentCode.endLine = lineIndex;
- codeSnippets.push(currentCode);
- currentCode = null;
- } else {
- currentCode.code += "\n" + line;
- }
- }
- }
- return codeSnippets;
- }
- function findNextMarker(text: string) {
- for (let marker of markdownMarkers) {
- const index = text.indexOf(marker);
- if (index > -1) {
- return marker;
- }
- }
- return '';
- }
- }
|