securemark 0.288.1 → 0.289.0

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.
Files changed (34) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +1 -1
  3. package/design.md +3 -3
  4. package/dist/index.js +92 -50
  5. package/markdown.d.ts +1 -7
  6. package/package.json +1 -1
  7. package/src/combinator/control/manipulation/surround.ts +24 -6
  8. package/src/combinator/data/parser/context/delimiter.ts +9 -4
  9. package/src/combinator/data/parser/inits.ts +1 -1
  10. package/src/combinator/data/parser/sequence.ts +1 -1
  11. package/src/combinator/data/parser/some.ts +4 -3
  12. package/src/combinator/data/parser.ts +2 -0
  13. package/src/parser/api/parse.test.ts +2 -2
  14. package/src/parser/block/heading.test.ts +1 -1
  15. package/src/parser/context.ts +1 -2
  16. package/src/parser/inline/annotation.test.ts +1 -0
  17. package/src/parser/inline/bracket.test.ts +2 -0
  18. package/src/parser/inline/bracket.ts +23 -26
  19. package/src/parser/inline/extension/index.test.ts +1 -1
  20. package/src/parser/inline/extension/index.ts +17 -7
  21. package/src/parser/inline/extension/indexee.ts +2 -3
  22. package/src/parser/inline/extension/indexer.test.ts +2 -1
  23. package/src/parser/inline/htmlentity.ts +4 -5
  24. package/src/parser/inline/media.ts +2 -2
  25. package/src/parser/inline/reference.ts +1 -1
  26. package/src/parser/inline/ruby.ts +2 -2
  27. package/src/parser/inline.test.ts +13 -3
  28. package/src/parser/source/escapable.test.ts +5 -5
  29. package/src/parser/source/escapable.ts +8 -1
  30. package/src/parser/source/str.ts +4 -6
  31. package/src/parser/source/text.ts +2 -0
  32. package/src/parser/source/unescapable.test.ts +5 -5
  33. package/src/parser/source/unescapable.ts +14 -8
  34. package/src/parser/visibility.ts +2 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.289.0
4
+
5
+ - Improve bracket parser.
6
+
7
+ ## 0.288.2
8
+
9
+ - Fix signature syntax.
10
+
3
11
  ## 0.288.1
4
12
 
5
13
  - Refactoring.
package/README.md CHANGED
@@ -67,7 +67,7 @@ Secure markdown renderer working on browsers for user input data.
67
67
 
68
68
  |P| Operators |
69
69
  |-|------------------------------|
70
- |9| \n, \\\n |
70
+ |9| \n |
71
71
  |6| ` |
72
72
  |5| ${}$ |
73
73
  |4| [% %] |
package/design.md CHANGED
@@ -290,8 +290,8 @@ CodeMirrorが素では速いがVimModeでは数万文字程度でも耐え難く
290
290
  ### バックトラック
291
291
 
292
292
  SecuremarkのAnnotation構文に典型的であるように文脈を変更する構文の中にその文脈に依存し変更される他の構文が存在する場合文脈の相違から解析結果を再利用不能(`αAβ | αA'B`)なバックトラックが生じる。またこの結果再帰的バックトラックが生じる可能性があり再帰的バックトラックは一般的にメモ化により解決されるがCommonMarkは実行性能追及のためメモ化を廃止しているためメモ化により性能を低下させてまで文脈依存構文の問題を解決するつもりはないと思われる(すなわちCommonMarkは機械を至上とし人間に制約を課す低水準の言語であり人間の需要を至上とするSecuremarkとは対極に位置する)。従って現在の再帰的バックトラックなしで解析可能な構文と最小計算量に制約されるCommonMarkにはこれ以上再帰的バックトラックが生じる可能性を増加させて文脈依存構文を追加できないという拡張性の欠陥が存在する。CommonMarkの仕様策定者が構文の拡張に(名称を維持するか否かにかかわらず)不自然なまでに消極的または進展がないのは正当な理由や怠慢からでなく文脈依存構文を追加するにつれて構文解析戦略の失敗が明白になっていくためおよび現在の高い実行性能を低下させたくないためであり陳腐な自尊心を守るためにこのような拡張性の欠陥を秘匿しCommonMarkとその仕様策定者である自分の評価が下がらないよう画策しているからである。でなければ何年も隠さず速やかにこの拡張性の欠陥を公表して助力を求めていなければならず不都合な事実を隠し全Markdown利用者および開発者を不必要に足止めした罪は重い。CommonMarkは`~~a~~`のような文脈自由構文は容易に追加できるがこうしたマージンを失えばもはや後はない。
