(md)
| 40 | } |
| 41 | |
| 42 | function extractBlocks(md) { |
| 43 | const rgx = /(```\w+;\s*?(?:runnable|auto|hidden)\s*?[\n\r]+[\s\S]*?^\s*?```\s*?$)/gm; |
| 44 | const parts = md.split(rgx); |
| 45 | |
| 46 | let blockCounter = 0; |
| 47 | let currentString = ""; |
| 48 | const blockOrder = []; |
| 49 | const blocks = {}; |
| 50 | |
| 51 | for (let i = 0; i < parts.length; i++) { |
| 52 | const part = parts[i]; |
| 53 | const tokens = markdownIt.parse(parts[i]); |
| 54 | if (tokens.length === 1 && tokens[0].type === 'fence') { |
| 55 | const block = extractCodeBlock(tokens[0]); |
| 56 | // If it's an executable block |
| 57 | if (block) { |
| 58 | // Flush the current text to a text block |
| 59 | flushTextBlock(blockCounter, blocks, blockOrder, currentString); |
| 60 | currentString = ""; |
| 61 | blockCounter++; |
| 62 | |
| 63 | // Then add the code block |
| 64 | const id = String(blockCounter); |
| 65 | blockOrder.push(id); |
| 66 | blocks[id] = block.set('id', id); |
| 67 | blockCounter++; |
| 68 | continue; |
| 69 | } |
| 70 | } |
| 71 | // If it isn't an executable code block, just add |
| 72 | // to the current text block; |
| 73 | currentString += part; |
| 74 | } |
| 75 | flushTextBlock(blockCounter, blocks, blockOrder, currentString); |
| 76 | |
| 77 | return { |
| 78 | content: blockOrder, |
| 79 | blocks |
| 80 | }; |
| 81 | } |
| 82 | |
| 83 | function getDate(attributes) { |
| 84 | if (attributes.created) { |
no test coverage detected