AK-21/Graphite-Industrial-Intelligence
0
1/**2 * @import {3 * Construct,4 * State,5 * TokenizeContext,6 * Tokenizer7 * } from 'micromark-util-types'8 */9 10import { factorySpace } from 'micromark-factory-space';11import { markdownLineEnding, markdownSpace } from 'micromark-util-character';12/** @type {Construct} */13export const codeIndented = {14 name: 'codeIndented',15 tokenize: tokenizeCodeIndented16};17 18/** @type {Construct} */19const furtherStart = {20 partial: true,21 tokenize: tokenizeFurtherStart22};23 24/**25 * @this {TokenizeContext}26 * Context.27 * @type {Tokenizer}28 */29function tokenizeCodeIndented(effects, ok, nok) {30 const self = this;31 return start;32 33 /**34 * Start of code (indented).35 *36 * > **Parsing note**: it is not needed to check if this first line is a37 * > filled line (that it has a non-whitespace character), because blank lines38 * > are parsed already, so we never run into that.39 *40 * ```markdown41 * > | aaa42 * ^43 * ```44 *45 * @type {State}46 */47 function start(code) {48 // To do: manually check if interrupting like `markdown-rs`.49 50 effects.enter("codeIndented");51 // To do: use an improved `space_or_tab` function like `markdown-rs`,52 // so that we can drop the next state.53 return factorySpace(effects, afterPrefix, "linePrefix", 4 + 1)(code);54 }55 56 /**57 * At start, after 1 or 4 spaces.58 *59 * ```markdown60 * > | aaa61 * ^62 * ```63 *64 * @type {State}65 */66 function afterPrefix(code) {67 const tail = self.events[self.events.length - 1];68 return tail && tail[1].type === "linePrefix" && tail[2].sliceSerialize(tail[1], true).length >= 4 ? atBreak(code) : nok(code);69 }70 71 /**72 * At a break.73 *74 * ```markdown75 * > | aaa76 * ^ ^77 * ```78 *79 * @type {State}80 */81 function atBreak(code) {82 if (code === null) {83 return after(code);84 }85 if (markdownLineEnding(code)) {86 return effects.attempt(furtherStart, atBreak, after)(code);87 }88 effects.enter("codeFlowValue");89 return inside(code);90 }91 92 /**93 * In code content.94 *95 * ```markdown96 * > | aaa97 * ^^^^98 * ```99 *100 * @type {State}101 */102 function inside(code) {103 if (code === null || markdownLineEnding(code)) {104 effects.exit("codeFlowValue");105 return atBreak(code);106 }107 effects.consume(code);108 return inside;109 }110 111 /** @type {State} */112 function after(code) {113 effects.exit("codeIndented");114 // To do: allow interrupting like `markdown-rs`.115 // Feel free to interrupt.116 // tokenizer.interrupt = false117 return ok(code);118 }119}120 121/**122 * @this {TokenizeContext}123 * Context.124 * @type {Tokenizer}125 */126function tokenizeFurtherStart(effects, ok, nok) {127 const self = this;128 return furtherStart;129 130 /**131 * At eol, trying to parse another indent.132 *133 * ```markdown134 * > | aaa135 * ^136 * | bbb137 * ```138 *139 * @type {State}140 */141 function furtherStart(code) {142 // To do: improve `lazy` / `pierce` handling.143 // If this is a lazy line, it can’t be code.144 if (self.parser.lazy[self.now().line]) {145 return nok(code);146 }147 if (markdownLineEnding(code)) {148 effects.enter("lineEnding");149 effects.consume(code);150 effects.exit("lineEnding");151 return furtherStart;152 }153 154 // To do: the code here in `micromark-js` is a bit different from155 // `markdown-rs` because there it can attempt spaces.156 // We can’t yet.157 //158 // To do: use an improved `space_or_tab` function like `markdown-rs`,159 // so that we can drop the next state.160 return factorySpace(effects, afterPrefix, "linePrefix", 4 + 1)(code);161 }162 163 /**164 * At start, after 1 or 4 spaces.165 *166 * ```markdown167 * > | aaa168 * ^169 * ```170 *171 * @type {State}172 */173 function afterPrefix(code) {174 const tail = self.events[self.events.length - 1];175 return tail && tail[1].type === "linePrefix" && tail[2].sliceSerialize(tail[1], true).length >= 4 ? ok(code) : markdownLineEnding(code) ? furtherStart(code) : nok(code);176 }177}