293
- CommonMarkは小さく単純であるがゆえに正しくいられる象牙の塔であり仕様策定者はこの正しさを失わず正しいままでいたいがために象牙の塔に引きこもり小さな表面的完全性に固執し続けているに過ぎない。しかし実際にはCommonMarkはまったく完全ではなく本来文脈依存構文である構文を文脈自由構文として解析しているため破綻している部分があり実際のところCommonMarkは最初から現在までずっと壊れている。またCommonMarkはバックトラックなく最小計算量で解析するために文脈自由言語として設計されているが実際には文脈依存言語であるMarkdownから文脈依存構文を文脈自由構文に変換して除去することができずCommonMarkは最初の数年間は再帰的バックトラックに気づかず最悪計算量が指数関数計算量になっており修正後は最悪計算量が当初の想定の1nから32nへと32倍に劇的に悪化している。CommonMarkは未だにバックトラックを忌避し1nの最小計算量に固執しているがそんなものはとっくの昔に破綻してるのを未練がましく執着しているだけである。最悪計算量が32nにまで悪化するのであれば計算量が少ないよう適切に設計された文脈依存言語と大差なく最初から文脈依存言語として適切に設計するほうが自然で破綻がなく拡張性を確保できていた。文脈依存構文を強引に文脈自由構文として解析して最悪計算量が当初の想定の1nから32nに劇的に悪化し結局文脈依存言語の妥当な最悪計算量の水準に落ちていることから文脈自由言語として設計されたCommonMarkの破綻と失敗は明らかでありCommonMarkは文脈自由構文に固執せず最初から多少の文脈依存構文を許容するよう設計しなければならなかった。実際には文脈依存言語であるにもかかわらず文脈自由言語としてしか構文解析できなければ構文解析が破綻し構文が増えるほど破綻が拡大することは自明でありすでに破綻済みで失敗済みのCommonMarkに未来などない。文脈依存言語であるMarkdownに対して文脈自由構文解析器として作られたCommonMarkは最初から技術選択を間違え失敗しており最初から破綻していた。Markdownを文脈自由言語として解析しようとして行き詰ったCommonMarkとその閉塞に技術的合理性はなくCommonMarkは最初からの失敗していた過去の遺物であり廃棄すべき負債である。CommonMarkに動きがないのはすでに破綻しており死んでいることに気付かれないように死んでいるからに過ぎない。このようにCommonMarkは完全に破綻し失敗に終わっているためCommonMarkの拡張や発展を期待しても無駄であり既存の文脈依存構文による破綻がなく新たに文脈依存構文を追加可能な拡張性の高いMarkdown仕様は新しく作り直さなければ作れない。しかしCommonMarkの仕様策定者は独自の新しい仕様においてもMarkdownをバックトラックを排除した文脈自由言語として設計しているため救いようがない。しかもその構文と仕様は機械可読性を至上としているため非常に醜く人間が書くことも読むことも困難で実用性の欠如したものである。
294
- Securemarkはスーパークラス構文が解析に失敗した入力をサブクラス構文で解析しないことにより再帰的バックトラックを回避する(ここで解析中の構文自身はスーパークラスとサブクラスの両方に含まれるものとする)。スーパークラス構文A(`αAβ`)の解析が失敗すればサブクラス構文B(`α'A'β'`)の解析も失敗することは自明であり解析を試みるまでもなく省略できる。これは構文の文法が生成する言語空間がスーパーセットとサブセットの関係にあるならスーパーセットの言語空間の外にある文字列はサブセットの言語空間の内に入る余地がないことからも自明である(この解析法は事前処理によっても可能だが文脈内外のオートリンクURLの括弧解析などを高速に行うことは困難であるためMarkdownをこの事前処理により高速化することは難しい)。メモ化は解析結果を再利用することで結果的に副次的効果としてバックトラックを回避しているのでありメモ化はバックトラックを回避するだけなら過剰機能であり不要である(メモ化はバックトラックがなければ使用されないためバックトラックの少ないほとんどの入力に対してはほとんど使用されず無駄であり空間計算量を常に不必要に数倍以上に増加させてまで行う利益は少ないことから構文解析において必須ではない。バックトラック回避のためにメモ化するとバックトラックなしで解析可能な場合も常に不必要に空間計算量が増加することがメモ化の最大の欠点である(この問題は解析失敗時のみメモ化すれば解消可能のはずだが基本的にはこうなる)。特に文脈自由構文解析器におけるメモ化の使用は完全に無駄でありバグである。バックトラックが他の方法で解決されるならば最終的に文脈ごと破棄され使用されないメモ化も無駄であり複数の文脈で解析結果が同一である文脈独立性のある構文ならメモ化した解析結果を異なる文脈で再利用でき有用だがそのような構文は基本的に少数であるため効果が限定的であり最悪計算量は改善されない)。この独自の解析法によりSecuremarkはメモ化なしに線形時間で解析不能な文脈依存言語をメモ化なしでおおよそ12nの最悪時間計算量に改善しさらに一定時間内で解析不能な入力の影響を解析時間と解析範囲の局限することで解決している。この解析方法はほとんどの自然な入力に対して1nに近い時間で効率的に動作し、最悪計算量で低速に動作させる入力に対してもこの開発効率と安全性優先の低速な実装をサーバーで使用し多数のユーザーのリクエストに応じるには低速で脆弱性となる可能性があるがクライアントで個別のユーザーの操作に応じるには十分高速であるためクライアントで解析する限り解析の効率または速度が実用上問題となることはなく仕様が固まり実行効率優先の高速な実装に移れば速度面の懸念もないだろう。またSecuremarkはメモ化を行っていないため実装依存の非効率性を除けば空間計算量も小さく、異なる構文や状態の解析結果を利用して未知の入力に対してもバックトラックを回避できるためメモ化より時間計算量が小さい。時間計算量と空間計算量を合わせてO(n, n)と表記すると文脈依存言語の通常の最悪計算量はO(n^2, n)、メモ化により効率化できた場合もO(nm, nm)(解析結果の構文木等を記録するため空間使用量S(m)>=m byte)に過ぎないがSecuremarkの失敗単一化はO(nm, n + nm)(解析失敗のフラグしか記録しないためS(m)=m bit。また包含文字列を含め全体でn byteの構文1つに対してメモ化は少なくともn byteを消費するが失敗単一化のメモリ消費量は構文全体のサイズにかかわらず1 bit固定である。なお成功フラグによる解析は解析済みかの情報が追加で必要になり処理が複雑化かつほとんどの成功した解析に対してメモリ消費と追加処理が発生し解析効率が全体として悪化するが失敗フラグは少数の失敗した解析でしか解析効率が悪化しないため失敗フラグを記録するほうが全体として解析効率が高く優れている)と極めて効率的であり最も優れている。なお現在のSecuremarkは開発効率優先の実装により空間計算量が低下しているが時間計算量は低下せずメモ化より優れている。またSecuremarkの再帰数制限はパーサーコンビネーターの使用による実装依存の制限であるため再帰が生じないよう書き換えれば再帰数制限もない。SecuremarkをCommonMarkのような再帰数制限のない実装に変換することは設計上何の支障もないがCommonMarkをSecuremarkのような文脈依存言語解析器に変更することは根本的な設計変更なしに不可能である。例えば二重リンク`[[]()]()`を解析するときCommonMarkはバックトラックと計算量を最小化すべく文脈自由構文解析器として設計されているためリンク構文内を異なる文脈として解析せず外側のリンク構文の解析を破棄して内側のみリンクとして解析するがSecuremarkは文脈依存構文解析器とし設計されているため内側のリンク構文を無効化して外側のみリンクとして解析する。旧構文だけ従来通り文脈自由構文として解析し新構文を文脈依存構文として解析することも不可能ではないが構文としても解析器としてもキメラ的な非常に不自然で歪なものとなり解析規則の一貫性のなさによりユーザーを混乱させることになる。いずれにせよCommonMarkはこのような根本的設計変更なしに文脈依存構文解析器に変更して拡張性を確保することはできないためMarkdownは素直にCommonMarkの文脈自由言語特有の解析規則を捨てて素直な文脈依存構文言語として新しい仕様を作るのが賢明である。
293
+ CommonMarkは小さく単純であるがゆえに正しくいられる象牙の塔であり仕様策定者はこの正しさを失わず正しいままでいたいがために象牙の塔に引きこもり小さな表面的完全性に固執し続けているに過ぎない。しかしCommonMarkは実際にはまったく完全ではなく本来文脈依存構文である構文を文脈自由構文として解析しているため破綻している部分があり実際のところCommonMarkは最初から現在までずっと壊れている。またCommonMarkはバックトラックなく最小計算量で解析するために文脈自由言語として設計されているが実際には文脈依存言語であるMarkdownから文脈依存構文を文脈自由構文に変換して除去することに失敗しているためCommonMarkは最初の数年間は再帰的バックトラックに気づかず最悪計算量が指数関数計算量になっており修正後は最悪計算量が当初の想定の2nから32nへと劇的に悪化している。CommonMarkが最初の数年間指数関数計算量であった事実はCommonMarkが初歩的な再帰的バックトラックの原理すら理解していない素人により設計された素人仕事である事実を証明している。一貫して素人により設計開発仕様策定されているCommonMarkは未だにバックトラックを忌避し2nの最小計算量に固執しているがそんなものはとっくの昔に破綻してるのを未練がましく執着しているだけである。最悪計算量が32nにまで悪化するのであれば計算量が少ないよう適切に設計された文脈依存言語と大差なく最初から文脈依存言語として適切に設計するほうが自然で破綻がなく拡張性を確保できていた。文脈依存構文を強引に文脈自由構文として解析して最悪計算量が当初の想定の2nから32nに劇的に悪化し結局文脈依存言語の妥当な最悪計算量の水準に落ちていることから文脈自由言語として設計されたCommonMarkの破綻と失敗は明らかでありCommonMarkは文脈自由構文に固執せず最初から多少の文脈依存構文を許容するよう設計しなければならなかった。実際には文脈依存言語であるにもかかわらず文脈自由言語としてしか構文解析できなければ構文解析が破綻し構文が増えるほど破綻が拡大することは自明でありすでに破綻済みで失敗済みのCommonMarkに未来などない。文脈依存言語であるMarkdownに対して文脈自由構文解析器として作られたCommonMarkは最初から技術選択を間違え失敗しており最初から破綻していた。CommonMarkが文脈依存言語を文脈自由言語として最小計算量で解析するために使用した手法は邪道の小手先の技術に過ぎずCommonMarkは邪道を選んだ挙句失敗に終わったのである。文脈依存言語を文脈依存言語のまま解析する正道を選んだSecuremarkが正着し文脈自由言語に歪める邪道を選んだCommonMarkが失着に終わったのは当然の帰結であり最初の言語選択の時点で決まっていたことである。文脈依存言語であるMarkdownを文脈自由言語として解析しようとして行き詰ったCommonMarkとその閉塞に技術的合理性はなくCommonMarkは最初からの失敗していた過去の遺物であり廃棄すべき負債である。CommonMarkに動きがないのはすでに破綻しており死んでいることに気付かれないように死んでいるからに過ぎない。このようにCommonMarkは完全に破綻し失敗に終わっているためCommonMarkの拡張や発展を期待しても無駄であり既存の文脈依存構文による破綻がなく新たに文脈依存構文を追加可能な拡張性の高いMarkdown仕様は新しく作り直さなければ作れない。しかしCommonMarkの仕様策定者は独自の新しい仕様においてもMarkdownをバックトラックを排除した文脈自由言語として設計しているため救いようがない。しかもその構文と仕様は機械可読性を至上としているため非常に醜く人間が書くことも読むことも困難で実用性の欠如したものである。
294
+ Securemarkはスーパークラス構文が解析に失敗した入力をサブクラス構文で解析しないことにより再帰的バックトラックを回避する(ここで解析中の構文自身はスーパークラスとサブクラスの両方に含まれるものとする)。スーパークラス構文A(`αAβ`)の解析が失敗すればサブクラス構文B(`α'A'β'`)の解析も失敗することは自明であり解析を試みるまでもなく省略できる。これは構文の文法が生成する言語空間がスーパーセットとサブセットの関係にあるならスーパーセットの言語空間の外にある文字列はサブセットの言語空間の内に入る余地がないことからも自明である(この解析法は事前処理によっても可能だが文脈内外のオートリンクURLの括弧解析などを高速に行うことは困難であるためMarkdownをこの事前処理により高速化することは難しい)。メモ化は解析結果を再利用することで結果的に副次的効果としてバックトラックを回避しているのでありメモ化はバックトラックを回避するだけなら過剰機能であり不要である(メモ化はバックトラックがなければ使用されないためバックトラックの少ないほとんどの入力に対してはほとんど使用されず無駄であり空間計算量を常に不必要に数倍以上に増加させてまで行う利益は少ないことから構文解析において必須ではない。バックトラック回避のためにメモ化するとバックトラックなしで解析可能な場合も常に不必要に空間計算量が増加することがメモ化の最大の欠点である(この問題は解析失敗時のみメモ化すれば解消可能のはずだが基本的にはこうなる)。特に文脈自由構文解析器におけるメモ化の使用は完全に無駄でありバグである。バックトラックが他の方法で解決されるならば最終的に文脈ごと破棄され使用されないメモ化も無駄であり複数の文脈で解析結果が同一である文脈独立性のある構文ならメモ化した解析結果を異なる文脈で再利用でき有用だがそのような構文は基本的に少数であるため効果が限定的であり最悪計算量は改善されない)。この独自の解析法により、CommonMarkならば最悪時間計算量384nを要する拡張Markdown言語をSecuremarkはメモ化なしで12nの最悪時間計算量で解析しさらに一定時間内で解析不能な入力の影響を解析時間と解析範囲の制限により局限している。またSecuremarkはメモ化を行っていないため実装依存の非効率性を除けば空間計算量も小さい。時間計算量と空間計算量を合わせてO(n, n)と表記すると文脈依存言語の通常の最悪計算量はO(n^2, n)、メモ化により効率化できた場合もO(nm, nm)(S(m)>=m byte)(解析結果の構文木等を記録するため空間使用量S(m)>=m byte)に過ぎないがSecuremarkのマーキング法はO(nm, nm)(S(m)=m bit)(解析の失敗フラグしか記録しないためS(m)=m bit。また包含文字列を含め全体でn byteの構文1つに対してメモ化は少なくともn byteを消費するがマーキング法のメモリ消費量は構文全体のサイズにかかわらず1bit固定である。よって100KBの構文1つに対してメモ化は100KB以上消費するがこの場合もマーキング法は1bitしか消費しない。なお成功フラグによる解析は解析済みかの情報が追加で必要になり処理が複雑化かつほとんどの成功した解析に対してメモリ消費と追加処理が発生し解析効率が全体として悪化するが失敗フラグは少数の失敗した解析でしか解析効率が悪化しないため失敗フラグを記録するほうが全体として解析効率が高く優れている)と極めて効率的であり最も優れている。以上のようにSecuremarkの構文解析アルゴリズムの優位性は理論と実践いずれにおいても革新的かつ圧倒的である。現在のSecuremarkは開発効率と安全性優先の実装により実行性能が大きく低下しているが最悪計算量で低速に動作させる入力に対してもこの実装をサーバーで使用し多数のユーザーのリクエストに応じるには低速で脆弱性となる可能性があるがクライアントで個別のユーザーの操作に応じるには十分高速であるためクライアントで解析する限り解析の効率または速度が実用上問題となることはなく仕様が固まり実行効率優先の高速な実装に移れば速度面の懸念もないだろう。またSecuremarkの再帰数制限はパーサーコンビネーターの使用による実装依存の制限であるため再帰が生じないよう書き換えれば再帰数制限もない。SecuremarkをCommonMarkのような再帰数制限のない実装に変換することは設計上何の支障もないがCommonMarkをSecuremarkのような正常な文脈依存言語解析器に変更することは解析規則の破壊的変更なしに不可能である。具体的には二重リンク`[[]()]()`を解析するときCommonMarkはバックトラックと計算量を最小化すべく文脈自由構文解析器として設計されているためリンク構文内をリンク構文が定義されていない異なる文脈として解析せず外側のリンク構文の解析を破棄して内側のみリンク構文として解析するがSecuremarkは文脈依存構文解析器とし設計されているためリンク構文内にリンク構文が定義されておらず外側のみリンクとして解析する(ここでCommonMarkはリンク構文`[]()`の文脈自由化に角括弧`[]`に対しては成功したが丸括弧`()`に対しては失敗したことで最悪計算量が指数関数計算量ないし32nに悪化した)。多くのプログラミング言語を見ても明らかなように文脈依存言語は構文内で使用可能な構文を定義しその他の構文は構文内で使用できず例外処理するのが通常でありCommonMarkのように本来使用不能な構文を外側の構文を無効化して使用可能に変える異常な言語はほとんどの人間はCommonMark以外に見たことがないだろう。ほぼすべての人間において他のすべての言語が同じ一貫した規則を持ち同じ規則で統一的に使用できるのに対してCommonMarkだけが他と異なる異常な挙動をして認知的負荷をかけるのである。破壊的変更を避けるため旧構文で使用した苦肉の策を不必要に新構文でも使用して一貫させれば文脈依存言語なのに文脈自由言語の苦肉の策で解析される非常に不自然で理論的に設計ミスが明白で実用的にも認知的負荷の高い言語となり旧構文だけ従来通り文脈自由構文として解析し新構文を文脈依存構文として解析すればキメラ的な非常に不自然かつ歪で一貫性のない解析規則によりCommonMarkという一つの言語の中だけでもユーザーを混乱させるものとなる。そして構文エラーであることが明らかな二重リンクを意図的に入力することはほぼないためCommonMarkの異常な挙動はこれまであまり人目に付かなかったがMarkdownに文脈依存構文を追加して明らかでない構文エラーが頻発すると他の言語と逆に外側の構文を無効化していくCommonMarkの異常な挙動を頻繁に目撃し認知的負荷をかけられることになる。このようにCommonMarkは内部設計だけ文脈依存構文解析器に変更しても理論的齟齬が解析結果と使用感に明白に表れるためCommonMarkが失敗した言語である事実は到底隠し切れるものではない。Markdownはもはや負債以外の何物でもないCommonMarkの異常な解析規則を捨てて素直な文脈依存構文言語として新しい仕様を作り直すのが賢明である。
295
295
 
