summaryrefslogtreecommitdiff
path: root/packages/markdown-it-14.1.0/lib/rules_inline/balance_pairs.mjs
diff options
context:
space:
mode:
authoraltaf-creator <dev@altafcreator.com>2024-05-12 12:14:02 +0700
committeraltaf-creator <dev@altafcreator.com>2024-05-12 12:14:02 +0700
commitd607ac12097afb5cb6f398a4e7b5cf4316efedc6 (patch)
tree6f4bc5b98a6ff3a1c3189f7ef9b570c0481e100d /packages/markdown-it-14.1.0/lib/rules_inline/balance_pairs.mjs
parent7441f212967256ac4c9a93ba0b1f026308a8bfb6 (diff)
self host
Diffstat (limited to 'packages/markdown-it-14.1.0/lib/rules_inline/balance_pairs.mjs')
-rw-r--r--packages/markdown-it-14.1.0/lib/rules_inline/balance_pairs.mjs124
1 files changed, 124 insertions, 0 deletions
diff --git a/packages/markdown-it-14.1.0/lib/rules_inline/balance_pairs.mjs b/packages/markdown-it-14.1.0/lib/rules_inline/balance_pairs.mjs
new file mode 100644
index 0000000..8638d21
--- /dev/null
+++ b/packages/markdown-it-14.1.0/lib/rules_inline/balance_pairs.mjs
@@ -0,0 +1,124 @@
+// For each opening emphasis-like marker find a matching closing one
+//
+
+function processDelimiters (delimiters) {
+ const openersBottom = {}
+ const max = delimiters.length
+
+ if (!max) return
+
+ // headerIdx is the first delimiter of the current (where closer is) delimiter run
+ let headerIdx = 0
+ let lastTokenIdx = -2 // needs any value lower than -1
+ const jumps = []
+
+ for (let closerIdx = 0; closerIdx < max; closerIdx++) {
+ const closer = delimiters[closerIdx]
+
+ jumps.push(0)
+
+ // markers belong to same delimiter run if:
+ // - they have adjacent tokens
+ // - AND markers are the same
+ //
+ if (delimiters[headerIdx].marker !== closer.marker || lastTokenIdx !== closer.token - 1) {
+ headerIdx = closerIdx
+ }
+
+ lastTokenIdx = closer.token
+
+ // Length is only used for emphasis-specific "rule of 3",
+ // if it's not defined (in strikethrough or 3rd party plugins),
+ // we can default it to 0 to disable those checks.
+ //
+ closer.length = closer.length || 0
+
+ if (!closer.close) continue
+
+ // Previously calculated lower bounds (previous fails)
+ // for each marker, each delimiter length modulo 3,
+ // and for whether this closer can be an opener;
+ // https://github.com/commonmark/cmark/commit/34250e12ccebdc6372b8b49c44fab57c72443460
+ /* eslint-disable-next-line no-prototype-builtins */
+ if (!openersBottom.hasOwnProperty(closer.marker)) {
+ openersBottom[closer.marker] = [-1, -1, -1, -1, -1, -1]
+ }
+
+ const minOpenerIdx = openersBottom[closer.marker][(closer.open ? 3 : 0) + (closer.length % 3)]
+
+ let openerIdx = headerIdx - jumps[headerIdx] - 1
+
+ let newMinOpenerIdx = openerIdx
+
+ for (; openerIdx > minOpenerIdx; openerIdx -= jumps[openerIdx] + 1) {
+ const opener = delimiters[openerIdx]
+
+ if (opener.marker !== closer.marker) continue
+
+ if (opener.open && opener.end < 0) {
+ let isOddMatch = false
+
+ // from spec:
+ //
+ // If one of the delimiters can both open and close emphasis, then the
+ // sum of the lengths of the delimiter runs containing the opening and
+ // closing delimiters must not be a multiple of 3 unless both lengths
+ // are multiples of 3.
+ //
+ if (opener.close || closer.open) {
+ if ((opener.length + closer.length) % 3 === 0) {
+ if (opener.length % 3 !== 0 || closer.length % 3 !== 0) {
+ isOddMatch = true
+ }
+ }
+ }
+
+ if (!isOddMatch) {
+ // If previous delimiter cannot be an opener, we can safely skip
+ // the entire sequence in future checks. This is required to make
+ // sure algorithm has linear complexity (see *_*_*_*_*_... case).
+ //
+ const lastJump = openerIdx > 0 && !delimiters[openerIdx - 1].open
+ ? jumps[openerIdx - 1] + 1
+ : 0
+
+ jumps[closerIdx] = closerIdx - openerIdx + lastJump
+ jumps[openerIdx] = lastJump
+
+ closer.open = false
+ opener.end = closerIdx
+ opener.close = false
+ newMinOpenerIdx = -1
+ // treat next token as start of run,
+ // it optimizes skips in **<...>**a**<...>** pathological case
+ lastTokenIdx = -2
+ break
+ }
+ }
+ }
+
+ if (newMinOpenerIdx !== -1) {
+ // If match for this delimiter run failed, we want to set lower bound for
+ // future lookups. This is required to make sure algorithm has linear
+ // complexity.
+ //
+ // See details here:
+ // https://github.com/commonmark/cmark/issues/178#issuecomment-270417442
+ //
+ openersBottom[closer.marker][(closer.open ? 3 : 0) + ((closer.length || 0) % 3)] = newMinOpenerIdx
+ }
+ }
+}
+
+export default function link_pairs (state) {
+ const tokens_meta = state.tokens_meta
+ const max = state.tokens_meta.length
+
+ processDelimiters(state.delimiters)
+
+ for (let curr = 0; curr < max; curr++) {
+ if (tokens_meta[curr] && tokens_meta[curr].delimiters) {
+ processDelimiters(tokens_meta[curr].delimiters)
+ }
+ }
+}