@tinta-lang/syntax 0.0.0-stage → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +16 -2
- package/THIRD_PARTY_NOTICES.txt +13651 -0
- package/dist/directive.d.ts +40 -0
- package/dist/editing.d.ts +46 -0
- package/dist/enrichment.d.ts +5 -0
- package/dist/expression.d.ts +26 -0
- package/dist/image-destinations.d.ts +3 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +10118 -0
- package/dist/parser.d.ts +40 -0
- package/dist/registry.d.ts +144 -0
- package/dist/source.d.ts +28 -0
- package/package.json +289 -3
- package/parser-provenance.json +1419 -0
- package/patches/README.md +5 -0
- package/patches/micromark.patch +84 -0
- package/vendor/@noble/hashes/LICENSE +21 -0
- package/vendor/@noble/hashes/_md.js +209 -0
- package/vendor/@noble/hashes/_u64.js +77 -0
- package/vendor/@noble/hashes/package.json +91 -0
- package/vendor/@noble/hashes/sha2.js +446 -0
- package/vendor/@noble/hashes/utils.js +687 -0
- package/vendor/character-entities/index.js +2132 -0
- package/vendor/character-entities/license +22 -0
- package/vendor/character-entities/package.json +78 -0
- package/vendor/decode-named-character-reference/index.js +19 -0
- package/vendor/decode-named-character-reference/license +22 -0
- package/vendor/decode-named-character-reference/package.json +90 -0
- package/vendor/devlop/lib/default.js +9 -0
- package/vendor/devlop/license +22 -0
- package/vendor/devlop/package.json +80 -0
- package/vendor/longest-streak/index.js +36 -0
- package/vendor/longest-streak/license +22 -0
- package/vendor/longest-streak/package.json +73 -0
- package/vendor/markdown-table/index.js +393 -0
- package/vendor/markdown-table/license +22 -0
- package/vendor/markdown-table/package.json +77 -0
- package/vendor/mdast-util-from-markdown/index.js +2 -0
- package/vendor/mdast-util-from-markdown/lib/index.js +1270 -0
- package/vendor/mdast-util-from-markdown/license +22 -0
- package/vendor/mdast-util-from-markdown/package.json +98 -0
- package/vendor/mdast-util-gfm-strikethrough/index.js +5 -0
- package/vendor/mdast-util-gfm-strikethrough/lib/index.js +133 -0
- package/vendor/mdast-util-gfm-strikethrough/license +22 -0
- package/vendor/mdast-util-gfm-strikethrough/package.json +84 -0
- package/vendor/mdast-util-gfm-table/index.js +2 -0
- package/vendor/mdast-util-gfm-table/lib/index.js +300 -0
- package/vendor/mdast-util-gfm-table/license +22 -0
- package/vendor/mdast-util-gfm-table/package.json +101 -0
- package/vendor/mdast-util-gfm-task-list-item/index.js +4 -0
- package/vendor/mdast-util-gfm-task-list-item/lib/index.js +141 -0
- package/vendor/mdast-util-gfm-task-list-item/license +22 -0
- package/vendor/mdast-util-gfm-task-list-item/package.json +90 -0
- package/vendor/mdast-util-phrasing/index.js +1 -0
- package/vendor/mdast-util-phrasing/lib/index.js +45 -0
- package/vendor/mdast-util-phrasing/license +23 -0
- package/vendor/mdast-util-phrasing/package.json +78 -0
- package/vendor/mdast-util-to-markdown/index.js +3 -0
- package/vendor/mdast-util-to-markdown/lib/configure.js +98 -0
- package/vendor/mdast-util-to-markdown/lib/handle/blockquote.js +40 -0
- package/vendor/mdast-util-to-markdown/lib/handle/break.js +41 -0
- package/vendor/mdast-util-to-markdown/lib/handle/code.js +86 -0
- package/vendor/mdast-util-to-markdown/lib/handle/definition.js +83 -0
- package/vendor/mdast-util-to-markdown/lib/handle/emphasis.js +67 -0
- package/vendor/mdast-util-to-markdown/lib/handle/heading.js +84 -0
- package/vendor/mdast-util-to-markdown/lib/handle/html.js +27 -0
- package/vendor/mdast-util-to-markdown/lib/handle/image-reference.js +78 -0
- package/vendor/mdast-util-to-markdown/lib/handle/image.js +92 -0
- package/vendor/mdast-util-to-markdown/lib/handle/index.js +45 -0
- package/vendor/mdast-util-to-markdown/lib/handle/inline-code.js +86 -0
- package/vendor/mdast-util-to-markdown/lib/handle/link-reference.js +78 -0
- package/vendor/mdast-util-to-markdown/lib/handle/link.js +129 -0
- package/vendor/mdast-util-to-markdown/lib/handle/list-item.js +73 -0
- package/vendor/mdast-util-to-markdown/lib/handle/list.js +107 -0
- package/vendor/mdast-util-to-markdown/lib/handle/paragraph.js +27 -0
- package/vendor/mdast-util-to-markdown/lib/handle/root.js +34 -0
- package/vendor/mdast-util-to-markdown/lib/handle/strong.js +67 -0
- package/vendor/mdast-util-to-markdown/lib/handle/text.js +30 -0
- package/vendor/mdast-util-to-markdown/lib/handle/thematic-break.js +27 -0
- package/vendor/mdast-util-to-markdown/lib/index.js +213 -0
- package/vendor/mdast-util-to-markdown/lib/join.js +56 -0
- package/vendor/mdast-util-to-markdown/lib/unsafe.js +160 -0
- package/vendor/mdast-util-to-markdown/lib/util/association.js +33 -0
- package/vendor/mdast-util-to-markdown/lib/util/character.js +32 -0
- package/vendor/mdast-util-to-markdown/lib/util/check-bullet-ordered.js +25 -0
- package/vendor/mdast-util-to-markdown/lib/util/check-bullet-other.js +42 -0
- package/vendor/mdast-util-to-markdown/lib/util/check-bullet.js +25 -0
- package/vendor/mdast-util-to-markdown/lib/util/check-emphasis.js +25 -0
- package/vendor/mdast-util-to-markdown/lib/util/check-fence.js +25 -0
- package/vendor/mdast-util-to-markdown/lib/util/check-list-item-indent.js +25 -0
- package/vendor/mdast-util-to-markdown/lib/util/check-quote.js +25 -0
- package/vendor/mdast-util-to-markdown/lib/util/check-rule-repetition.js +25 -0
- package/vendor/mdast-util-to-markdown/lib/util/check-rule.js +25 -0
- package/vendor/mdast-util-to-markdown/lib/util/check-strong.js +25 -0
- package/vendor/mdast-util-to-markdown/lib/util/compile-pattern.js +30 -0
- package/vendor/mdast-util-to-markdown/lib/util/container-flow.js +93 -0
- package/vendor/mdast-util-to-markdown/lib/util/container-phrasing.js +704 -0
- package/vendor/mdast-util-to-markdown/lib/util/encode-character-reference.js +11 -0
- package/vendor/mdast-util-to-markdown/lib/util/encode-info.js +82 -0
- package/vendor/mdast-util-to-markdown/lib/util/format-code-as-indented.js +27 -0
- package/vendor/mdast-util-to-markdown/lib/util/format-heading-as-setext.js +39 -0
- package/vendor/mdast-util-to-markdown/lib/util/format-link-as-autolink.js +39 -0
- package/vendor/mdast-util-to-markdown/lib/util/html-kind.js +63 -0
- package/vendor/mdast-util-to-markdown/lib/util/indent-lines.js +40 -0
- package/vendor/mdast-util-to-markdown/lib/util/pattern-in-scope.js +52 -0
- package/vendor/mdast-util-to-markdown/lib/util/safe.js +263 -0
- package/vendor/mdast-util-to-markdown/lib/util/track.js +55 -0
- package/vendor/mdast-util-to-markdown/license +22 -0
- package/vendor/mdast-util-to-markdown/package.json +88 -0
- package/vendor/mdast-util-to-string/index.js +5 -0
- package/vendor/mdast-util-to-string/lib/index.js +108 -0
- package/vendor/mdast-util-to-string/license +22 -0
- package/vendor/mdast-util-to-string/package.json +78 -0
- package/vendor/micromark/index.js +60 -0
- package/vendor/micromark/lib/compile.js +1068 -0
- package/vendor/micromark/lib/constructs.js +85 -0
- package/vendor/micromark/lib/create-tokenizer.js +615 -0
- package/vendor/micromark/lib/initialize/content.js +79 -0
- package/vendor/micromark/lib/initialize/document.js +370 -0
- package/vendor/micromark/lib/initialize/flow.js +58 -0
- package/vendor/micromark/lib/initialize/text.js +216 -0
- package/vendor/micromark/lib/parse.js +56 -0
- package/vendor/micromark/lib/postprocess.js +18 -0
- package/vendor/micromark/lib/preprocess.js +112 -0
- package/vendor/micromark/license +22 -0
- package/vendor/micromark/package.json +87 -0
- package/vendor/micromark-core-commonmark/index.js +22 -0
- package/vendor/micromark-core-commonmark/lib/attention.js +231 -0
- package/vendor/micromark-core-commonmark/lib/autolink.js +233 -0
- package/vendor/micromark-core-commonmark/lib/blank-line.js +61 -0
- package/vendor/micromark-core-commonmark/lib/block-quote.js +143 -0
- package/vendor/micromark-core-commonmark/lib/character-escape.js +64 -0
- package/vendor/micromark-core-commonmark/lib/character-reference.js +149 -0
- package/vendor/micromark-core-commonmark/lib/code-fenced.js +422 -0
- package/vendor/micromark-core-commonmark/lib/code-indented.js +159 -0
- package/vendor/micromark-core-commonmark/lib/code-text.js +225 -0
- package/vendor/micromark-core-commonmark/lib/content.js +163 -0
- package/vendor/micromark-core-commonmark/lib/definition.js +254 -0
- package/vendor/micromark-core-commonmark/lib/hard-break-escape.js +60 -0
- package/vendor/micromark-core-commonmark/lib/heading-atx.js +191 -0
- package/vendor/micromark-core-commonmark/lib/html-flow.js +827 -0
- package/vendor/micromark-core-commonmark/lib/html-text.js +678 -0
- package/vendor/micromark-core-commonmark/lib/label-end.js +561 -0
- package/vendor/micromark-core-commonmark/lib/label-start-image.js +110 -0
- package/vendor/micromark-core-commonmark/lib/label-start-link.js +63 -0
- package/vendor/micromark-core-commonmark/lib/line-ending.js +33 -0
- package/vendor/micromark-core-commonmark/lib/list.js +213 -0
- package/vendor/micromark-core-commonmark/lib/partial-non-lazy-continuation.js +61 -0
- package/vendor/micromark-core-commonmark/lib/setext-underline.js +187 -0
- package/vendor/micromark-core-commonmark/lib/thematic-break.js +102 -0
- package/vendor/micromark-core-commonmark/license +22 -0
- package/vendor/micromark-core-commonmark/package.json +62 -0
- package/vendor/micromark-extension-gfm-strikethrough/index.js +3 -0
- package/vendor/micromark-extension-gfm-strikethrough/lib/html.js +26 -0
- package/vendor/micromark-extension-gfm-strikethrough/lib/syntax.js +142 -0
- package/vendor/micromark-extension-gfm-strikethrough/license +22 -0
- package/vendor/micromark-extension-gfm-strikethrough/package.json +129 -0
- package/vendor/micromark-extension-gfm-table/index.js +2 -0
- package/vendor/micromark-extension-gfm-table/lib/edit-map.js +222 -0
- package/vendor/micromark-extension-gfm-table/lib/html.js +135 -0
- package/vendor/micromark-extension-gfm-table/lib/infer.js +52 -0
- package/vendor/micromark-extension-gfm-table/lib/syntax.js +846 -0
- package/vendor/micromark-extension-gfm-table/license +22 -0
- package/vendor/micromark-extension-gfm-table/package.json +86 -0
- package/vendor/micromark-extension-gfm-task-list-item/index.js +2 -0
- package/vendor/micromark-extension-gfm-task-list-item/lib/html.js +29 -0
- package/vendor/micromark-extension-gfm-task-list-item/lib/syntax.js +158 -0
- package/vendor/micromark-extension-gfm-task-list-item/license +22 -0
- package/vendor/micromark-extension-gfm-task-list-item/package.json +131 -0
- package/vendor/micromark-factory-destination/index.js +206 -0
- package/vendor/micromark-factory-destination/license +22 -0
- package/vendor/micromark-factory-destination/package.json +57 -0
- package/vendor/micromark-factory-label/index.js +148 -0
- package/vendor/micromark-factory-label/license +22 -0
- package/vendor/micromark-factory-label/package.json +60 -0
- package/vendor/micromark-factory-space/index.js +116 -0
- package/vendor/micromark-factory-space/license +22 -0
- package/vendor/micromark-factory-space/package.json +46 -0
- package/vendor/micromark-factory-title/index.js +158 -0
- package/vendor/micromark-factory-title/license +22 -0
- package/vendor/micromark-factory-title/package.json +58 -0
- package/vendor/micromark-factory-whitespace/index.js +44 -0
- package/vendor/micromark-factory-whitespace/license +22 -0
- package/vendor/micromark-factory-whitespace/package.json +57 -0
- package/vendor/micromark-util-character/index.js +246 -0
- package/vendor/micromark-util-character/license +22 -0
- package/vendor/micromark-util-character/package.json +57 -0
- package/vendor/micromark-util-chunked/index.js +81 -0
- package/vendor/micromark-util-chunked/license +22 -0
- package/vendor/micromark-util-chunked/package.json +57 -0
- package/vendor/micromark-util-classify-character/index.js +27 -0
- package/vendor/micromark-util-classify-character/license +22 -0
- package/vendor/micromark-util-classify-character/package.json +59 -0
- package/vendor/micromark-util-combine-extensions/index.js +143 -0
- package/vendor/micromark-util-combine-extensions/license +22 -0
- package/vendor/micromark-util-combine-extensions/package.json +52 -0
- package/vendor/micromark-util-decode-numeric-character-reference/index.js +32 -0
- package/vendor/micromark-util-decode-numeric-character-reference/license +22 -0
- package/vendor/micromark-util-decode-numeric-character-reference/package.json +59 -0
- package/vendor/micromark-util-decode-string/index.js +45 -0
- package/vendor/micromark-util-decode-string/license +22 -0
- package/vendor/micromark-util-decode-string/package.json +63 -0
- package/vendor/micromark-util-edit-map/index.js +225 -0
- package/vendor/micromark-util-edit-map/license +22 -0
- package/vendor/micromark-util-edit-map/package.json +48 -0
- package/vendor/micromark-util-encode/index.js +33 -0
- package/vendor/micromark-util-encode/license +22 -0
- package/vendor/micromark-util-encode/package.json +47 -0
- package/vendor/micromark-util-html-tag-name/index.js +93 -0
- package/vendor/micromark-util-html-tag-name/license +22 -0
- package/vendor/micromark-util-html-tag-name/package.json +47 -0
- package/vendor/micromark-util-normalize-identifier/index.js +33 -0
- package/vendor/micromark-util-normalize-identifier/license +22 -0
- package/vendor/micromark-util-normalize-identifier/package.json +58 -0
- package/vendor/micromark-util-resolve-all/index.js +32 -0
- package/vendor/micromark-util-resolve-all/license +22 -0
- package/vendor/micromark-util-resolve-all/package.json +48 -0
- package/vendor/micromark-util-sanitize-uri/index.js +107 -0
- package/vendor/micromark-util-sanitize-uri/license +22 -0
- package/vendor/micromark-util-sanitize-uri/package.json +59 -0
- package/vendor/micromark-util-subtokenize/index.js +228 -0
- package/vendor/micromark-util-subtokenize/lib/splice-buffer.js +251 -0
- package/vendor/micromark-util-subtokenize/license +22 -0
- package/vendor/micromark-util-subtokenize/package.json +60 -0
- package/vendor/unist-util-is/index.js +7 -0
- package/vendor/unist-util-is/lib/index.js +296 -0
- package/vendor/unist-util-is/license +22 -0
- package/vendor/unist-util-is/package.json +103 -0
- package/vendor/unist-util-stringify-position/index.js +1 -0
- package/vendor/unist-util-stringify-position/lib/index.js +84 -0
- package/vendor/unist-util-stringify-position/license +22 -0
- package/vendor/unist-util-stringify-position/package.json +80 -0
- package/vendor/unist-util-visit/index.js +2 -0
- package/vendor/unist-util-visit/lib/index.js +312 -0
- package/vendor/unist-util-visit/license +22 -0
- package/vendor/unist-util-visit/package.json +108 -0
- package/vendor/unist-util-visit-parents/index.js +2 -0
- package/vendor/unist-util-visit-parents/lib/color.js +7 -0
- package/vendor/unist-util-visit-parents/lib/index.js +399 -0
- package/vendor/unist-util-visit-parents/license +22 -0
- package/vendor/unist-util-visit-parents/package.json +106 -0
- package/vendor/zwitch/index.js +118 -0
- package/vendor/zwitch/license +22 -0
- package/vendor/zwitch/package.json +72 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import {Break, Parents} from 'mdast'
|
|
3
|
+
* @import {Info, State} from 'mdast-util-to-markdown'
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {patternInScope} from '../util/pattern-in-scope.js'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Serialize a break node.
|
|
10
|
+
*
|
|
11
|
+
* @param {Break} _
|
|
12
|
+
* Node to serialize.
|
|
13
|
+
* @param {Parents | undefined} _1
|
|
14
|
+
* Parent node.
|
|
15
|
+
* @param {State} state
|
|
16
|
+
* Info passed around.
|
|
17
|
+
* @param {Info} info
|
|
18
|
+
* Info on surrounding context.
|
|
19
|
+
* @returns {string}
|
|
20
|
+
* Serialized markdown.
|
|
21
|
+
*/
|
|
22
|
+
export function hardBreak(_, _1, state, info) {
|
|
23
|
+
let index = -1
|
|
24
|
+
|
|
25
|
+
while (++index < state.unsafe.length) {
|
|
26
|
+
const pattern = state.unsafe[index]
|
|
27
|
+
|
|
28
|
+
// If we can’t put unconditional eols in this construct (setext headings,
|
|
29
|
+
// tables), use a space instead.
|
|
30
|
+
if (
|
|
31
|
+
pattern.character === '\n' &&
|
|
32
|
+
!pattern.before &&
|
|
33
|
+
!pattern.after &&
|
|
34
|
+
patternInScope(state.stack, pattern)
|
|
35
|
+
) {
|
|
36
|
+
return /[\t ]/.test(info.before) ? '' : ' '
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return '\\\n'
|
|
41
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import {Info, Map, State} from 'mdast-util-to-markdown'
|
|
3
|
+
* @import {Code, Parents} from 'mdast'
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {longestStreak} from 'longest-streak'
|
|
7
|
+
import {formatCodeAsIndented} from '../util/format-code-as-indented.js'
|
|
8
|
+
import {checkFence} from '../util/check-fence.js'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Serialize a code node.
|
|
12
|
+
*
|
|
13
|
+
* @param {Code} node
|
|
14
|
+
* Node to serialize.
|
|
15
|
+
* @param {Parents | undefined} _
|
|
16
|
+
* Parent node.
|
|
17
|
+
* @param {State} state
|
|
18
|
+
* Info passed around.
|
|
19
|
+
* @param {Info} info
|
|
20
|
+
* Info on surrounding context.
|
|
21
|
+
* @returns {string}
|
|
22
|
+
* Serialized markdown.
|
|
23
|
+
*/
|
|
24
|
+
export function code(node, _, state, info) {
|
|
25
|
+
const marker = checkFence(state)
|
|
26
|
+
const raw = node.value || ''
|
|
27
|
+
|
|
28
|
+
if (formatCodeAsIndented(node, state)) {
|
|
29
|
+
const exit = state.enter('codeIndented')
|
|
30
|
+
const value = state.indentLines(raw, map)
|
|
31
|
+
exit()
|
|
32
|
+
return value
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const tracker = state.createTracker(info)
|
|
36
|
+
const sequence = marker.repeat(Math.max(longestStreak(raw, marker) + 1, 3))
|
|
37
|
+
const exit = state.enter('codeFenced')
|
|
38
|
+
const suffix = marker === '`' ? 'GraveAccent' : 'Tilde'
|
|
39
|
+
let value = tracker.move(sequence)
|
|
40
|
+
|
|
41
|
+
if (node.lang) {
|
|
42
|
+
const subexit = state.enter(`codeFencedLang${suffix}`)
|
|
43
|
+
value += tracker.move(
|
|
44
|
+
state.safe(node.lang, {
|
|
45
|
+
before: value,
|
|
46
|
+
after: ' ',
|
|
47
|
+
encode: ['`'],
|
|
48
|
+
...tracker.current()
|
|
49
|
+
})
|
|
50
|
+
)
|
|
51
|
+
subexit()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (node.lang && node.meta) {
|
|
55
|
+
const subexit = state.enter(`codeFencedMeta${suffix}`)
|
|
56
|
+
value += tracker.move(' ')
|
|
57
|
+
value += tracker.move(
|
|
58
|
+
state.safe(node.meta, {
|
|
59
|
+
before: value,
|
|
60
|
+
after: '\n',
|
|
61
|
+
encode: ['`'],
|
|
62
|
+
...tracker.current()
|
|
63
|
+
})
|
|
64
|
+
)
|
|
65
|
+
subexit()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
value += tracker.move('\n')
|
|
69
|
+
|
|
70
|
+
if (raw) {
|
|
71
|
+
value += tracker.move(raw + '\n')
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
value += tracker.move(sequence)
|
|
75
|
+
exit()
|
|
76
|
+
return value
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Indent lines w/ code indent.
|
|
81
|
+
*
|
|
82
|
+
* @type {Map}
|
|
83
|
+
*/
|
|
84
|
+
function map(line, _, blank) {
|
|
85
|
+
return (blank ? '' : ' ') + line
|
|
86
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import {Info, State} from 'mdast-util-to-markdown'
|
|
3
|
+
* @import {Definition, Parents} from 'mdast'
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {checkQuote} from '../util/check-quote.js'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Serialize a definition node.
|
|
10
|
+
*
|
|
11
|
+
* @param {Definition} node
|
|
12
|
+
* Node to serialize.
|
|
13
|
+
* @param {Parents | undefined} _
|
|
14
|
+
* Parent node.
|
|
15
|
+
* @param {State} state
|
|
16
|
+
* Info passed around.
|
|
17
|
+
* @param {Info} info
|
|
18
|
+
* Info on surrounding context.
|
|
19
|
+
* @returns {string}
|
|
20
|
+
* Serialized markdown.
|
|
21
|
+
*/
|
|
22
|
+
export function definition(node, _, state, info) {
|
|
23
|
+
const quote = checkQuote(state)
|
|
24
|
+
const suffix = quote === '"' ? 'Quote' : 'Apostrophe'
|
|
25
|
+
const exit = state.enter('definition')
|
|
26
|
+
let subexit = state.enter('label')
|
|
27
|
+
const tracker = state.createTracker(info)
|
|
28
|
+
let value = tracker.move('[')
|
|
29
|
+
value += tracker.move(
|
|
30
|
+
state.safe(state.associationId(node), {
|
|
31
|
+
before: value,
|
|
32
|
+
after: ']',
|
|
33
|
+
...tracker.current()
|
|
34
|
+
})
|
|
35
|
+
)
|
|
36
|
+
value += tracker.move(']: ')
|
|
37
|
+
|
|
38
|
+
subexit()
|
|
39
|
+
|
|
40
|
+
if (
|
|
41
|
+
// If there’s no url, or…
|
|
42
|
+
!node.url ||
|
|
43
|
+
// If there are control characters or whitespace.
|
|
44
|
+
/[\0- \u007F]/.test(node.url)
|
|
45
|
+
) {
|
|
46
|
+
subexit = state.enter('destinationLiteral')
|
|
47
|
+
value += tracker.move('<')
|
|
48
|
+
value += tracker.move(
|
|
49
|
+
state.safe(node.url, {before: value, after: '>', ...tracker.current()})
|
|
50
|
+
)
|
|
51
|
+
value += tracker.move('>')
|
|
52
|
+
} else {
|
|
53
|
+
// No whitespace, raw is prettier.
|
|
54
|
+
subexit = state.enter('destinationRaw')
|
|
55
|
+
value += tracker.move(
|
|
56
|
+
state.safe(node.url, {
|
|
57
|
+
before: value,
|
|
58
|
+
after: node.title ? ' ' : '\n',
|
|
59
|
+
...tracker.current()
|
|
60
|
+
})
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
subexit()
|
|
65
|
+
|
|
66
|
+
if (node.title) {
|
|
67
|
+
subexit = state.enter(`title${suffix}`)
|
|
68
|
+
value += tracker.move(' ' + quote)
|
|
69
|
+
value += tracker.move(
|
|
70
|
+
state.safe(node.title, {
|
|
71
|
+
before: value,
|
|
72
|
+
after: quote,
|
|
73
|
+
...tracker.current()
|
|
74
|
+
})
|
|
75
|
+
)
|
|
76
|
+
value += tracker.move(quote)
|
|
77
|
+
subexit()
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
exit()
|
|
81
|
+
|
|
82
|
+
return value
|
|
83
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import {AttentionInfo, Info, State} from 'mdast-util-to-markdown'
|
|
3
|
+
* @import {Emphasis, Parents} from 'mdast'
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {checkEmphasis} from '../util/check-emphasis.js'
|
|
7
|
+
|
|
8
|
+
emphasis.attention = attention
|
|
9
|
+
emphasis.peek = peek
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Serialize an emphasis node.
|
|
13
|
+
*
|
|
14
|
+
* Attention is properly handled by `containerPhrasing`.
|
|
15
|
+
*
|
|
16
|
+
* @param {Emphasis} node
|
|
17
|
+
* Node to serialize.
|
|
18
|
+
* @param {Parents | undefined} _
|
|
19
|
+
* Parent node.
|
|
20
|
+
* @param {State} state
|
|
21
|
+
* Info passed around.
|
|
22
|
+
* @param {Info} info
|
|
23
|
+
* Info on surrounding context.
|
|
24
|
+
* @returns {string}
|
|
25
|
+
* Serialized markdown.
|
|
26
|
+
*/
|
|
27
|
+
export function emphasis(node, _, state, info) {
|
|
28
|
+
const exit = state.enter('phrasing')
|
|
29
|
+
const value = state.containerPhrasing({type: 'root', children: [node]}, info)
|
|
30
|
+
exit()
|
|
31
|
+
return value
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Serialize an emphasis node as attention.
|
|
36
|
+
*
|
|
37
|
+
* @param {Emphasis} _
|
|
38
|
+
* Node to serialize.
|
|
39
|
+
* @param {State} state
|
|
40
|
+
* Info passed around.
|
|
41
|
+
* @returns {AttentionInfo}
|
|
42
|
+
* Info on how to serialize the node.
|
|
43
|
+
*/
|
|
44
|
+
function attention(_, state) {
|
|
45
|
+
const marker = checkEmphasis(state)
|
|
46
|
+
return {
|
|
47
|
+
construct: 'emphasis',
|
|
48
|
+
markers: marker === '*' ? ['*', '_'] : ['_', '*'],
|
|
49
|
+
sizes: [1]
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Peek at this node.
|
|
55
|
+
*
|
|
56
|
+
* @param {Emphasis} _
|
|
57
|
+
* Node to serialize.
|
|
58
|
+
* @param {Parents | undefined} _1
|
|
59
|
+
* Parent node.
|
|
60
|
+
* @param {State} state
|
|
61
|
+
* Info passed around.
|
|
62
|
+
* @returns {string}
|
|
63
|
+
* Start of the serialized markdown.
|
|
64
|
+
*/
|
|
65
|
+
function peek(_, _1, state) {
|
|
66
|
+
return state.options.emphasis || '*'
|
|
67
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import {Info, State} from 'mdast-util-to-markdown'
|
|
3
|
+
* @import {Heading, Parents} from 'mdast'
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {encodeCharacterReference} from '../util/encode-character-reference.js'
|
|
7
|
+
import {formatHeadingAsSetext} from '../util/format-heading-as-setext.js'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Serialize a heading node.
|
|
11
|
+
*
|
|
12
|
+
* @param {Heading} node
|
|
13
|
+
* Node to serialize.
|
|
14
|
+
* @param {Parents | undefined} _
|
|
15
|
+
* Parent node.
|
|
16
|
+
* @param {State} state
|
|
17
|
+
* Info passed around.
|
|
18
|
+
* @param {Info} info
|
|
19
|
+
* Info on surrounding context.
|
|
20
|
+
* @returns {string}
|
|
21
|
+
* Serialized markdown.
|
|
22
|
+
*/
|
|
23
|
+
export function heading(node, _, state, info) {
|
|
24
|
+
const rank = Math.max(Math.min(6, node.depth || 1), 1)
|
|
25
|
+
const tracker = state.createTracker(info)
|
|
26
|
+
|
|
27
|
+
if (formatHeadingAsSetext(node, state)) {
|
|
28
|
+
const exit = state.enter('headingSetext')
|
|
29
|
+
const subexit = state.enter('phrasing')
|
|
30
|
+
const value = state.containerPhrasing(node, {
|
|
31
|
+
...tracker.current(),
|
|
32
|
+
before: '\n',
|
|
33
|
+
after: '\n'
|
|
34
|
+
})
|
|
35
|
+
subexit()
|
|
36
|
+
exit()
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
value +
|
|
40
|
+
'\n' +
|
|
41
|
+
(rank === 1 ? '=' : '-').repeat(
|
|
42
|
+
// The whole size…
|
|
43
|
+
value.length -
|
|
44
|
+
// Minus the position of the character after the last EOL (or
|
|
45
|
+
// 0 if there is none)…
|
|
46
|
+
(Math.max(value.lastIndexOf('\r'), value.lastIndexOf('\n')) + 1)
|
|
47
|
+
)
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const sequence = '#'.repeat(rank)
|
|
52
|
+
const exit = state.enter('headingAtx')
|
|
53
|
+
const subexit = state.enter('phrasing')
|
|
54
|
+
|
|
55
|
+
// Note: for proper tracking, we should reset the output positions when there
|
|
56
|
+
// is no content returned, because then the space is not output.
|
|
57
|
+
// Practically, in that case, there is no content, so it doesn’t matter that
|
|
58
|
+
// we’ve tracked one too many characters.
|
|
59
|
+
tracker.move(sequence + ' ')
|
|
60
|
+
|
|
61
|
+
let value = state.containerPhrasing(node, {
|
|
62
|
+
before: '# ',
|
|
63
|
+
after: '\n',
|
|
64
|
+
...tracker.current()
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
const head = value.charCodeAt(0)
|
|
68
|
+
|
|
69
|
+
if (head === 9 /* `\t` */ || head === 32 /* ` ` */) {
|
|
70
|
+
// To do: what effect has the character reference on tracking?
|
|
71
|
+
value = encodeCharacterReference(head) + value.slice(1)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
value = value ? sequence + ' ' + value : sequence
|
|
75
|
+
|
|
76
|
+
if (state.options.closeAtx) {
|
|
77
|
+
value += ' ' + sequence
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
subexit()
|
|
81
|
+
exit()
|
|
82
|
+
|
|
83
|
+
return value
|
|
84
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import {Html} from 'mdast'
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
html.peek = htmlPeek
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Serialize an HTML node.
|
|
9
|
+
*
|
|
10
|
+
* @param {Html} node
|
|
11
|
+
* Node to serialize.
|
|
12
|
+
* @returns {string}
|
|
13
|
+
* Serialized markdown.
|
|
14
|
+
*/
|
|
15
|
+
export function html(node) {
|
|
16
|
+
return node.value || ''
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Peek at this node.
|
|
21
|
+
*
|
|
22
|
+
* @returns {string}
|
|
23
|
+
* Start of the serialized markdown.
|
|
24
|
+
*/
|
|
25
|
+
function htmlPeek() {
|
|
26
|
+
return '<'
|
|
27
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import {Info, State} from 'mdast-util-to-markdown'
|
|
3
|
+
* @import {ImageReference, Parents} from 'mdast'
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
imageReference.peek = imageReferencePeek
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Serialize an image reference node.
|
|
10
|
+
*
|
|
11
|
+
* @param {ImageReference} node
|
|
12
|
+
* Node to serialize.
|
|
13
|
+
* @param {Parents | undefined} _
|
|
14
|
+
* Parent node.
|
|
15
|
+
* @param {State} state
|
|
16
|
+
* Info passed around.
|
|
17
|
+
* @param {Info} info
|
|
18
|
+
* Info on surrounding context.
|
|
19
|
+
* @returns {string}
|
|
20
|
+
* Serialized markdown.
|
|
21
|
+
*/
|
|
22
|
+
export function imageReference(node, _, state, info) {
|
|
23
|
+
const type = node.referenceType
|
|
24
|
+
const exit = state.enter('imageReference')
|
|
25
|
+
let subexit = state.enter('label')
|
|
26
|
+
const tracker = state.createTracker(info)
|
|
27
|
+
let value = tracker.move('![')
|
|
28
|
+
const alt = state.safe(node.alt, {
|
|
29
|
+
before: value,
|
|
30
|
+
after: ']',
|
|
31
|
+
...tracker.current()
|
|
32
|
+
})
|
|
33
|
+
value += tracker.move(alt + '][')
|
|
34
|
+
|
|
35
|
+
subexit()
|
|
36
|
+
// Hide that we’re in phrasing as things like attention or code cannot form
|
|
37
|
+
// in references.
|
|
38
|
+
// Character escapes and references *do* work.
|
|
39
|
+
// It is important to know about other constructs, such as table cells.
|
|
40
|
+
const stack = state.stack
|
|
41
|
+
state.stack = stack.filter(function (d) {
|
|
42
|
+
return d !== 'phrasing'
|
|
43
|
+
})
|
|
44
|
+
subexit = state.enter('reference')
|
|
45
|
+
// Note: for proper tracking, we should reset the output positions when we end
|
|
46
|
+
// up making a `shortcut` reference, because then there is no brace output.
|
|
47
|
+
// Practically, in that case, there is no content, so it doesn’t matter that
|
|
48
|
+
// we’ve tracked one too many characters.
|
|
49
|
+
const reference = state.safe(state.associationId(node), {
|
|
50
|
+
before: value,
|
|
51
|
+
after: ']',
|
|
52
|
+
...tracker.current()
|
|
53
|
+
})
|
|
54
|
+
subexit()
|
|
55
|
+
state.stack = stack
|
|
56
|
+
exit()
|
|
57
|
+
|
|
58
|
+
if (type === 'full' || !alt || alt !== reference) {
|
|
59
|
+
value += tracker.move(reference + ']')
|
|
60
|
+
} else if (type === 'shortcut') {
|
|
61
|
+
// Remove the unwanted `[`.
|
|
62
|
+
value = value.slice(0, -1)
|
|
63
|
+
} else {
|
|
64
|
+
value += tracker.move(']')
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return value
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Peek at this node.
|
|
72
|
+
*
|
|
73
|
+
* @returns {string}
|
|
74
|
+
* Start of the serialized markdown.
|
|
75
|
+
*/
|
|
76
|
+
function imageReferencePeek() {
|
|
77
|
+
return '!'
|
|
78
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import {Info, State} from 'mdast-util-to-markdown'
|
|
3
|
+
* @import {Image, Parents} from 'mdast'
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {checkQuote} from '../util/check-quote.js'
|
|
7
|
+
|
|
8
|
+
image.peek = imagePeek
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Serialize an image node.
|
|
12
|
+
*
|
|
13
|
+
* @param {Image} node
|
|
14
|
+
* Node to serialize.
|
|
15
|
+
* @param {Parents | undefined} _
|
|
16
|
+
* Parent node.
|
|
17
|
+
* @param {State} state
|
|
18
|
+
* Info passed around.
|
|
19
|
+
* @param {Info} info
|
|
20
|
+
* Info on surrounding context.
|
|
21
|
+
* @returns {string}
|
|
22
|
+
* Serialized markdown.
|
|
23
|
+
*/
|
|
24
|
+
export function image(node, _, state, info) {
|
|
25
|
+
const quote = checkQuote(state)
|
|
26
|
+
const suffix = quote === '"' ? 'Quote' : 'Apostrophe'
|
|
27
|
+
const exit = state.enter('image')
|
|
28
|
+
let subexit = state.enter('label')
|
|
29
|
+
const tracker = state.createTracker(info)
|
|
30
|
+
let value = tracker.move('![')
|
|
31
|
+
value += tracker.move(
|
|
32
|
+
state.safe(node.alt, {before: value, after: ']', ...tracker.current()})
|
|
33
|
+
)
|
|
34
|
+
value += tracker.move('](')
|
|
35
|
+
|
|
36
|
+
subexit()
|
|
37
|
+
|
|
38
|
+
if (
|
|
39
|
+
// If there’s no url but there is a title…
|
|
40
|
+
(!node.url && node.title) ||
|
|
41
|
+
// If there are control characters or whitespace.
|
|
42
|
+
/[\0- \u007F]/.test(node.url)
|
|
43
|
+
) {
|
|
44
|
+
subexit = state.enter('destinationLiteral')
|
|
45
|
+
value += tracker.move('<')
|
|
46
|
+
value += tracker.move(
|
|
47
|
+
state.safe(node.url, {before: value, after: '>', ...tracker.current()})
|
|
48
|
+
)
|
|
49
|
+
value += tracker.move('>')
|
|
50
|
+
} else {
|
|
51
|
+
// No whitespace, raw is prettier.
|
|
52
|
+
subexit = state.enter('destinationRaw')
|
|
53
|
+
value += tracker.move(
|
|
54
|
+
state.safe(node.url, {
|
|
55
|
+
before: value,
|
|
56
|
+
after: node.title ? ' ' : ')',
|
|
57
|
+
...tracker.current()
|
|
58
|
+
})
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
subexit()
|
|
63
|
+
|
|
64
|
+
if (node.title) {
|
|
65
|
+
subexit = state.enter(`title${suffix}`)
|
|
66
|
+
value += tracker.move(' ' + quote)
|
|
67
|
+
value += tracker.move(
|
|
68
|
+
state.safe(node.title, {
|
|
69
|
+
before: value,
|
|
70
|
+
after: quote,
|
|
71
|
+
...tracker.current()
|
|
72
|
+
})
|
|
73
|
+
)
|
|
74
|
+
value += tracker.move(quote)
|
|
75
|
+
subexit()
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
value += tracker.move(')')
|
|
79
|
+
exit()
|
|
80
|
+
|
|
81
|
+
return value
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Peek at this node.
|
|
86
|
+
*
|
|
87
|
+
* @returns {string}
|
|
88
|
+
* Start of the serialized markdown.
|
|
89
|
+
*/
|
|
90
|
+
function imagePeek() {
|
|
91
|
+
return '!'
|
|
92
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {blockquote} from './blockquote.js'
|
|
2
|
+
import {hardBreak} from './break.js'
|
|
3
|
+
import {code} from './code.js'
|
|
4
|
+
import {definition} from './definition.js'
|
|
5
|
+
import {emphasis} from './emphasis.js'
|
|
6
|
+
import {heading} from './heading.js'
|
|
7
|
+
import {html} from './html.js'
|
|
8
|
+
import {image} from './image.js'
|
|
9
|
+
import {imageReference} from './image-reference.js'
|
|
10
|
+
import {inlineCode} from './inline-code.js'
|
|
11
|
+
import {link} from './link.js'
|
|
12
|
+
import {linkReference} from './link-reference.js'
|
|
13
|
+
import {list} from './list.js'
|
|
14
|
+
import {listItem} from './list-item.js'
|
|
15
|
+
import {paragraph} from './paragraph.js'
|
|
16
|
+
import {root} from './root.js'
|
|
17
|
+
import {strong} from './strong.js'
|
|
18
|
+
import {text} from './text.js'
|
|
19
|
+
import {thematicBreak} from './thematic-break.js'
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Default (CommonMark) handlers.
|
|
23
|
+
*/
|
|
24
|
+
export const handle = {
|
|
25
|
+
blockquote,
|
|
26
|
+
break: hardBreak,
|
|
27
|
+
code,
|
|
28
|
+
definition,
|
|
29
|
+
emphasis,
|
|
30
|
+
hardBreak,
|
|
31
|
+
heading,
|
|
32
|
+
html,
|
|
33
|
+
image,
|
|
34
|
+
imageReference,
|
|
35
|
+
inlineCode,
|
|
36
|
+
link,
|
|
37
|
+
linkReference,
|
|
38
|
+
list,
|
|
39
|
+
listItem,
|
|
40
|
+
paragraph,
|
|
41
|
+
root,
|
|
42
|
+
strong,
|
|
43
|
+
text,
|
|
44
|
+
thematicBreak
|
|
45
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import {State} from 'mdast-util-to-markdown'
|
|
3
|
+
* @import {InlineCode, Parents} from 'mdast'
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
inlineCode.peek = inlineCodePeek
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Serialize an inline code node.
|
|
10
|
+
*
|
|
11
|
+
* @param {InlineCode} node
|
|
12
|
+
* Node to serialize.
|
|
13
|
+
* @param {Parents | undefined} _
|
|
14
|
+
* Parent node.
|
|
15
|
+
* @param {State} state
|
|
16
|
+
* Info passed around.
|
|
17
|
+
* @returns {string}
|
|
18
|
+
* Serialized markdown.
|
|
19
|
+
*/
|
|
20
|
+
export function inlineCode(node, _, state) {
|
|
21
|
+
let value = node.value || ''
|
|
22
|
+
let sequence = '`'
|
|
23
|
+
let index = -1
|
|
24
|
+
|
|
25
|
+
// If there is a single grave accent on its own in the code, use a fence of
|
|
26
|
+
// two.
|
|
27
|
+
// If there are two in a row, use one.
|
|
28
|
+
while (new RegExp('(^|[^`])' + sequence + '([^`]|$)').test(value)) {
|
|
29
|
+
sequence += '`'
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// If this is not just spaces or eols (tabs don’t count), and either the
|
|
33
|
+
// first or last character are a space, eol, or tick, then pad with spaces.
|
|
34
|
+
if (
|
|
35
|
+
/[^\n\r ]/.test(value) &&
|
|
36
|
+
((/^[\n\r ]/.test(value) && /[\n\r ]$/.test(value)) || /^`|`$/.test(value))
|
|
37
|
+
) {
|
|
38
|
+
value = ' ' + value + ' '
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// We have a potential problem: certain characters after eols could result in
|
|
42
|
+
// blocks being seen.
|
|
43
|
+
// For example, if someone injected the string `'\n# b'`, then that would
|
|
44
|
+
// result in an ATX heading.
|
|
45
|
+
// We can’t escape characters in `inlineCode`, but because eols are
|
|
46
|
+
// transformed to spaces when going from markdown to HTML anyway, we can swap
|
|
47
|
+
// them out.
|
|
48
|
+
while (++index < state.unsafe.length) {
|
|
49
|
+
const pattern = state.unsafe[index]
|
|
50
|
+
const expression = state.compilePattern(pattern)
|
|
51
|
+
|
|
52
|
+
// Only look for `atBreak`s.
|
|
53
|
+
// Btw: note that `atBreak` patterns will always start the regex at LF or
|
|
54
|
+
// CR.
|
|
55
|
+
if (!pattern.atBreak) continue
|
|
56
|
+
|
|
57
|
+
/** @type {RegExpExecArray | null} */
|
|
58
|
+
let match
|
|
59
|
+
|
|
60
|
+
while ((match = expression.exec(value))) {
|
|
61
|
+
let position = match.index
|
|
62
|
+
|
|
63
|
+
// Support CRLF (patterns only look for one of the characters).
|
|
64
|
+
if (
|
|
65
|
+
value.charCodeAt(position) === 10 /* `\n` */ &&
|
|
66
|
+
value.charCodeAt(position - 1) === 13 /* `\r` */
|
|
67
|
+
) {
|
|
68
|
+
position--
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
value = value.slice(0, position) + ' ' + value.slice(match.index + 1)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return sequence + value + sequence
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Peek at this node.
|
|
80
|
+
*
|
|
81
|
+
* @returns {string}
|
|
82
|
+
* Start of the serialized markdown.
|
|
83
|
+
*/
|
|
84
|
+
function inlineCodePeek() {
|
|
85
|
+
return '`'
|
|
86
|
+
}
|