296
296
  ### 最適化
297
297
 
@@ -323,7 +323,7 @@ Markdownに本当に必要な仕様はSecuremarkのクラス化制約のよう
323
323
  - リンクのURLを効率的に解析不可能
324
324
  - altはまだしもURLは文脈依存構文としての解析を避けられないため再帰もまた避けられず公式デモページのCommonMarkで`[](`を1万文字程度繰り返しただけで解析時間が1秒を超える
325
325
  - この欠陥は入れ子数を制限することで回避可能だがこれはCommonmarkは文脈依存構文全般に入れ子数制限を要することを意味する
326
- - CommonMarkは最初のバージョンから数年後にこの欠陥を入れ子数制限により修正しこれにより最悪計算量が当初の想定の1nから32nへと32倍に劇的に悪化したことから文脈自由言語および最小計算量としての設計と開発が破綻し失敗に終わったことが明らかである
326
+ - CommonMarkは最初のバージョンから数年後にこの欠陥を入れ子数制限により修正しこれにより最悪計算量が当初の想定の2nから32nへと32倍に劇的に悪化したことから文脈自由言語および最小計算量としての設計と開発が破綻し失敗に終わったことが明らかである
327
327
  - これほど計算量が悪ければ入れ子数制限付き文脈依存言語と大差ない計算量であり素直に文脈依存言語として作り直したほうが遥かに拡張性と発展性が高く優れている
