File size: 2,045 Bytes
bc20498 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
/**
* @typedef {import('micromark-util-types').Code} Code
* @typedef {import('micromark-util-types').Construct} Construct
* @typedef {import('micromark-util-types').State} State
* @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext
* @typedef {import('micromark-util-types').Tokenizer} Tokenizer
*/
import {factorySpace} from 'micromark-factory-space'
import {markdownLineEnding, markdownSpace} from 'micromark-util-character'
/** @type {Construct} */
export const thematicBreak = {
name: 'thematicBreak',
tokenize: tokenizeThematicBreak
}
/**
* @this {TokenizeContext}
* @type {Tokenizer}
*/
function tokenizeThematicBreak(effects, ok, nok) {
let size = 0
/** @type {NonNullable<Code>} */
let marker
return start
/**
* Start of thematic break.
*
* ```markdown
* > | ***
* ^
* ```
*
* @type {State}
*/
function start(code) {
effects.enter('thematicBreak')
// To do: parse indent like `markdown-rs`.
return before(code)
}
/**
* After optional whitespace, at marker.
*
* ```markdown
* > | ***
* ^
* ```
*
* @type {State}
*/
function before(code) {
marker = code
return atBreak(code)
}
/**
* After something, before something else.
*
* ```markdown
* > | ***
* ^
* ```
*
* @type {State}
*/
function atBreak(code) {
if (code === marker) {
effects.enter('thematicBreakSequence')
return sequence(code)
}
if (size >= 3 && (code === null || markdownLineEnding(code))) {
effects.exit('thematicBreak')
return ok(code)
}
return nok(code)
}
/**
* In sequence.
*
* ```markdown
* > | ***
* ^
* ```
*
* @type {State}
*/
function sequence(code) {
if (code === marker) {
effects.consume(code)
size++
return sequence
}
effects.exit('thematicBreakSequence')
return markdownSpace(code)
? factorySpace(effects, atBreak, 'whitespace')(code)
: atBreak(code)
}
}
|