328
328
  - 計算資源は使うためにあるにもかかわらず言語と一致しない不適切な解析方法を使用してまでこの程度の計算資源を惜しんで人間に不便と不自由を強いて生産性を下げるのは本末転倒である
329
329
  - 計算機は人間の生産性に奉仕しなければならない
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! securemark v0.288.1 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
1
+ /*! securemark v0.289.0 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
2
2
  (function webpackUniversalModuleDefinition(root, factory) {
3
3
  if(typeof exports === 'object' && typeof module === 'object')
4
4
  module.exports = factory(require("Prism"), require("DOMPurify"));
@@ -3177,11 +3177,15 @@ function surround(opener, parser, closer, optional = false, f, g, backtracks = [
3177
3177
  }) => {
3178
3178
  const lmr_ = source;
3179
3179
  if (lmr_ === '') return;
3180
+ const {
3181
+ linebreak
3182
+ } = context;
3183
+ context.linebreak = undefined;
3180
3184
  const res1 = opener({
3181
3185
  source: lmr_,
3182
3186
  context
3183
3187
  });
3184
- if (res1 === undefined) return;
3188
+ if (res1 === undefined) return void revert(context, linebreak);
3185
3189
  const rl = (0, parser_1.eval)(res1);
3186
3190
  const mr_ = (0, parser_1.exec)(res1);
3187
3191
  for (const backtrack of backtracks) {
@@ -3197,7 +3201,7 @@ function surround(opener, parser, closer, optional = false, f, g, backtracks = [
3197
3201
  if (!(pos in backtracks)) continue;
3198
3202
  // bracket only
3199
3203
  const shift = backtrack >>> 2 === state >>> 2 ? state & 3 : 0;
3200
- if (backtracks[pos] & 1 << (backtrack >>> 2) + shift) return;
3204
+ if (backtracks[pos] & 1 << (backtrack >>> 2) + shift) return void revert(context, linebreak);
3201
3205
  }
3202
3206
  }
3203
3207
  }
@@ -3212,14 +3216,14 @@ function surround(opener, parser, closer, optional = false, f, g, backtracks = [
3212
3216
  context.backtrack = state;
3213
3217
  const rm = (0, parser_1.eval)(res2);
3214
3218
  const r_ = (0, parser_1.exec)(res2, mr_);
3215
- if (!rm && !optional) return;
3219
+ if (!rm && !optional) return void revert(context, linebreak);
3216
3220
  const res3 = closer({
3217
3221
  source: r_,
3218
3222
  context
3219
3223
  });
3220
3224
  const rr = (0, parser_1.eval)(res3);
3221
3225
  const rest = (0, parser_1.exec)(res3, r_);
3222
- if (rest.length === lmr_.length) return;
3226
+ if (rest.length === lmr_.length) return void revert(context, linebreak);
3223
3227
  for (const backtrack of backtracks) {
3224
3228
  if (backtrack & 2 && rr === undefined) {
3225
3229
  const {
@@ -3232,7 +3236,14 @@ function surround(opener, parser, closer, optional = false, f, g, backtracks = [
3232
3236
  backtracks[source.length + offset - 1] |= 1 << (backtrack >>> 2) + shift;
3233
3237
  }
3234
3238
  }
3235
- return rr ? f ? f([rl, rm, rr], rest, context) : [(0, array_1.push)((0, array_1.unshift)(rl, rm ?? []), rr), rest] : g ? g([rl, rm, mr_], rest, context) : undefined;
3239
+ context.recent = [lmr_.slice(0, lmr_.length - mr_.length), mr_.slice(0, mr_.length - r_.length), r_.slice(0, r_.length - rest.length)];
3240
+ const result = rr ? f ? f([rl, rm, rr], rest, context) : [(0, array_1.push)((0, array_1.unshift)(rl, rm ?? []), rr), rest] : g ? g([rl, rm, mr_], rest, context) : undefined;
3241
+ if (result) {
3242
+ context.linebreak ??= linebreak;
3243
+ } else {
3244
+ revert(context, linebreak);
3245
+ }
3246
+ return result;
3236
3247
  };
3237
3248
  }
3238
3249
  exports.surround = surround;
@@ -3251,6 +3262,9 @@ function match(pattern) {
3251
3262
  };
3252
3263
  }
3253
3264
  }
3265
+ function revert(context, linebreak) {
3266
+ context.linebreak = linebreak;
3267
+ }
3254
3268
  function open(opener, parser, optional = false) {
3255
3269
  return surround(opener, parser, '', optional);
3256
3270
  }
@@ -3569,7 +3583,8 @@ class Delimiters {
3569
3583
  const {
3570
3584
  signature,
3571
3585
  matcher,
3572
- precedence
3586
+ precedence,
3587
+ linebreakable
3573
3588
  } = delims[i];
3574
3589
  const memory = registry(signature);
3575
3590
  const index = memory[0]?.index ?? delimiters.length;
@@ -3579,6 +3594,7 @@ class Delimiters {
3579
3594
  signature,
3580
3595
  matcher,
3581
3596
  precedence,
3597
+ linebreakable: linebreakable,
3582
3598
  state: true
3583
3599
  };
3584
3600
  delimiters[index] = delimiter;
@@ -3631,7 +3647,10 @@ class Delimiters {
3631
3647
  delimiters[indexes[i]].state = true;
3632
3648
  }
3633
3649
  }
3634
- match(source, precedence = 0) {
3650
+ match(source, {
3651
+ precedence = 0,
3652
+ linebreak = 0
3653
+ }) {
3635
3654
  const {
3636
3655
  delimiters
3637
3656
  } = this;
@@ -3640,6 +3659,7 @@ class Delimiters {
3640
3659
  if (delimiter.precedence <= precedence || !delimiter.state) continue;
3641
3660
  switch (delimiter.matcher(source)) {
3642
3661
  case true:
3662
+ if (!delimiter.linebreakable && linebreak > 0) return false;
3643
3663
  return true;
3644
3664
  case false:
3645
3665
  return false;
@@ -3659,7 +3679,7 @@ Delimiters.matcher = (0, memoize_1.memoize)(pattern => {
3659
3679
  case 'string':
3660
3680
  return source => source.slice(0, pattern.length) === pattern || undefined;
3661
3681
  case 'object':
3662
- return (0, memoize_1.reduce)(source => pattern.test(source) || undefined);
3682
+ return source => pattern.test(source) || undefined;
3663
3683
  }
3664
3684
  }, _a.signature);
3665
3685
 
@@ -3687,7 +3707,7 @@ function inits(parsers, resume) {
3687
3707
  let nodes;
3688
3708
  for (let len = parsers.length, i = 0; i < len; ++i) {
3689
3709
  if (rest === '') break;
3690
- if (context.delimiters?.match(rest, context.precedence)) break;
3710
+ if (context.delimiters?.match(rest, context)) break;
3691
3711
  const result = parsers[i]({
3692
3712
  source: rest,
3693
3713
  context
@@ -3726,7 +3746,7 @@ function sequence(parsers, resume) {
3726
3746
  let nodes;
3727
3747
  for (let len = parsers.length, i = 0; i < len; ++i) {
3728
3748
  if (rest === '') return;
3729
- if (context.delimiters?.match(rest, context.precedence)) return;
3749
+ if (context.delimiters?.match(rest, context)) return;
3730
3750
  const result = parsers[i]({
3731
3751
  source: rest,
3732
3752
  context
@@ -3759,10 +3779,11 @@ const array_1 = __webpack_require__(6876);
3759
3779
  function some(parser, end, delimiters = [], limit = -1) {
3760
3780
  if (typeof end === 'number') return some(parser, undefined, delimiters, end);
3761
3781
  const match = delimiter_1.Delimiters.matcher(end);
3762
- const delims = delimiters.map(([delimiter, precedence]) => ({
3782
+ const delims = delimiters.map(([delimiter, precedence, linebreakable = true]) => ({
3763
3783
  signature: delimiter_1.Delimiters.signature(delimiter),
3764
3784
  matcher: delimiter_1.Delimiters.matcher(delimiter),
3765
- precedence
3785
+ precedence,
3786
+ linebreakable
3766
3787
  }));
3767
3788
  return ({
3768
3789
  source,
@@ -3778,7 +3799,7 @@ function some(parser, end, delimiters = [], limit = -1) {
3778
3799
  while (true) {
3779
3800
  if (rest === '') break;
3780
3801
  if (match(rest)) break;
3781
- if (context.delimiters?.match(rest, context.precedence)) break;
3802
+ if (context.delimiters?.match(rest, context)) break;
3782
3803
  const result = parser({
3783
3804
  source: rest,
3784
3805
  context
@@ -5672,7 +5693,7 @@ Object.defineProperty(exports, "__esModule", ({
5672
5693
  }));
5673
5694
  exports.CmdRegExp = void 0;
5674
5695
  exports.CmdRegExp = {
5675
- Escape: /\x1B/g
5696
+ Error: /\x07/g
5676
5697
  };
5677
5698
 
5678
5699
  /***/ },
@@ -6098,15 +6119,21 @@ const inline_1 = __webpack_require__(7973);
6098
6119
  const source_1 = __webpack_require__(8745);
6099
6120
  const array_1 = __webpack_require__(6876);
6100
6121
  const dom_1 = __webpack_require__(394);
6101
- const indexA = /^[0-9A-Za-z]+(?:(?:[.-]|, )[0-9A-Za-z]+)*(?=\))/;
6102
- const indexF = new RegExp(indexA.source.replace(', ', '[,、]').replace(/[09AZaz.]|\-(?!\w)|\)(?=\)$)/g, c => String.fromCodePoint(c.codePointAt(0) + 0xFEE0)));
6103
- exports.bracket = (0, combinator_1.lazy)(() => (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, source_1.str)(indexA))), (0, source_1.str)(')'), false, undefined, undefined, [3 | 8 /* Backtrack.bracket */]), (0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, ')', [[')', 1]]))), (0, source_1.str)(')'), true, ([as, bs = [], cs], rest) => [[(0, dom_1.html)('span', {
6122
+ const indexA = /^[0-9A-Za-z]+(?:(?:[.-]|, )[0-9A-Za-z]+)*$/;
6123
+ const indexF = new RegExp(indexA.source.replace(', ', '[,、]').replace(/[09AZaz.]|\-(?!\w)/g, c => String.fromCodePoint(c.codePointAt(0) + 0xFEE0)));
6124
+ exports.bracket = (0, combinator_1.lazy)(() => (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, ')', [[')', 1]]))), (0, source_1.str)(')'), true, ([as, bs = [], cs], rest, {
6125
+ recent = []
6126
+ }) => [indexA.test(recent[1]) ? recent : [(0, dom_1.html)('span', {
6104
6127
  class: 'paren'
6105
- }, (0, dom_1.defrag)((0, array_1.push)((0, array_1.unshift)(as, bs), cs)))], rest], ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest], [3 | 8 /* Backtrack.bracket */]), (0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, source_1.str)(indexF))), (0, source_1.str)(')'), false, undefined, undefined, [3 | 8 /* Backtrack.bracket */]), (0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, ')', [[')', 1]]))), (0, source_1.str)(')'), true, ([as, bs = [], cs], rest) => [[(0, dom_1.html)('span', {
6128
+ }, (0, dom_1.defrag)((0, array_1.push)((0, array_1.unshift)(as, bs), cs)))], rest], ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest], [2 | 8 /* Backtrack.bracket */]), (0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, ')', [[')', 1]]))), (0, source_1.str)(')'), true, ([as, bs = [], cs], rest, {
6129
+ recent = []
6130
+ }) => [indexF.test(recent[1]) ? recent : [(0, dom_1.html)('span', {
6106
6131
  class: 'paren'
6107
- }, (0, dom_1.defrag)((0, array_1.push)((0, array_1.unshift)(as, bs), cs)))], rest], ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, ']', [[']', 1]]))), (0, source_1.str)(']'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest], [3 | 8 /* Backtrack.bracket */]), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, ']', [[']', 1]]))), (0, source_1.str)(']'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, '}', [['}', 1]]))), (0, source_1.str)('}'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest], [3 | 8 /* Backtrack.bracket */]), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, '}', [['}', 1]]))), (0, source_1.str)('}'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]),
6132
+ }, (0, dom_1.defrag)((0, array_1.push)((0, array_1.unshift)(as, bs), cs)))], rest], ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, ']', [[']', 1]]))), (0, source_1.str)(']'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest], [2 | 8 /* Backtrack.bracket */]), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, ']', [[']', 1]]))), (0, source_1.str)(']'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, '}', [['}', 1]]))), (0, source_1.str)('}'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest], [2 | 8 /* Backtrack.bracket */]), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, '}', [['}', 1]]))), (0, source_1.str)('}'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]),
6108
6133
  // 改行禁止はバックトラックなしでは内側の構文を破壊するため安易に行えない。
6109
- (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(2, (0, combinator_1.some)(inline_1.inline, '"', [['\n', 9], ['"', 2]]))), (0, source_1.str)('"'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)(''), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(2, (0, combinator_1.some)(inline_1.inline, '”', [['\n', 9], ['”', 2]]))), (0, source_1.str)('”'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('‘'), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(2, (0, combinator_1.some)(inline_1.inline, '’', [['\n', 9], ['’', 2]]))), (0, source_1.str)('’'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('「'), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(2, (0, combinator_1.some)(inline_1.inline, '」', [['\n', 9], ['」', 2]]))), (0, source_1.str)('」'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('『'), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(2, (0, combinator_1.some)(inline_1.inline, '』', [['\n', 9], ['』', 2]]))), (0, source_1.str)('』'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest])]));
6134
+ (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(2, (0, combinator_1.some)(inline_1.inline, '"', [['"', 2, false]]))), (0, source_1.str)('"'), true, ([as, bs = [], cs], rest, {
6135
+ linebreak = 0
6136
+ }) => linebreak > rest.length ? [(0, array_1.unshift)(as, bs), cs[0] + rest] : [(0, array_1.push)((0, array_1.unshift)(as, bs), cs), rest], ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest], [2 | 8 /* Backtrack.bracket */])]));
6110
6137
 
6111
6138
  /***/ },
6112
6139
 
@@ -6275,9 +6302,11 @@ Object.defineProperty(exports, "__esModule", ({
6275
6302
  value: true
6276
6303
  }));
6277
6304
  exports.dataindex = exports.signature = exports.index = void 0;
6305
+ const parser_1 = __webpack_require__(605);
6278
6306
  const combinator_1 = __webpack_require__(3484);
6279
6307
  const inline_1 = __webpack_require__(7973);
6280
6308
  const indexee_1 = __webpack_require__(7610);
6309
+ const htmlentity_1 = __webpack_require__(470);
6281
6310
  const source_1 = __webpack_require__(8745);
6282
6311
  const visibility_1 = __webpack_require__(6364);
6283
6312
  const array_1 = __webpack_require__(6876);
@@ -6289,8 +6318,14 @@ exports.index = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(32 /*
6289
6318
  class: 'index',
6290
6319
  href: el.id ? `#${el.id}` : undefined
6291
6320
  })])));
6292
- exports.signature = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('|', (0, combinator_1.surround)((0, source_1.str)(/^\|(?!\\?\s)/), (0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ']'), /^(?=])/, false, ([as, bs], rest) => {
6293
- const index = (0, indexee_1.identity)('index', undefined, (0, indexee_1.text)((0, dom_1.frag)(bs)))?.slice(7);
6321
+ exports.signature = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('|', (0, combinator_1.surround)((0, source_1.str)(/^\|(?!\\?\s)/), (0, visibility_1.tightStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ']')), /^(?=])/, false, ([as, bs], rest, {
6322
+ recent = []
6323
+ }) => {
6324
+ const sig = (0, parser_1.eval)(parser({
6325
+ source: recent[1],
6326
+ context: {}
6327
+ }), []).join('');
6328
+ const index = sig.includes("\u0007" /* Command.Error */) ? undefined : (0, indexee_1.identity)('index', undefined, sig)?.slice(7);
6294
6329
  return index ? [[(0, dom_1.html)('span', {
6295
6330
  class: 'indexer',
6296
6331
  'data-index': index
@@ -6307,6 +6342,7 @@ function dataindex(ns) {
6307
6342
  }
6308
6343
  }
6309
6344
  exports.dataindex = dataindex;
6345
+ const parser = (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, source_1.text]));
6310
6346
 
6311
6347
  /***/ },
6312
6348
 
@@ -6321,7 +6357,6 @@ Object.defineProperty(exports, "__esModule", ({
6321
6357
  }));
6322
6358
  exports.text = exports.signature = exports.identity = exports.indexee = void 0;
6323
6359
  const combinator_1 = __webpack_require__(3484);
6324
- const memoize_1 = __webpack_require__(6925);
6325
6360
  const dom_1 = __webpack_require__(394);
6326
6361
  function indexee(parser) {
6327
6362
  return (0, combinator_1.fmap)(parser, ([el], _, {
@@ -6414,7 +6449,7 @@ function signature(source) {
6414
6449
  return target.textContent.trim();
6415
6450
  }
6416
6451
  exports.signature = signature;
6417
- exports.text = (0, memoize_1.reduce)(source => {
6452
+ function text(source) {
6418
6453
  const target = source.cloneNode(true);
6419
6454
  for (let es = target.querySelectorAll('code[data-src], .math[data-src], .remark, rt, rp, br, .annotation, .reference, .checkbox, ul, ol'), len = es.length, i = 0; i < len; ++i) {
6420
6455
  const el = es[i];
@@ -6443,7 +6478,8 @@ exports.text = (0, memoize_1.reduce)(source => {
6443
6478
  }
6444
6479
  }
6445
6480
  return target.textContent;
6446
- });
6481
+ }
6482
+ exports.text = text;
6447
6483
 
6448
6484
  /***/ },
6449
6485
 
@@ -6617,20 +6653,19 @@ exports.htmlentity = exports.unsafehtmlentity = void 0;
6617
6653
  const combinator_1 = __webpack_require__(3484);
6618
6654
  const util_1 = __webpack_require__(4992);
6619
6655
  const dom_1 = __webpack_require__(394);
6620
- const memoize_1 = __webpack_require__(6925);
6621
6656
  exports.unsafehtmlentity = (0, combinator_1.validate)('&', (0, combinator_1.focus)(/^&[0-9A-Za-z]{1,99};/, ({
6622
6657
  source
6623
- }) => [[parse(source) ?? `${"\u001B" /* Command.Escape */}${source}`], '']));
6624
- exports.htmlentity = (0, combinator_1.fmap)((0, combinator_1.union)([exports.unsafehtmlentity]), ([text]) => [text[0] === "\u001B" /* Command.Escape */ ? (0, dom_1.html)('span', {
6658
+ }) => [[parser(source) ?? `${"\u0007" /* Command.Error */}${source}`], '']));
6659
+ exports.htmlentity = (0, combinator_1.fmap)((0, combinator_1.union)([exports.unsafehtmlentity]), ([text]) => [text[0] === "\u0007" /* Command.Error */ ? (0, dom_1.html)('span', {
6625
6660
  class: 'invalid',
6626
6661
  ...(0, util_1.invalid)('htmlentity', 'syntax', 'Invalid HTML entity')
6627
6662
  }, text.slice(1)) : text]);
6628
- const parse = (0, memoize_1.reduce)((el => entity => {
6663
+ const parser = (el => entity => {
6629
6664
  if (entity === '&NewLine;') return ' ';
6630
6665
  el.innerHTML = entity;
6631
6666
  const text = el.textContent;
6632
6667
  return entity === text ? undefined : text;
6633
- })((0, dom_1.html)('span')));
6668
+ })((0, dom_1.html)('span'));
6634
6669
 
6635
6670
  /***/ },
6636
6671
 
@@ -6930,10 +6965,10 @@ function sanitize(target, uri, alt) {
6930
6965
  });
6931
6966
  return false;
6932
6967
  }
6933
- if (alt.includes("\u001B" /* Command.Escape */)) {
6968
+ if (alt.includes("\u0007" /* Command.Error */)) {
6934
6969
  (0, dom_1.define)(target, {
6935
6970
  class: 'invalid',
6936
- alt: target.getAttribute('alt')?.replace(context_1.CmdRegExp.Escape, ''),
6971
+ alt: target.getAttribute('alt')?.replace(context_1.CmdRegExp.Error, ''),
6937
6972
  ...(0, util_1.invalid)('media', 'argument', `Cannot use invalid HTML entitiy "${alt.match(/&[0-9A-Za-z]+;/)[0]}"`)
6938
6973
  });
6939
6974
  return false;
@@ -6960,7 +6995,7 @@ const visibility_1 = __webpack_require__(6364);
6960
6995
  const dom_1 = __webpack_require__(394);
6961
6996
  const array_1 = __webpack_require__(6876);
6962
6997
  const util_1 = __webpack_require__(4992);
6963
- exports.reference = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(64 /* State.reference */, false, (0, combinator_1.surround)('[[', (0, combinator_1.precedence)(1, (0, combinator_1.state)(128 /* State.annotation */ | 64 /* State.reference */ | 4 /* State.media */, (0, combinator_1.subsequence)([abbr, (0, visibility_1.trimBlankStart)((0, combinator_1.some)(inline_1.inline, ']', [['\n', 9], [']', 1]]))]))), ']]', false, ([, ns], rest) => (0, visibility_1.trimBlankNodeEnd)(ns).length > 0 ? [[(0, dom_1.html)('sup', attributes(ns), [(0, dom_1.html)('span', (0, dom_1.defrag)(ns))])], rest] : undefined, ([as, bs], rest, {
6998
+ exports.reference = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(64 /* State.reference */, false, (0, combinator_1.surround)((0, source_1.str)('[['), (0, combinator_1.precedence)(1, (0, combinator_1.state)(128 /* State.annotation */ | 64 /* State.reference */ | 4 /* State.media */, (0, combinator_1.subsequence)([abbr, (0, visibility_1.trimBlankStart)((0, combinator_1.some)(inline_1.inline, ']', [['\n', 9], [']', 1]]))]))), ']]', false, ([, ns], rest) => (0, visibility_1.trimBlankNodeEnd)(ns).length > 0 ? [[(0, dom_1.html)('sup', attributes(ns), [(0, dom_1.html)('span', (0, dom_1.defrag)(ns))])], rest] : undefined, ([as, bs], rest, {
6964
6999
  state = 0
6965
7000
  }) => state & 128 /* State.annotation */ ? [(0, array_1.unshift)(as, bs), rest] : undefined, [3 | 16 /* Backtrack.linedoublebracket */, 1 | 12 /* Backtrack.linebracket */], 8 /* Backtrack.bracket */ | 1 /* BacktrackState.nobreak */)));
6966
7001
  // Chicago-Style
@@ -7098,8 +7133,8 @@ function attributes(texts, rubies) {
7098
7133
  let attrs;
7099
7134
  for (const ss of [texts, rubies]) {
7100
7135
  for (let i = 0; i < ss.length; ++i) {
7101
- if (!ss[i].includes("\u001B" /* Command.Escape */)) continue;
7102
- ss[i] = ss[i].replace(context_1.CmdRegExp.Escape, '');
7136
+ if (!ss[i].includes("\u0007" /* Command.Error */)) continue;
7137
+ ss[i] = ss[i].replace(context_1.CmdRegExp.Error, '');
7103
7138
  attrs ??= {
7104
7139
  class: 'invalid',
7105
7140
  ...(0, util_1.invalid)('ruby', ss === texts ? 'content' : 'argument', 'Invalid HTML entity')
@@ -7629,14 +7664,18 @@ const escsource = ({
7629
7664
  case '\\':
7630
7665
  switch (source[1]) {
7631
7666
  case undefined:
7667
+ return [[source[0]], ''];
7632
7668
  case '\n':
7633
7669
  return [[source[0]], source.slice(1)];
7634
7670
  default:
7635
7671
  (0, combinator_1.consume)(1, context);
7636
7672
  return [[source.slice(0, 2)], source.slice(2)];
7637
7673
  }
7674
+ case '\n':
7675
+ context.linebreak ??= source.length;
7676
+ return [[source[0]], source.slice(1)];
7638
7677
  default:
7639
- const b = source[0] !== '\n' && source[0].trimStart() === '';
7678
+ const b = source[0].trimStart() === '';
7640
7679
  const i = b ? source.search(text_1.nonWhitespace) : 1;
7641
7680
  (0, combinator_1.consume)(i - 1, context);
7642
7681
  return [[source.slice(0, i - +b || 1)], source.slice(i - +b || 1)];
@@ -7692,10 +7731,10 @@ function str(pattern, not) {
7692
7731
  }) => {
7693
7732
  if (source === '') return;
7694
7733
  const m = source.match(pattern);
7695
- count && m && (0, combinator_1.consume)(m[0].length, context);
7696
- if (m && not && source.slice(m[0].length, m[0].length + not.length) === not) return;
7697
- //assert(!m || m[0]);
7698
- return m ? [[m[0]], source.slice(m[0].length)] : undefined;
7734
+ if (m === null) return;
7735
+ count && (0, combinator_1.consume)(m[0].length, context);
7736
+ if (not && source.slice(m[0].length, m[0].length + not.length) === not) return;
7737
+ return [[m[0]], source.slice(m[0].length)];
7699
7738
  };
7700
7739
  }
7701
7740
  exports.str = str;
@@ -7739,6 +7778,7 @@ const text = ({
7739
7778
  case '\\':
7740
7779
  switch (source[1]) {
7741
7780
  case undefined:
7781
+ return [[], ''];
7742
7782
  case '\n':
7743
7783
  return [[], source.slice(1)];
7744
7784
  default:
@@ -7746,6 +7786,7 @@ const text = ({
7746
7786
  return [[source.slice(1, 2)], source.slice(2)];
7747
7787
  }
7748
7788
  case '\n':
7789
+ context.linebreak ??= source.length;
7749
7790
  return [[(0, dom_1.html)('br')], source.slice(1)];
7750
7791
  case '*':
7751
7792
  case '`':
@@ -7807,11 +7848,15 @@ const unescsource = ({
7807
7848
  case "\u001B" /* Command.Escape */:
7808
7849
  (0, combinator_1.consume)(1, context);
7809
7850
  return [[source.slice(1, 2)], source.slice(2)];
7851
+ case '\n':
7852
+ context.linebreak ??= source.length;
7853
+ return [[source[0]], source.slice(1)];
7854
+ default:
7855
+ const b = source[0].trimStart() === '';
7856
+ const i = b || (0, text_1.isAlphanumeric)(source[0]) ? source.search(b ? text_1.nonWhitespace : text_1.nonAlphanumeric) || 1 : 1;
7857
+ (0, combinator_1.consume)(i - 1, context);
7858
+ return [[source.slice(0, i - +b || 1)], source.slice(i - +b || 1)];
7810
7859
  }
7811
- const b = source[0] !== '\n' && source[0].trimStart() === '';
7812
- const i = b || (0, text_1.isAlphanumeric)(source[0]) ? source.search(b ? text_1.nonWhitespace : text_1.nonAlphanumeric) || 1 : 1;
7813
- (0, combinator_1.consume)(i - 1, context);
7814
- return [[source.slice(0, i - +b || 1)], source.slice(i - +b || 1)];
7815
7860
  }
7816
7861
  default:
7817
7862
  (0, combinator_1.consume)(i, context);
@@ -7963,7 +8008,6 @@ const combinator_1 = __webpack_require__(3484);
7963
8008
  const htmlentity_1 = __webpack_require__(470);
7964
8009
  const source_1 = __webpack_require__(8745);
7965
8010
  const normalize_1 = __webpack_require__(4490);
7966
- const memoize_1 = __webpack_require__(6925);
7967
8011
  const array_1 = __webpack_require__(6876);
7968
8012
  var blank;
7969
8013
  (function (blank) {
@@ -7998,7 +8042,7 @@ function tightStart(parser, except) {
7998
8042
  return input => isTightStart(input, except) ? parser(input) : undefined;
7999
8043
  }
8000
8044
  exports.tightStart = tightStart;
8001
- const isTightStart = (0, memoize_1.reduce)((input, except) => {
8045
+ function isTightStart(input, except) {
8002
8046
  const {
8003
8047
  source
8004
8048
  } = input;
@@ -8027,9 +8071,7 @@ const isTightStart = (0, memoize_1.reduce)((input, except) => {
8027
8071
  default:
8028
8072
  return source[0].trimStart() !== '';
8029
8073
  }
8030
- }, ({
8031
- source
8032
- }, except = '') => `${source}${"\u001F" /* Command.Separator */}${except}`);
8074
+ }
8033
8075
  function isLooseNodeStart(nodes) {
8034
8076
  if (nodes.length === 0) return true;
8035
8077
  for (let i = 0; i < nodes.length; ++i) {
package/markdown.d.ts CHANGED
@@ -1112,12 +1112,6 @@ export namespace MarkdownParser {
1112
1112
  // ""
1113
1113
  Inline<'bracket'>,
1114
1114
  Parser<HTMLElement | string, Context, [
1115
- SourceParser.StrParser,
1116
- InlineParser,
1117
- SourceParser.StrParser,
1118
- InlineParser,
1119
- InlineParser,
1120
- InlineParser,
1121
1115
  InlineParser,
1122
1116
  InlineParser,
1123
1117
  InlineParser,
@@ -1251,7 +1245,7 @@ export namespace MarkdownParser {
1251
1245
  export interface TextParser extends
1252
1246
  // abc
1253
1247
  Source<'text'>,
1254
- Parser<string | HTMLBRElement | HTMLSpanElement, Context, []> {
1248
+ Parser<string | HTMLBRElement, Context, []> {
1255
1249
  }
1256
1250
  export interface TxtParser extends
1257
1251
  // abc
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.288.1",
3
+ "version": "0.289.0",
4
4
  "description": "Secure markdown renderer working on browsers for user input data.",
5
5
  "private": false,
6
6
  "homepage": "https://github.com/falsandtru/securemark",
@@ -55,9 +55,11 @@ export function surround<T>(
55
55
  return ({ source, context }) => {
56
56
  const lmr_ = source;
57
57
  if (lmr_ === '') return;
58
+ const { linebreak } = context;
59
+ context.linebreak = undefined;
58
60
  const res1 = opener({ source: lmr_, context });
59
61
  assert(check(lmr_, res1, false));
60
- if (res1 === undefined) return;
62
+ if (res1 === undefined) return void revert(context, linebreak);
61
63
  const rl = eval(res1);
62
64
  const mr_ = exec(res1);
63
65
  for (const backtrack of backtracks) {
@@ -69,7 +71,7 @@ export function surround<T>(
69
71
  if (!(pos in backtracks)) continue;
70
72
  // bracket only
71
73
  const shift = backtrack >>> 2 === state >>> 2 ? state & 3 : 0;
72
- if (backtracks[pos] & 1 << (backtrack >>> 2) + shift) return;
74
+ if (backtracks[pos] & 1 << (backtrack >>> 2) + shift) return void revert(context, linebreak);
73
75
  }
74
76
  }
75
77
  }
@@ -80,12 +82,12 @@ export function surround<T>(
80
82
  context.backtrack = state;
81
83
  const rm = eval(res2);
82
84
  const r_ = exec(res2, mr_);
83
- if (!rm && !optional) return;
85
+ if (!rm && !optional) return void revert(context, linebreak);
84
86
  const res3 = closer({ source: r_, context });
85
87
  assert(check(r_, res3, false));
86
88
  const rr = eval(res3);
87
89
  const rest = exec(res3, r_);
88
- if (rest.length === lmr_.length) return;
90
+ if (rest.length === lmr_.length) return void revert(context, linebreak);
89
91
  for (const backtrack of backtracks) {
90
92
  if (backtrack & 2 && rr === undefined) {
91
93
  const { backtracks = {}, backtrack: state = 0, offset = 0 } = context;
@@ -94,13 +96,25 @@ export function surround<T>(
94
96
  backtracks[source.length + offset - 1] |= 1 << (backtrack >>> 2) + shift;
95
97
  }
96
98
  }
97
- return rr
99
+ context.recent = [
100
+ lmr_.slice(0, lmr_.length - mr_.length),
101
+ mr_.slice(0, mr_.length - r_.length),
102
+ r_.slice(0, r_.length - rest.length),
103
+ ];
104
+ const result = rr
98
105
  ? f
99
106
  ? f([rl, rm!, rr], rest, context)
100
- : [push(unshift(rl, rm ?? []), rr), rest]
107
+ : [push(unshift(rl, rm ?? []), rr), rest] satisfies [T[], string]
101
108
  : g
102
109
  ? g([rl, rm!, mr_], rest, context)
103
110
  : undefined;
111
+ if (result) {
112
+ context.linebreak ??= linebreak;
113
+ }
114
+ else {
115
+ revert(context, linebreak);
116
+ }
117
+ return result;
104
118
  };
105
119
  }
106
120
 
@@ -118,6 +132,10 @@ function match(pattern: string | RegExp): (input: Input) => [never[], string] |
118
132
  }
119
133
  }
120
134
 
135
+ function revert(context: Ctx, linebreak: number | undefined): void {
136
+ context.linebreak = linebreak;
137
+ }
138
+
121
139
  export function open<P extends Parser<unknown>>(opener: string | RegExp | Parser<Tree<P>, Context<P>>, parser: P, optional?: boolean): P;
122
140
  export function open<T>(opener: string | RegExp | Parser<T>, parser: Parser<T>, optional = false): Parser<T> {
123
141
  return surround(opener, parser, '', optional);