@uiw/react-md-editor 3.20.9 → 3.21.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.
package/dist/mdeditor.js CHANGED
@@ -17364,121 +17364,123 @@ __webpack_require__.r(__webpack_exports__);
17364
17364
 
17365
17365
  // EXPORTS
17366
17366
  __webpack_require__.d(__webpack_exports__, {
17367
- "EditorContext": () => (/* reexport */ EditorContext),
17368
- "MarkdownUtil": () => (/* reexport */ markdownUtils_namespaceObject),
17369
- "TextAreaCommandOrchestrator": () => (/* reexport */ TextAreaCommandOrchestrator),
17370
- "TextAreaTextApi": () => (/* reexport */ TextAreaTextApi),
17371
- "bold": () => (/* reexport */ bold),
17372
- "checkedListCommand": () => (/* reexport */ checkedListCommand),
17373
- "code": () => (/* reexport */ code_code),
17374
- "codeBlock": () => (/* reexport */ codeBlock),
17375
- "codeEdit": () => (/* reexport */ codeEdit),
17376
- "codeLive": () => (/* reexport */ codeLive),
17377
- "codePreview": () => (/* reexport */ codePreview),
17378
- "commands": () => (/* reexport */ commands_namespaceObject),
17379
- "comment": () => (/* reexport */ commands_comment_comment),
17367
+ EditorContext: () => (/* reexport */ EditorContext),
17368
+ MarkdownUtil: () => (/* reexport */ markdownUtils_namespaceObject),
17369
+ TextAreaCommandOrchestrator: () => (/* reexport */ TextAreaCommandOrchestrator),
17370
+ TextAreaTextApi: () => (/* reexport */ TextAreaTextApi),
17371
+ bold: () => (/* reexport */ bold),
17372
+ checkedListCommand: () => (/* reexport */ checkedListCommand),
17373
+ code: () => (/* reexport */ code_code),
17374
+ codeBlock: () => (/* reexport */ codeBlock),
17375
+ codeEdit: () => (/* reexport */ codeEdit),
17376
+ codeLive: () => (/* reexport */ codeLive),
17377
+ codePreview: () => (/* reexport */ codePreview),
17378
+ commands: () => (/* reexport */ commands_namespaceObject),
17379
+ comment: () => (/* reexport */ commands_comment_comment),
17380
17380
  "default": () => (/* binding */ src_0),
17381
- "divider": () => (/* reexport */ divider),
17382
- "fullscreen": () => (/* reexport */ fullscreen),
17383
- "getBreaksNeededForEmptyLineAfter": () => (/* reexport */ getBreaksNeededForEmptyLineAfter),
17384
- "getBreaksNeededForEmptyLineBefore": () => (/* reexport */ getBreaksNeededForEmptyLineBefore),
17385
- "getCommands": () => (/* reexport */ commands_getCommands),
17386
- "getExtraCommands": () => (/* reexport */ getExtraCommands),
17387
- "getStateFromTextArea": () => (/* reexport */ getStateFromTextArea),
17388
- "getSurroundingWord": () => (/* reexport */ getSurroundingWord),
17389
- "group": () => (/* reexport */ group),
17390
- "hr": () => (/* reexport */ hr),
17391
- "image": () => (/* reexport */ commands_image_image),
17392
- "italic": () => (/* reexport */ italic),
17393
- "link": () => (/* reexport */ commands_link_link),
17394
- "orderedListCommand": () => (/* reexport */ orderedListCommand),
17395
- "quote": () => (/* reexport */ quote),
17396
- "reducer": () => (/* reexport */ reducer),
17397
- "selectWord": () => (/* reexport */ selectWord),
17398
- "strikethrough": () => (/* reexport */ strikeThrough_strikethrough),
17399
- "title": () => (/* reexport */ title),
17400
- "title1": () => (/* reexport */ title1),
17401
- "title2": () => (/* reexport */ title2),
17402
- "title3": () => (/* reexport */ title3),
17403
- "title4": () => (/* reexport */ title4),
17404
- "title5": () => (/* reexport */ title5),
17405
- "title6": () => (/* reexport */ title6),
17406
- "unorderedListCommand": () => (/* reexport */ unorderedListCommand)
17381
+ divider: () => (/* reexport */ divider),
17382
+ fullscreen: () => (/* reexport */ fullscreen),
17383
+ getBreaksNeededForEmptyLineAfter: () => (/* reexport */ getBreaksNeededForEmptyLineAfter),
17384
+ getBreaksNeededForEmptyLineBefore: () => (/* reexport */ getBreaksNeededForEmptyLineBefore),
17385
+ getCommands: () => (/* reexport */ commands_getCommands),
17386
+ getExtraCommands: () => (/* reexport */ getExtraCommands),
17387
+ getStateFromTextArea: () => (/* reexport */ getStateFromTextArea),
17388
+ getSurroundingWord: () => (/* reexport */ getSurroundingWord),
17389
+ group: () => (/* reexport */ group),
17390
+ hr: () => (/* reexport */ hr),
17391
+ image: () => (/* reexport */ commands_image_image),
17392
+ insertAtLineStart: () => (/* reexport */ insertAtLineStart),
17393
+ insertTextAtPosition: () => (/* reexport */ insertTextAtPosition),
17394
+ italic: () => (/* reexport */ italic),
17395
+ link: () => (/* reexport */ commands_link_link),
17396
+ orderedListCommand: () => (/* reexport */ orderedListCommand),
17397
+ quote: () => (/* reexport */ quote),
17398
+ reducer: () => (/* reexport */ reducer),
17399
+ selectWord: () => (/* reexport */ selectWord),
17400
+ strikethrough: () => (/* reexport */ strikeThrough_strikethrough),
17401
+ title: () => (/* reexport */ title),
17402
+ title1: () => (/* reexport */ title1),
17403
+ title2: () => (/* reexport */ title2),
17404
+ title3: () => (/* reexport */ title3),
17405
+ title4: () => (/* reexport */ title4),
17406
+ title5: () => (/* reexport */ title5),
17407
+ title6: () => (/* reexport */ title6),
17408
+ unorderedListCommand: () => (/* reexport */ unorderedListCommand)
17407
17409
  });
17408
17410
 
17409
17411
  // NAMESPACE OBJECT: ../node_modules/react-markdown/node_modules/micromark/lib/constructs.js
17410
17412
  var constructs_namespaceObject = {};
17411
17413
  __webpack_require__.r(constructs_namespaceObject);
17412
17414
  __webpack_require__.d(constructs_namespaceObject, {
17413
- "attentionMarkers": () => (attentionMarkers),
17414
- "contentInitial": () => (contentInitial),
17415
- "disable": () => (disable),
17416
- "document": () => (constructs_document),
17417
- "flow": () => (constructs_flow),
17418
- "flowInitial": () => (flowInitial),
17419
- "insideSpan": () => (insideSpan),
17420
- "string": () => (constructs_string),
17421
- "text": () => (constructs_text)
17415
+ attentionMarkers: () => (attentionMarkers),
17416
+ contentInitial: () => (contentInitial),
17417
+ disable: () => (disable),
17418
+ document: () => (constructs_document),
17419
+ flow: () => (constructs_flow),
17420
+ flowInitial: () => (flowInitial),
17421
+ insideSpan: () => (insideSpan),
17422
+ string: () => (constructs_string),
17423
+ text: () => (constructs_text)
17422
17424
  });
17423
17425
 
17424
17426
  // NAMESPACE OBJECT: ../node_modules/property-information/lib/util/types.js
17425
17427
  var types_namespaceObject = {};
17426
17428
  __webpack_require__.r(types_namespaceObject);
17427
17429
  __webpack_require__.d(types_namespaceObject, {
17428
- "boolean": () => (types_boolean),
17429
- "booleanish": () => (booleanish),
17430
- "commaOrSpaceSeparated": () => (commaOrSpaceSeparated),
17431
- "commaSeparated": () => (commaSeparated),
17432
- "number": () => (number),
17433
- "overloadedBoolean": () => (overloadedBoolean),
17434
- "spaceSeparated": () => (spaceSeparated)
17430
+ boolean: () => (types_boolean),
17431
+ booleanish: () => (booleanish),
17432
+ commaOrSpaceSeparated: () => (commaOrSpaceSeparated),
17433
+ commaSeparated: () => (commaSeparated),
17434
+ number: () => (number),
17435
+ overloadedBoolean: () => (overloadedBoolean),
17436
+ spaceSeparated: () => (spaceSeparated)
17435
17437
  });
17436
17438
 
17437
17439
  // NAMESPACE OBJECT: ./src/utils/markdownUtils.ts
17438
17440
  var markdownUtils_namespaceObject = {};
17439
17441
  __webpack_require__.r(markdownUtils_namespaceObject);
17440
17442
  __webpack_require__.d(markdownUtils_namespaceObject, {
17441
- "getBreaksNeededForEmptyLineAfter": () => (getBreaksNeededForEmptyLineAfter),
17442
- "getBreaksNeededForEmptyLineBefore": () => (getBreaksNeededForEmptyLineBefore),
17443
- "getSurroundingWord": () => (getSurroundingWord),
17444
- "selectWord": () => (selectWord)
17443
+ getBreaksNeededForEmptyLineAfter: () => (getBreaksNeededForEmptyLineAfter),
17444
+ getBreaksNeededForEmptyLineBefore: () => (getBreaksNeededForEmptyLineBefore),
17445
+ getSurroundingWord: () => (getSurroundingWord),
17446
+ selectWord: () => (selectWord)
17445
17447
  });
17446
17448
 
17447
17449
  // NAMESPACE OBJECT: ./src/commands/index.ts
17448
17450
  var commands_namespaceObject = {};
17449
17451
  __webpack_require__.r(commands_namespaceObject);
17450
17452
  __webpack_require__.d(commands_namespaceObject, {
17451
- "TextAreaCommandOrchestrator": () => (TextAreaCommandOrchestrator),
17452
- "TextAreaTextApi": () => (TextAreaTextApi),
17453
- "bold": () => (bold),
17454
- "checkedListCommand": () => (checkedListCommand),
17455
- "code": () => (code_code),
17456
- "codeBlock": () => (codeBlock),
17457
- "codeEdit": () => (codeEdit),
17458
- "codeLive": () => (codeLive),
17459
- "codePreview": () => (codePreview),
17460
- "comment": () => (commands_comment_comment),
17461
- "divider": () => (divider),
17462
- "fullscreen": () => (fullscreen),
17463
- "getCommands": () => (commands_getCommands),
17464
- "getExtraCommands": () => (getExtraCommands),
17465
- "getStateFromTextArea": () => (getStateFromTextArea),
17466
- "group": () => (group),
17467
- "hr": () => (hr),
17468
- "image": () => (commands_image_image),
17469
- "italic": () => (italic),
17470
- "link": () => (commands_link_link),
17471
- "orderedListCommand": () => (orderedListCommand),
17472
- "quote": () => (quote),
17473
- "strikethrough": () => (strikeThrough_strikethrough),
17474
- "title": () => (title),
17475
- "title1": () => (title1),
17476
- "title2": () => (title2),
17477
- "title3": () => (title3),
17478
- "title4": () => (title4),
17479
- "title5": () => (title5),
17480
- "title6": () => (title6),
17481
- "unorderedListCommand": () => (unorderedListCommand)
17453
+ TextAreaCommandOrchestrator: () => (TextAreaCommandOrchestrator),
17454
+ TextAreaTextApi: () => (TextAreaTextApi),
17455
+ bold: () => (bold),
17456
+ checkedListCommand: () => (checkedListCommand),
17457
+ code: () => (code_code),
17458
+ codeBlock: () => (codeBlock),
17459
+ codeEdit: () => (codeEdit),
17460
+ codeLive: () => (codeLive),
17461
+ codePreview: () => (codePreview),
17462
+ comment: () => (commands_comment_comment),
17463
+ divider: () => (divider),
17464
+ fullscreen: () => (fullscreen),
17465
+ getCommands: () => (commands_getCommands),
17466
+ getExtraCommands: () => (getExtraCommands),
17467
+ getStateFromTextArea: () => (getStateFromTextArea),
17468
+ group: () => (group),
17469
+ hr: () => (hr),
17470
+ image: () => (commands_image_image),
17471
+ italic: () => (italic),
17472
+ link: () => (commands_link_link),
17473
+ orderedListCommand: () => (orderedListCommand),
17474
+ quote: () => (quote),
17475
+ strikethrough: () => (strikeThrough_strikethrough),
17476
+ title: () => (title),
17477
+ title1: () => (title1),
17478
+ title2: () => (title2),
17479
+ title3: () => (title3),
17480
+ title4: () => (title4),
17481
+ title5: () => (title5),
17482
+ title6: () => (title6),
17483
+ unorderedListCommand: () => (unorderedListCommand)
17482
17484
  });
17483
17485
 
17484
17486
  ;// CONCATENATED MODULE: ../node_modules/@babel/runtime/helpers/esm/typeof.js
@@ -28019,7 +28021,10 @@ function defaultOnError(left, right) {
28019
28021
 
28020
28022
 
28021
28023
 
28022
- /** @type {import('unified').Plugin<[Options?] | void[], string, Root>} */
28024
+ /**
28025
+ * @this {import('unified').Processor}
28026
+ * @type {import('unified').Plugin<[Options?] | void[], string, Root>}
28027
+ */
28023
28028
  function remarkParse(options) {
28024
28029
  /** @type {import('unified').ParserFunction<Root>} */
28025
28030
  const parser = (doc) => {
@@ -28041,11 +28046,6 @@ function remarkParse(options) {
28041
28046
  Object.assign(this, {Parser: parser})
28042
28047
  }
28043
28048
 
28044
- ;// CONCATENATED MODULE: ../node_modules/react-markdown/node_modules/remark-parse/index.js
28045
-
28046
-
28047
- /* harmony default export */ const remark_parse = (remarkParse);
28048
-
28049
28049
  ;// CONCATENATED MODULE: ../node_modules/micromark-util-sanitize-uri/index.js
28050
28050
 
28051
28051
 
@@ -33333,7 +33333,7 @@ function ReactMarkdown(options) {
33333
33333
  }
33334
33334
 
33335
33335
  const processor = unified()
33336
- .use(remark_parse)
33336
+ .use(remarkParse)
33337
33337
  .use(options.remarkPlugins || [])
33338
33338
  .use(lib, {
33339
33339
  ...options.remarkRehypeOptions,
@@ -33434,17 +33434,19 @@ ReactMarkdown.propTypes = {
33434
33434
 
33435
33435
  ;// CONCATENATED MODULE: ../node_modules/micromark-extension-gfm-autolink-literal/lib/syntax.js
33436
33436
  /**
33437
- * @typedef {import('micromark-util-types').Extension} Extension
33437
+ * @typedef {import('micromark-util-types').Code} Code
33438
33438
  * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord
33439
- * @typedef {import('micromark-util-types').Tokenizer} Tokenizer
33439
+ * @typedef {import('micromark-util-types').Event} Event
33440
+ * @typedef {import('micromark-util-types').Extension} Extension
33440
33441
  * @typedef {import('micromark-util-types').Previous} Previous
33441
33442
  * @typedef {import('micromark-util-types').State} State
33442
- * @typedef {import('micromark-util-types').Event} Event
33443
- * @typedef {import('micromark-util-types').Code} Code
33443
+ * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext
33444
+ * @typedef {import('micromark-util-types').Tokenizer} Tokenizer
33444
33445
  */
33445
33446
 
33446
- const www = {
33447
- tokenize: tokenizeWww,
33447
+
33448
+ const wwwPrefix = {
33449
+ tokenize: tokenizeWwwPrefix,
33448
33450
  partial: true
33449
33451
  }
33450
33452
  const domain = {
@@ -33455,610 +33457,925 @@ const syntax_path = {
33455
33457
  tokenize: tokenizePath,
33456
33458
  partial: true
33457
33459
  }
33458
- const punctuation = {
33459
- tokenize: tokenizePunctuation,
33460
+ const trail = {
33461
+ tokenize: tokenizeTrail,
33460
33462
  partial: true
33461
33463
  }
33462
- const namedCharacterReference = {
33463
- tokenize: tokenizeNamedCharacterReference,
33464
+ const emailDomainDotTrail = {
33465
+ tokenize: tokenizeEmailDomainDotTrail,
33464
33466
  partial: true
33465
33467
  }
33466
33468
  const wwwAutolink = {
33467
33469
  tokenize: tokenizeWwwAutolink,
33468
33470
  previous: previousWww
33469
33471
  }
33470
- const httpAutolink = {
33471
- tokenize: tokenizeHttpAutolink,
33472
- previous: previousHttp
33472
+ const protocolAutolink = {
33473
+ tokenize: tokenizeProtocolAutolink,
33474
+ previous: previousProtocol
33473
33475
  }
33474
33476
  const emailAutolink = {
33475
33477
  tokenize: tokenizeEmailAutolink,
33476
33478
  previous: previousEmail
33477
33479
  }
33478
- /** @type {ConstructRecord} */
33479
33480
 
33481
+ /** @type {ConstructRecord} */
33480
33482
  const syntax_text = {}
33481
- /** @type {Extension} */
33482
33483
 
33484
+ // To do: next major: expose functions that yields extension.
33485
+
33486
+ /**
33487
+ * Extension for `micromark` that can be passed in `extensions` to enable GFM
33488
+ * autolink literal syntax.
33489
+ *
33490
+ * @type {Extension}
33491
+ */
33483
33492
  const gfmAutolinkLiteral = {
33484
33493
  text: syntax_text
33485
33494
  }
33486
- let syntax_code = 48 // Add alphanumerics.
33495
+ let syntax_code = 48
33487
33496
 
33497
+ // Add alphanumerics.
33488
33498
  while (syntax_code < 123) {
33489
33499
  syntax_text[syntax_code] = emailAutolink
33490
33500
  syntax_code++
33491
33501
  if (syntax_code === 58) syntax_code = 65
33492
33502
  else if (syntax_code === 91) syntax_code = 97
33493
33503
  }
33494
-
33495
33504
  syntax_text[43] = emailAutolink
33496
33505
  syntax_text[45] = emailAutolink
33497
33506
  syntax_text[46] = emailAutolink
33498
33507
  syntax_text[95] = emailAutolink
33499
- syntax_text[72] = [emailAutolink, httpAutolink]
33500
- syntax_text[104] = [emailAutolink, httpAutolink]
33508
+ syntax_text[72] = [emailAutolink, protocolAutolink]
33509
+ syntax_text[104] = [emailAutolink, protocolAutolink]
33501
33510
  syntax_text[87] = [emailAutolink, wwwAutolink]
33502
33511
  syntax_text[119] = [emailAutolink, wwwAutolink]
33503
- /** @type {Tokenizer} */
33504
33512
 
33513
+ // To do: perform email autolink literals on events, afterwards.
33514
+ // That’s where `markdown-rs` and `cmark-gfm` perform it.
33515
+ // It should look for `@`, then for atext backwards, and then for a label
33516
+ // forwards.
33517
+ // To do: `mailto:`, `xmpp:` protocol as prefix.
33518
+
33519
+ /**
33520
+ * Email autolink literal.
33521
+ *
33522
+ * ```markdown
33523
+ * > | a contact@example.org b
33524
+ * ^^^^^^^^^^^^^^^^^^^
33525
+ * ```
33526
+ *
33527
+ * @this {TokenizeContext}
33528
+ * @type {Tokenizer}
33529
+ */
33505
33530
  function tokenizeEmailAutolink(effects, ok, nok) {
33506
33531
  const self = this
33532
+ /** @type {boolean | undefined} */
33533
+ let dot
33507
33534
  /** @type {boolean} */
33508
-
33509
- let hasDot
33510
- /** @type {boolean|undefined} */
33511
-
33512
- let hasDigitInLastSegment
33535
+ let data
33513
33536
  return start
33514
- /** @type {State} */
33515
33537
 
33538
+ /**
33539
+ * Start of email autolink literal.
33540
+ *
33541
+ * ```markdown
33542
+ * > | a contact@example.org b
33543
+ * ^
33544
+ * ```
33545
+ *
33546
+ * @type {State}
33547
+ */
33516
33548
  function start(code) {
33517
33549
  if (
33518
33550
  !gfmAtext(code) ||
33519
- !previousEmail(self.previous) ||
33551
+ !previousEmail.call(self, self.previous) ||
33520
33552
  previousUnbalanced(self.events)
33521
33553
  ) {
33522
33554
  return nok(code)
33523
33555
  }
33524
-
33525
33556
  effects.enter('literalAutolink')
33526
33557
  effects.enter('literalAutolinkEmail')
33527
33558
  return atext(code)
33528
33559
  }
33529
- /** @type {State} */
33530
33560
 
33561
+ /**
33562
+ * In email atext.
33563
+ *
33564
+ * ```markdown
33565
+ * > | a contact@example.org b
33566
+ * ^
33567
+ * ```
33568
+ *
33569
+ * @type {State}
33570
+ */
33531
33571
  function atext(code) {
33532
33572
  if (gfmAtext(code)) {
33533
33573
  effects.consume(code)
33534
33574
  return atext
33535
33575
  }
33536
-
33537
33576
  if (code === 64) {
33538
33577
  effects.consume(code)
33539
- return label
33578
+ return emailDomain
33540
33579
  }
33541
-
33542
33580
  return nok(code)
33543
33581
  }
33544
- /** @type {State} */
33545
33582
 
33546
- function label(code) {
33583
+ /**
33584
+ * In email domain.
33585
+ *
33586
+ * The reference code is a bit overly complex as it handles the `@`, of which
33587
+ * there may be just one.
33588
+ * Source: <https://github.com/github/cmark-gfm/blob/ef1cfcb/extensions/autolink.c#L318>
33589
+ *
33590
+ * ```markdown
33591
+ * > | a contact@example.org b
33592
+ * ^
33593
+ * ```
33594
+ *
33595
+ * @type {State}
33596
+ */
33597
+ function emailDomain(code) {
33598
+ // Dot followed by alphanumerical (not `-` or `_`).
33547
33599
  if (code === 46) {
33548
- return effects.check(punctuation, done, dotContinuation)(code)
33549
- }
33550
-
33551
- if (code === 45 || code === 95) {
33552
- return effects.check(punctuation, nok, dashOrUnderscoreContinuation)(code)
33600
+ return effects.check(
33601
+ emailDomainDotTrail,
33602
+ emailDomainAfter,
33603
+ emailDomainDot
33604
+ )(code)
33553
33605
  }
33554
33606
 
33555
- if (asciiAlphanumeric(code)) {
33556
- if (!hasDigitInLastSegment && asciiDigit(code)) {
33557
- hasDigitInLastSegment = true
33558
- }
33559
-
33607
+ // Alphanumerical, `-`, and `_`.
33608
+ if (code === 45 || code === 95 || asciiAlphanumeric(code)) {
33609
+ data = true
33560
33610
  effects.consume(code)
33561
- return label
33611
+ return emailDomain
33562
33612
  }
33563
33613
 
33564
- return done(code)
33565
- }
33566
- /** @type {State} */
33614
+ // To do: `/` if xmpp.
33567
33615
 
33568
- function dotContinuation(code) {
33569
- effects.consume(code)
33570
- hasDot = true
33571
- hasDigitInLastSegment = undefined
33572
- return label
33616
+ // Note: normally we’d truncate trailing punctuation from the link.
33617
+ // However, email autolink literals cannot contain any of those markers,
33618
+ // except for `.`, but that can only occur if it isn’t trailing.
33619
+ // So we can ignore truncating!
33620
+ return emailDomainAfter(code)
33573
33621
  }
33574
- /** @type {State} */
33575
33622
 
33576
- function dashOrUnderscoreContinuation(code) {
33623
+ /**
33624
+ * In email domain, on dot that is not a trail.
33625
+ *
33626
+ * ```markdown
33627
+ * > | a contact@example.org b
33628
+ * ^
33629
+ * ```
33630
+ *
33631
+ * @type {State}
33632
+ */
33633
+ function emailDomainDot(code) {
33577
33634
  effects.consume(code)
33578
- return afterDashOrUnderscore
33635
+ dot = true
33636
+ return emailDomain
33579
33637
  }
33580
- /** @type {State} */
33581
-
33582
- function afterDashOrUnderscore(code) {
33583
- if (code === 46) {
33584
- return effects.check(punctuation, nok, dotContinuation)(code)
33585
- }
33586
-
33587
- return label(code)
33588
- }
33589
- /** @type {State} */
33590
33638
 
33591
- function done(code) {
33592
- if (hasDot && !hasDigitInLastSegment) {
33639
+ /**
33640
+ * After email domain.
33641
+ *
33642
+ * ```markdown
33643
+ * > | a contact@example.org b
33644
+ * ^
33645
+ * ```
33646
+ *
33647
+ * @type {State}
33648
+ */
33649
+ function emailDomainAfter(code) {
33650
+ // Domain must not be empty, must include a dot, and must end in alphabetical.
33651
+ // Source: <https://github.com/github/cmark-gfm/blob/ef1cfcb/extensions/autolink.c#L332>.
33652
+ if (data && dot && asciiAlpha(self.previous)) {
33593
33653
  effects.exit('literalAutolinkEmail')
33594
33654
  effects.exit('literalAutolink')
33595
33655
  return ok(code)
33596
33656
  }
33597
-
33598
33657
  return nok(code)
33599
33658
  }
33600
33659
  }
33601
- /** @type {Tokenizer} */
33602
33660
 
33661
+ /**
33662
+ * `www` autolink literal.
33663
+ *
33664
+ * ```markdown
33665
+ * > | a www.example.org b
33666
+ * ^^^^^^^^^^^^^^^
33667
+ * ```
33668
+ *
33669
+ * @this {TokenizeContext}
33670
+ * @type {Tokenizer}
33671
+ */
33603
33672
  function tokenizeWwwAutolink(effects, ok, nok) {
33604
33673
  const self = this
33605
- return start
33606
- /** @type {State} */
33674
+ return wwwStart
33607
33675
 
33608
- function start(code) {
33676
+ /**
33677
+ * Start of www autolink literal.
33678
+ *
33679
+ * ```markdown
33680
+ * > | www.example.com/a?b#c
33681
+ * ^
33682
+ * ```
33683
+ *
33684
+ * @type {State}
33685
+ */
33686
+ function wwwStart(code) {
33609
33687
  if (
33610
33688
  (code !== 87 && code !== 119) ||
33611
- !previousWww(self.previous) ||
33689
+ !previousWww.call(self, self.previous) ||
33612
33690
  previousUnbalanced(self.events)
33613
33691
  ) {
33614
33692
  return nok(code)
33615
33693
  }
33616
-
33617
33694
  effects.enter('literalAutolink')
33618
- effects.enter('literalAutolinkWww') // For `www.` we check instead of attempt, because when it matches, GH
33619
- // treats it as part of a domain (yes, it says a valid domain must come
33620
- // after `www.`, but that’s not how it’s implemented by them).
33621
-
33695
+ effects.enter('literalAutolinkWww')
33696
+ // Note: we *check*, so we can discard the `www.` we parsed.
33697
+ // If it worked, we consider it as a part of the domain.
33622
33698
  return effects.check(
33623
- www,
33624
- effects.attempt(domain, effects.attempt(syntax_path, done), nok),
33699
+ wwwPrefix,
33700
+ effects.attempt(domain, effects.attempt(syntax_path, wwwAfter), nok),
33625
33701
  nok
33626
33702
  )(code)
33627
33703
  }
33628
- /** @type {State} */
33629
33704
 
33630
- function done(code) {
33705
+ /**
33706
+ * After a www autolink literal.
33707
+ *
33708
+ * ```markdown
33709
+ * > | www.example.com/a?b#c
33710
+ * ^
33711
+ * ```
33712
+ *
33713
+ * @type {State}
33714
+ */
33715
+ function wwwAfter(code) {
33631
33716
  effects.exit('literalAutolinkWww')
33632
33717
  effects.exit('literalAutolink')
33633
33718
  return ok(code)
33634
33719
  }
33635
33720
  }
33636
- /** @type {Tokenizer} */
33637
33721
 
33638
- function tokenizeHttpAutolink(effects, ok, nok) {
33722
+ /**
33723
+ * Protocol autolink literal.
33724
+ *
33725
+ * ```markdown
33726
+ * > | a https://example.org b
33727
+ * ^^^^^^^^^^^^^^^^^^^
33728
+ * ```
33729
+ *
33730
+ * @this {TokenizeContext}
33731
+ * @type {Tokenizer}
33732
+ */
33733
+ function tokenizeProtocolAutolink(effects, ok, nok) {
33639
33734
  const self = this
33640
- return start
33641
- /** @type {State} */
33735
+ let buffer = ''
33736
+ let seen = false
33737
+ return protocolStart
33642
33738
 
33643
- function start(code) {
33739
+ /**
33740
+ * Start of protocol autolink literal.
33741
+ *
33742
+ * ```markdown
33743
+ * > | https://example.com/a?b#c
33744
+ * ^
33745
+ * ```
33746
+ *
33747
+ * @type {State}
33748
+ */
33749
+ function protocolStart(code) {
33644
33750
  if (
33645
- (code !== 72 && code !== 104) ||
33646
- !previousHttp(self.previous) ||
33647
- previousUnbalanced(self.events)
33751
+ (code === 72 || code === 104) &&
33752
+ previousProtocol.call(self, self.previous) &&
33753
+ !previousUnbalanced(self.events)
33648
33754
  ) {
33649
- return nok(code)
33650
- }
33651
-
33652
- effects.enter('literalAutolink')
33653
- effects.enter('literalAutolinkHttp')
33654
- effects.consume(code)
33655
- return t1
33656
- }
33657
- /** @type {State} */
33658
-
33659
- function t1(code) {
33660
- if (code === 84 || code === 116) {
33661
- effects.consume(code)
33662
- return t2
33663
- }
33664
-
33665
- return nok(code)
33666
- }
33667
- /** @type {State} */
33668
-
33669
- function t2(code) {
33670
- if (code === 84 || code === 116) {
33671
- effects.consume(code)
33672
- return p
33673
- }
33674
-
33675
- return nok(code)
33676
- }
33677
- /** @type {State} */
33678
-
33679
- function p(code) {
33680
- if (code === 80 || code === 112) {
33755
+ effects.enter('literalAutolink')
33756
+ effects.enter('literalAutolinkHttp')
33757
+ buffer += String.fromCodePoint(code)
33681
33758
  effects.consume(code)
33682
- return s
33759
+ return protocolPrefixInside
33683
33760
  }
33684
-
33685
33761
  return nok(code)
33686
33762
  }
33687
- /** @type {State} */
33688
33763
 
33689
- function s(code) {
33690
- if (code === 83 || code === 115) {
33764
+ /**
33765
+ * In protocol.
33766
+ *
33767
+ * ```markdown
33768
+ * > | https://example.com/a?b#c
33769
+ * ^^^^^
33770
+ * ```
33771
+ *
33772
+ * @type {State}
33773
+ */
33774
+ function protocolPrefixInside(code) {
33775
+ // `5` is size of `https`
33776
+ if (asciiAlpha(code) && buffer.length < 5) {
33777
+ buffer += String.fromCodePoint(code)
33691
33778
  effects.consume(code)
33692
- return colon
33779
+ return protocolPrefixInside
33693
33780
  }
33694
-
33695
- return colon(code)
33696
- }
33697
- /** @type {State} */
33698
-
33699
- function colon(code) {
33700
33781
  if (code === 58) {
33701
- effects.consume(code)
33702
- return slash1
33703
- }
33704
-
33705
- return nok(code)
33706
- }
33707
- /** @type {State} */
33708
-
33709
- function slash1(code) {
33710
- if (code === 47) {
33711
- effects.consume(code)
33712
- return slash2
33782
+ const protocol = buffer.toLowerCase()
33783
+ if (protocol === 'http' || protocol === 'https') {
33784
+ effects.consume(code)
33785
+ return protocolSlashesInside
33786
+ }
33713
33787
  }
33714
-
33715
33788
  return nok(code)
33716
33789
  }
33717
- /** @type {State} */
33718
33790
 
33719
- function slash2(code) {
33791
+ /**
33792
+ * In slashes.
33793
+ *
33794
+ * ```markdown
33795
+ * > | https://example.com/a?b#c
33796
+ * ^^
33797
+ * ```
33798
+ *
33799
+ * @type {State}
33800
+ */
33801
+ function protocolSlashesInside(code) {
33720
33802
  if (code === 47) {
33721
33803
  effects.consume(code)
33722
- return after
33804
+ if (seen) {
33805
+ return afterProtocol
33806
+ }
33807
+ seen = true
33808
+ return protocolSlashesInside
33723
33809
  }
33724
-
33725
33810
  return nok(code)
33726
33811
  }
33727
- /** @type {State} */
33728
33812
 
33729
- function after(code) {
33813
+ /**
33814
+ * After protocol, before domain.
33815
+ *
33816
+ * ```markdown
33817
+ * > | https://example.com/a?b#c
33818
+ * ^
33819
+ * ```
33820
+ *
33821
+ * @type {State}
33822
+ */
33823
+ function afterProtocol(code) {
33824
+ // To do: this is different from `markdown-rs`:
33825
+ // https://github.com/wooorm/markdown-rs/blob/b3a921c761309ae00a51fe348d8a43adbc54b518/src/construct/gfm_autolink_literal.rs#L172-L182
33730
33826
  return code === null ||
33731
33827
  asciiControl(code) ||
33828
+ markdownLineEndingOrSpace(code) ||
33732
33829
  unicodeWhitespace(code) ||
33733
33830
  unicodePunctuation(code)
33734
33831
  ? nok(code)
33735
- : effects.attempt(domain, effects.attempt(syntax_path, done), nok)(code)
33832
+ : effects.attempt(domain, effects.attempt(syntax_path, protocolAfter), nok)(code)
33736
33833
  }
33737
- /** @type {State} */
33738
33834
 
33739
- function done(code) {
33835
+ /**
33836
+ * After a protocol autolink literal.
33837
+ *
33838
+ * ```markdown
33839
+ * > | https://example.com/a?b#c
33840
+ * ^
33841
+ * ```
33842
+ *
33843
+ * @type {State}
33844
+ */
33845
+ function protocolAfter(code) {
33740
33846
  effects.exit('literalAutolinkHttp')
33741
33847
  effects.exit('literalAutolink')
33742
33848
  return ok(code)
33743
33849
  }
33744
33850
  }
33745
- /** @type {Tokenizer} */
33746
-
33747
- function tokenizeWww(effects, ok, nok) {
33748
- return start
33749
- /** @type {State} */
33750
-
33751
- function start(code) {
33752
- effects.consume(code)
33753
- return w2
33754
- }
33755
- /** @type {State} */
33756
-
33757
- function w2(code) {
33758
- if (code === 87 || code === 119) {
33759
- effects.consume(code)
33760
- return w3
33761
- }
33762
33851
 
33763
- return nok(code)
33764
- }
33765
- /** @type {State} */
33852
+ /**
33853
+ * `www` prefix.
33854
+ *
33855
+ * ```markdown
33856
+ * > | a www.example.org b
33857
+ * ^^^^
33858
+ * ```
33859
+ *
33860
+ * @this {TokenizeContext}
33861
+ * @type {Tokenizer}
33862
+ */
33863
+ function tokenizeWwwPrefix(effects, ok, nok) {
33864
+ let size = 0
33865
+ return wwwPrefixInside
33766
33866
 
33767
- function w3(code) {
33768
- if (code === 87 || code === 119) {
33867
+ /**
33868
+ * In www prefix.
33869
+ *
33870
+ * ```markdown
33871
+ * > | www.example.com
33872
+ * ^^^^
33873
+ * ```
33874
+ *
33875
+ * @type {State}
33876
+ */
33877
+ function wwwPrefixInside(code) {
33878
+ if ((code === 87 || code === 119) && size < 3) {
33879
+ size++
33769
33880
  effects.consume(code)
33770
- return dot
33881
+ return wwwPrefixInside
33771
33882
  }
33772
-
33773
- return nok(code)
33774
- }
33775
- /** @type {State} */
33776
-
33777
- function dot(code) {
33778
- if (code === 46) {
33883
+ if (code === 46 && size === 3) {
33779
33884
  effects.consume(code)
33780
- return after
33885
+ return wwwPrefixAfter
33781
33886
  }
33782
-
33783
33887
  return nok(code)
33784
33888
  }
33785
- /** @type {State} */
33786
33889
 
33787
- function after(code) {
33788
- return code === null || markdownLineEnding(code) ? nok(code) : ok(code)
33890
+ /**
33891
+ * After www prefix.
33892
+ *
33893
+ * ```markdown
33894
+ * > | www.example.com
33895
+ * ^
33896
+ * ```
33897
+ *
33898
+ * @type {State}
33899
+ */
33900
+ function wwwPrefixAfter(code) {
33901
+ // If there is *anything*, we can link.
33902
+ return code === null ? nok(code) : ok(code)
33789
33903
  }
33790
33904
  }
33791
- /** @type {Tokenizer} */
33792
33905
 
33906
+ /**
33907
+ * Domain.
33908
+ *
33909
+ * ```markdown
33910
+ * > | a https://example.org b
33911
+ * ^^^^^^^^^^^
33912
+ * ```
33913
+ *
33914
+ * @this {TokenizeContext}
33915
+ * @type {Tokenizer}
33916
+ */
33793
33917
  function tokenizeDomain(effects, ok, nok) {
33794
- /** @type {boolean|undefined} */
33795
- let hasUnderscoreInLastSegment
33796
- /** @type {boolean|undefined} */
33797
-
33798
- let hasUnderscoreInLastLastSegment
33799
- return domain
33800
- /** @type {State} */
33918
+ /** @type {boolean | undefined} */
33919
+ let underscoreInLastSegment
33920
+ /** @type {boolean | undefined} */
33921
+ let underscoreInLastLastSegment
33922
+ /** @type {boolean | undefined} */
33923
+ let seen
33924
+ return domainInside
33801
33925
 
33802
- function domain(code) {
33803
- if (code === 38) {
33804
- return effects.check(
33805
- namedCharacterReference,
33806
- done,
33807
- punctuationContinuation
33808
- )(code)
33926
+ /**
33927
+ * In domain.
33928
+ *
33929
+ * ```markdown
33930
+ * > | https://example.com/a
33931
+ * ^^^^^^^^^^^
33932
+ * ```
33933
+ *
33934
+ * @type {State}
33935
+ */
33936
+ function domainInside(code) {
33937
+ // Check whether this marker, which is a trailing punctuation
33938
+ // marker, optionally followed by more trailing markers, and then
33939
+ // followed by an end.
33940
+ if (code === 46 || code === 95) {
33941
+ return effects.check(trail, domainAfter, domainAtPunctuation)(code)
33809
33942
  }
33810
33943
 
33811
- if (code === 46 || code === 95) {
33812
- return effects.check(punctuation, done, punctuationContinuation)(code)
33813
- } // GH documents that only alphanumerics (other than `-`, `.`, and `_`) can
33944
+ // GH documents that only alphanumerics (other than `-`, `.`, and `_`) can
33814
33945
  // occur, which sounds like ASCII only, but they also support `www.點看.com`,
33815
33946
  // so that’s Unicode.
33816
33947
  // Instead of some new production for Unicode alphanumerics, markdown
33817
33948
  // already has that for Unicode punctuation and whitespace, so use those.
33818
-
33949
+ // Source: <https://github.com/github/cmark-gfm/blob/ef1cfcb/extensions/autolink.c#L12>.
33819
33950
  if (
33820
33951
  code === null ||
33821
- asciiControl(code) ||
33952
+ markdownLineEndingOrSpace(code) ||
33822
33953
  unicodeWhitespace(code) ||
33823
33954
  (code !== 45 && unicodePunctuation(code))
33824
33955
  ) {
33825
- return done(code)
33956
+ return domainAfter(code)
33826
33957
  }
33827
-
33958
+ seen = true
33828
33959
  effects.consume(code)
33829
- return domain
33960
+ return domainInside
33830
33961
  }
33831
- /** @type {State} */
33832
33962
 
33833
- function punctuationContinuation(code) {
33834
- if (code === 46) {
33835
- hasUnderscoreInLastLastSegment = hasUnderscoreInLastSegment
33836
- hasUnderscoreInLastSegment = undefined
33837
- effects.consume(code)
33838
- return domain
33963
+ /**
33964
+ * In domain, at potential trailing punctuation, that was not trailing.
33965
+ *
33966
+ * ```markdown
33967
+ * > | https://example.com
33968
+ * ^
33969
+ * ```
33970
+ *
33971
+ * @type {State}
33972
+ */
33973
+ function domainAtPunctuation(code) {
33974
+ // There is an underscore in the last segment of the domain
33975
+ if (code === 95) {
33976
+ underscoreInLastSegment = true
33977
+ }
33978
+ // Otherwise, it’s a `.`: save the last segment underscore in the
33979
+ // penultimate segment slot.
33980
+ else {
33981
+ underscoreInLastLastSegment = underscoreInLastSegment
33982
+ underscoreInLastSegment = undefined
33839
33983
  }
33840
-
33841
- if (code === 95) hasUnderscoreInLastSegment = true
33842
33984
  effects.consume(code)
33843
- return domain
33985
+ return domainInside
33844
33986
  }
33845
- /** @type {State} */
33846
33987
 
33847
- function done(code) {
33848
- if (!hasUnderscoreInLastLastSegment && !hasUnderscoreInLastSegment) {
33849
- return ok(code)
33988
+ /**
33989
+ * After domain.
33990
+ *
33991
+ * ```markdown
33992
+ * > | https://example.com/a
33993
+ * ^
33994
+ * ```
33995
+ *
33996
+ * @type {State} */
33997
+ function domainAfter(code) {
33998
+ // Note: that’s GH says a dot is needed, but it’s not true:
33999
+ // <https://github.com/github/cmark-gfm/issues/279>
34000
+ if (underscoreInLastLastSegment || underscoreInLastSegment || !seen) {
34001
+ return nok(code)
33850
34002
  }
33851
-
33852
- return nok(code)
34003
+ return ok(code)
33853
34004
  }
33854
34005
  }
33855
- /** @type {Tokenizer} */
33856
34006
 
34007
+ /**
34008
+ * Path.
34009
+ *
34010
+ * ```markdown
34011
+ * > | a https://example.org/stuff b
34012
+ * ^^^^^^
34013
+ * ```
34014
+ *
34015
+ * @this {TokenizeContext}
34016
+ * @type {Tokenizer}
34017
+ */
33857
34018
  function tokenizePath(effects, ok) {
33858
- let balance = 0
33859
- return inPath
33860
- /** @type {State} */
33861
-
33862
- function inPath(code) {
33863
- if (code === 38) {
33864
- return effects.check(
33865
- namedCharacterReference,
33866
- ok,
33867
- continuedPunctuation
33868
- )(code)
33869
- }
34019
+ let sizeOpen = 0
34020
+ let sizeClose = 0
34021
+ return pathInside
33870
34022
 
34023
+ /**
34024
+ * In path.
34025
+ *
34026
+ * ```markdown
34027
+ * > | https://example.com/a
34028
+ * ^^
34029
+ * ```
34030
+ *
34031
+ * @type {State}
34032
+ */
34033
+ function pathInside(code) {
33871
34034
  if (code === 40) {
33872
- balance++
34035
+ sizeOpen++
34036
+ effects.consume(code)
34037
+ return pathInside
33873
34038
  }
33874
34039
 
33875
- if (code === 41) {
33876
- return effects.check(
33877
- punctuation,
33878
- parenAtPathEnd,
33879
- continuedPunctuation
33880
- )(code)
34040
+ // To do: `markdown-rs` also needs this.
34041
+ // If this is a paren, and there are less closings than openings,
34042
+ // we don’t check for a trail.
34043
+ if (code === 41 && sizeClose < sizeOpen) {
34044
+ return pathAtPunctuation(code)
33881
34045
  }
33882
34046
 
33883
- if (pathEnd(code)) {
33884
- return ok(code)
34047
+ // Check whether this trailing punctuation marker is optionally
34048
+ // followed by more trailing markers, and then followed
34049
+ // by an end.
34050
+ if (
34051
+ code === 33 ||
34052
+ code === 34 ||
34053
+ code === 38 ||
34054
+ code === 39 ||
34055
+ code === 41 ||
34056
+ code === 42 ||
34057
+ code === 44 ||
34058
+ code === 46 ||
34059
+ code === 58 ||
34060
+ code === 59 ||
34061
+ code === 60 ||
34062
+ code === 63 ||
34063
+ code === 93 ||
34064
+ code === 95 ||
34065
+ code === 126
34066
+ ) {
34067
+ return effects.check(trail, ok, pathAtPunctuation)(code)
33885
34068
  }
33886
-
33887
- if (trailingPunctuation(code)) {
33888
- return effects.check(punctuation, ok, continuedPunctuation)(code)
34069
+ if (
34070
+ code === null ||
34071
+ markdownLineEndingOrSpace(code) ||
34072
+ unicodeWhitespace(code)
34073
+ ) {
34074
+ return ok(code)
33889
34075
  }
33890
-
33891
34076
  effects.consume(code)
33892
- return inPath
34077
+ return pathInside
33893
34078
  }
33894
- /** @type {State} */
33895
34079
 
33896
- function continuedPunctuation(code) {
34080
+ /**
34081
+ * In path, at potential trailing punctuation, that was not trailing.
34082
+ *
34083
+ * ```markdown
34084
+ * > | https://example.com/a"b
34085
+ * ^
34086
+ * ```
34087
+ *
34088
+ * @type {State}
34089
+ */
34090
+ function pathAtPunctuation(code) {
34091
+ // Count closing parens.
34092
+ if (code === 41) {
34093
+ sizeClose++
34094
+ }
33897
34095
  effects.consume(code)
33898
- return inPath
33899
- }
33900
- /** @type {State} */
33901
-
33902
- function parenAtPathEnd(code) {
33903
- balance--
33904
- return balance < 0 ? ok(code) : continuedPunctuation(code)
34096
+ return pathInside
33905
34097
  }
33906
34098
  }
33907
- /** @type {Tokenizer} */
33908
-
33909
- function tokenizeNamedCharacterReference(effects, ok, nok) {
33910
- return start
33911
- /** @type {State} */
33912
34099
 
33913
- function start(code) {
33914
- effects.consume(code)
33915
- return inside
33916
- }
33917
- /** @type {State} */
34100
+ /**
34101
+ * Trail.
34102
+ *
34103
+ * This calls `ok` if this *is* the trail, followed by an end, which means
34104
+ * the entire trail is not part of the link.
34105
+ * It calls `nok` if this *is* part of the link.
34106
+ *
34107
+ * ```markdown
34108
+ * > | https://example.com").
34109
+ * ^^^
34110
+ * ```
34111
+ *
34112
+ * @this {TokenizeContext}
34113
+ * @type {Tokenizer}
34114
+ */
34115
+ function tokenizeTrail(effects, ok, nok) {
34116
+ return trail
33918
34117
 
33919
- function inside(code) {
33920
- if (asciiAlpha(code)) {
34118
+ /**
34119
+ * In trail of domain or path.
34120
+ *
34121
+ * ```markdown
34122
+ * > | https://example.com").
34123
+ * ^
34124
+ * ```
34125
+ *
34126
+ * @type {State}
34127
+ */
34128
+ function trail(code) {
34129
+ // Regular trailing punctuation.
34130
+ if (
34131
+ code === 33 ||
34132
+ code === 34 ||
34133
+ code === 39 ||
34134
+ code === 41 ||
34135
+ code === 42 ||
34136
+ code === 44 ||
34137
+ code === 46 ||
34138
+ code === 58 ||
34139
+ code === 59 ||
34140
+ code === 63 ||
34141
+ code === 95 ||
34142
+ code === 126
34143
+ ) {
33921
34144
  effects.consume(code)
33922
- return inside
34145
+ return trail
33923
34146
  }
33924
34147
 
33925
- if (code === 59) {
34148
+ // `&` followed by one or more alphabeticals and then a `;`, is
34149
+ // as a whole considered as trailing punctuation.
34150
+ // In all other cases, it is considered as continuation of the URL.
34151
+ if (code === 38) {
33926
34152
  effects.consume(code)
33927
- return after
34153
+ return trailCharRefStart
33928
34154
  }
33929
34155
 
34156
+ // Needed because we allow literals after `[`, as we fix:
34157
+ // <https://github.com/github/cmark-gfm/issues/278>.
34158
+ // Check that it is not followed by `(` or `[`.
34159
+ if (code === 93) {
34160
+ effects.consume(code)
34161
+ return trailBracketAfter
34162
+ }
34163
+ if (
34164
+ // `<` is an end.
34165
+ code === 60 ||
34166
+ // So is whitespace.
34167
+ code === null ||
34168
+ markdownLineEndingOrSpace(code) ||
34169
+ unicodeWhitespace(code)
34170
+ ) {
34171
+ return ok(code)
34172
+ }
33930
34173
  return nok(code)
33931
34174
  }
33932
- /** @type {State} */
33933
34175
 
33934
- function after(code) {
33935
- // If the named character reference is followed by the end of the path, it’s
33936
- // not continued punctuation.
33937
- return pathEnd(code) ? ok(code) : nok(code)
34176
+ /**
34177
+ * In trail, after `]`.
34178
+ *
34179
+ * > 👉 **Note**: this deviates from `cmark-gfm` to fix a bug.
34180
+ * > See end of <https://github.com/github/cmark-gfm/issues/278> for more.
34181
+ *
34182
+ * ```markdown
34183
+ * > | https://example.com](
34184
+ * ^
34185
+ * ```
34186
+ *
34187
+ * @type {State}
34188
+ */
34189
+ function trailBracketAfter(code) {
34190
+ // Whitespace or something that could start a resource or reference is the end.
34191
+ // Switch back to trail otherwise.
34192
+ if (
34193
+ code === null ||
34194
+ code === 40 ||
34195
+ code === 91 ||
34196
+ markdownLineEndingOrSpace(code) ||
34197
+ unicodeWhitespace(code)
34198
+ ) {
34199
+ return ok(code)
34200
+ }
34201
+ return trail(code)
33938
34202
  }
33939
- }
33940
- /** @type {Tokenizer} */
33941
-
33942
- function tokenizePunctuation(effects, ok, nok) {
33943
- return start
33944
- /** @type {State} */
33945
34203
 
33946
- function start(code) {
33947
- effects.consume(code)
33948
- return after
34204
+ /**
34205
+ * In character-reference like trail, after `&`.
34206
+ *
34207
+ * ```markdown
34208
+ * > | https://example.com&amp;).
34209
+ * ^
34210
+ * ```
34211
+ *
34212
+ * @type {State}
34213
+ */
34214
+ function trailCharRefStart(code) {
34215
+ // When non-alpha, it’s not a trail.
34216
+ return asciiAlpha(code) ? trailCharRefInside(code) : nok(code)
33949
34217
  }
33950
- /** @type {State} */
33951
34218
 
33952
- function after(code) {
33953
- // Check the next.
33954
- if (trailingPunctuation(code)) {
34219
+ /**
34220
+ * In character-reference like trail.
34221
+ *
34222
+ * ```markdown
34223
+ * > | https://example.com&amp;).
34224
+ * ^
34225
+ * ```
34226
+ *
34227
+ * @type {State}
34228
+ */
34229
+ function trailCharRefInside(code) {
34230
+ // Switch back to trail if this is well-formed.
34231
+ if (code === 59) {
33955
34232
  effects.consume(code)
33956
- return after
33957
- } // If the punctuation marker is followed by the end of the path, it’s not
33958
- // continued punctuation.
34233
+ return trail
34234
+ }
34235
+ if (asciiAlpha(code)) {
34236
+ effects.consume(code)
34237
+ return trailCharRefInside
34238
+ }
33959
34239
 
33960
- return pathEnd(code) ? ok(code) : nok(code)
34240
+ // It’s not a trail.
34241
+ return nok(code)
33961
34242
  }
33962
34243
  }
33963
- /**
33964
- * @param {Code} code
33965
- * @returns {boolean}
33966
- */
33967
34244
 
33968
- function trailingPunctuation(code) {
33969
- return (
33970
- code === 33 ||
33971
- code === 34 ||
33972
- code === 39 ||
33973
- code === 41 ||
33974
- code === 42 ||
33975
- code === 44 ||
33976
- code === 46 ||
33977
- code === 58 ||
33978
- code === 59 ||
33979
- code === 60 ||
33980
- code === 63 ||
33981
- code === 95 ||
33982
- code === 126
33983
- )
33984
- }
33985
34245
  /**
33986
- * @param {Code} code
33987
- * @returns {boolean}
34246
+ * Dot in email domain trail.
34247
+ *
34248
+ * This calls `ok` if this *is* the trail, followed by an end, which means
34249
+ * the trail is not part of the link.
34250
+ * It calls `nok` if this *is* part of the link.
34251
+ *
34252
+ * ```markdown
34253
+ * > | contact@example.org.
34254
+ * ^
34255
+ * ```
34256
+ *
34257
+ * @this {TokenizeContext}
34258
+ * @type {Tokenizer}
33988
34259
  */
34260
+ function tokenizeEmailDomainDotTrail(effects, ok, nok) {
34261
+ return start
33989
34262
 
33990
- function pathEnd(code) {
33991
- return code === null || code === 60 || markdownLineEndingOrSpace(code)
33992
- }
33993
- /**
33994
- * @param {Code} code
33995
- * @returns {boolean}
33996
- */
34263
+ /**
34264
+ * Dot.
34265
+ *
34266
+ * ```markdown
34267
+ * > | contact@example.org.
34268
+ * ^ ^
34269
+ * ```
34270
+ *
34271
+ * @type {State}
34272
+ */
34273
+ function start(code) {
34274
+ // Must be dot.
34275
+ effects.consume(code)
34276
+ return after
34277
+ }
33997
34278
 
33998
- function gfmAtext(code) {
33999
- return (
34000
- code === 43 ||
34001
- code === 45 ||
34002
- code === 46 ||
34003
- code === 95 ||
34004
- asciiAlphanumeric(code)
34005
- )
34279
+ /**
34280
+ * After dot.
34281
+ *
34282
+ * ```markdown
34283
+ * > | contact@example.org.
34284
+ * ^ ^
34285
+ * ```
34286
+ *
34287
+ * @type {State}
34288
+ */
34289
+ function after(code) {
34290
+ // Not a trail if alphanumeric.
34291
+ return asciiAlphanumeric(code) ? nok(code) : ok(code)
34292
+ }
34006
34293
  }
34007
- /** @type {Previous} */
34008
34294
 
34295
+ /**
34296
+ * See:
34297
+ * <https://github.com/github/cmark-gfm/blob/ef1cfcb/extensions/autolink.c#L156>.
34298
+ *
34299
+ * @type {Previous}
34300
+ */
34009
34301
  function previousWww(code) {
34010
34302
  return (
34011
34303
  code === null ||
34012
34304
  code === 40 ||
34013
34305
  code === 42 ||
34014
34306
  code === 95 ||
34307
+ code === 91 ||
34308
+ code === 93 ||
34015
34309
  code === 126 ||
34016
34310
  markdownLineEndingOrSpace(code)
34017
34311
  )
34018
34312
  }
34019
- /** @type {Previous} */
34020
34313
 
34021
- function previousHttp(code) {
34022
- return code === null || !asciiAlpha(code)
34314
+ /**
34315
+ * See:
34316
+ * <https://github.com/github/cmark-gfm/blob/ef1cfcb/extensions/autolink.c#L214>.
34317
+ *
34318
+ * @type {Previous}
34319
+ */
34320
+ function previousProtocol(code) {
34321
+ return !asciiAlpha(code)
34023
34322
  }
34024
- /** @type {Previous} */
34025
34323
 
34324
+ /**
34325
+ * @this {TokenizeContext}
34326
+ * @type {Previous}
34327
+ */
34026
34328
  function previousEmail(code) {
34027
- return code !== 47 && previousHttp(code)
34329
+ // Do not allow a slash “inside” atext.
34330
+ // The reference code is a bit weird, but that’s what it results in.
34331
+ // Source: <https://github.com/github/cmark-gfm/blob/ef1cfcb/extensions/autolink.c#L307>.
34332
+ // Other than slash, every preceding character is allowed.
34333
+ return !(code === 47 || gfmAtext(code))
34028
34334
  }
34335
+
34029
34336
  /**
34030
- * @param {Array<Event>} events
34337
+ * @param {Code} code
34031
34338
  * @returns {boolean}
34032
34339
  */
34340
+ function gfmAtext(code) {
34341
+ return (
34342
+ code === 43 ||
34343
+ code === 45 ||
34344
+ code === 46 ||
34345
+ code === 95 ||
34346
+ asciiAlphanumeric(code)
34347
+ )
34348
+ }
34033
34349
 
34350
+ /**
34351
+ * @param {Array<Event>} events
34352
+ * @returns {boolean}
34353
+ */
34034
34354
  function previousUnbalanced(events) {
34035
34355
  let index = events.length
34036
34356
  let result = false
34037
-
34038
34357
  while (index--) {
34039
34358
  const token = events[index][1]
34040
-
34041
34359
  if (
34042
34360
  (token.type === 'labelLink' || token.type === 'labelImage') &&
34043
34361
  !token._balanced
34044
34362
  ) {
34045
34363
  result = true
34046
34364
  break
34047
- } // @ts-expect-error If we’ve seen this token, and it was marked as not
34048
- // having any unbalanced bracket before it, we can exit.
34365
+ }
34049
34366
 
34367
+ // @ts-expect-error If we’ve seen this token, and it was marked as not
34368
+ // having any unbalanced bracket before it, we can exit.
34050
34369
  if (token._gfmAutolinkLiteralWalkedInto) {
34051
34370
  result = false
34052
34371
  break
34053
34372
  }
34054
34373
  }
34055
-
34056
34374
  if (events.length > 0 && !result) {
34057
34375
  // @ts-expect-error Mark the last token as “walked into” w/o finding
34058
34376
  // anything.
34059
34377
  events[events.length - 1][1]._gfmAutolinkLiteralWalkedInto = true
34060
34378
  }
34061
-
34062
34379
  return result
34063
34380
  }
34064
34381
 
@@ -34772,607 +35089,1143 @@ function gfmStrikethrough(options) {
34772
35089
  }
34773
35090
  }
34774
35091
 
34775
- ;// CONCATENATED MODULE: ../node_modules/micromark-extension-gfm-table/lib/syntax.js
35092
+ ;// CONCATENATED MODULE: ../node_modules/micromark-extension-gfm-table/lib/edit-map.js
34776
35093
  /**
34777
- * @typedef {import('micromark-util-types').Extension} Extension
34778
- * @typedef {import('micromark-util-types').Resolver} Resolver
34779
- * @typedef {import('micromark-util-types').Tokenizer} Tokenizer
34780
- * @typedef {import('micromark-util-types').State} State
34781
- * @typedef {import('micromark-util-types').Token} Token
35094
+ * @typedef {import('micromark-util-types').Event} Event
35095
+ */
35096
+
35097
+ // Port of `edit_map.rs` from `markdown-rs`.
35098
+ // This should move to `markdown-js` later.
35099
+
35100
+ // Deal with several changes in events, batching them together.
35101
+ //
35102
+ // Preferably, changes should be kept to a minimum.
35103
+ // Sometimes, it’s needed to change the list of events, because parsing can be
35104
+ // messy, and it helps to expose a cleaner interface of events to the compiler
35105
+ // and other users.
35106
+ // It can also help to merge many adjacent similar events.
35107
+ // And, in other cases, it’s needed to parse subcontent: pass some events
35108
+ // through another tokenizer and inject the result.
35109
+
35110
+ /**
35111
+ * @typedef {[number, number, Array<Event>]} Change
35112
+ * @typedef {[number, number, number]} Jump
34782
35113
  */
34783
35114
 
34784
35115
  /**
34785
- * @typedef {'left'|'center'|'right'|'none'} Align
35116
+ * Tracks a bunch of edits.
34786
35117
  */
35118
+ class EditMap {
35119
+ /**
35120
+ * Create a new edit map.
35121
+ */
35122
+ constructor() {
35123
+ /**
35124
+ * Record of changes.
35125
+ *
35126
+ * @type {Array<Change>}
35127
+ */
35128
+ this.map = []
35129
+ }
34787
35130
 
35131
+ /**
35132
+ * Create an edit: a remove and/or add at a certain place.
35133
+ *
35134
+ * @param {number} index
35135
+ * @param {number} remove
35136
+ * @param {Array<Event>} add
35137
+ * @returns {void}
35138
+ */
35139
+ add(index, remove, add) {
35140
+ addImpl(this, index, remove, add)
35141
+ }
35142
+
35143
+ // To do: not used here.
35144
+ // /**
35145
+ // * Create an edit: but insert `add` before existing additions.
35146
+ // *
35147
+ // * @param {number} index
35148
+ // * @param {number} remove
35149
+ // * @param {Array<Event>} add
35150
+ // * @returns {void}
35151
+ // */
35152
+ // addBefore(index, remove, add) {
35153
+ // addImpl(this, index, remove, add, true)
35154
+ // }
34788
35155
 
35156
+ /**
35157
+ * Done, change the events.
35158
+ *
35159
+ * @param {Array<Event>} events
35160
+ * @returns {void}
35161
+ */
35162
+ consume(events) {
35163
+ this.map.sort((a, b) => a[0] - b[0])
34789
35164
 
34790
- /** @type {Extension} */
34791
- const gfmTable = {
34792
- flow: {
34793
- null: {
34794
- tokenize: tokenizeTable,
34795
- resolve: resolveTable
35165
+ /* c8 ignore next 3 -- `resolve` is never called without tables, so without edits. */
35166
+ if (this.map.length === 0) {
35167
+ return
34796
35168
  }
34797
- }
34798
- }
34799
- const nextPrefixedOrBlank = {
34800
- tokenize: tokenizeNextPrefixedOrBlank,
34801
- partial: true
34802
- }
34803
- /** @type {Resolver} */
34804
35169
 
34805
- function resolveTable(events, context) {
34806
- let index = -1
34807
- /** @type {boolean|undefined} */
35170
+ // To do: if links are added in events, like they are in `markdown-rs`,
35171
+ // this is needed.
35172
+ // // Calculate jumps: where items in the current list move to.
35173
+ // /** @type {Array<Jump>} */
35174
+ // const jumps = []
35175
+ // let index = 0
35176
+ // let addAcc = 0
35177
+ // let removeAcc = 0
35178
+ // while (index < this.map.length) {
35179
+ // const [at, remove, add] = this.map[index]
35180
+ // removeAcc += remove
35181
+ // addAcc += add.length
35182
+ // jumps.push([at, removeAcc, addAcc])
35183
+ // index += 1
35184
+ // }
35185
+ //
35186
+ // . shiftLinks(events, jumps)
34808
35187
 
34809
- let inHead
34810
- /** @type {boolean|undefined} */
35188
+ let index = this.map.length
35189
+ /** @type {Array<Array<Event>>} */
35190
+ const vecs = []
35191
+ while (index > 0) {
35192
+ index -= 1
35193
+ vecs.push(events.slice(this.map[index][0] + this.map[index][1]))
35194
+ // eslint-disable-next-line unicorn/no-array-push-push
35195
+ vecs.push(this.map[index][2])
34811
35196
 
34812
- let inDelimiterRow
34813
- /** @type {boolean|undefined} */
35197
+ // Truncate rest.
35198
+ events.length = this.map[index][0]
35199
+ }
35200
+ vecs.push([...events])
35201
+ events.length = 0
35202
+ let slice = vecs.pop()
35203
+ while (slice) {
35204
+ events.push(...slice)
35205
+ slice = vecs.pop()
35206
+ }
34814
35207
 
34815
- let inRow
34816
- /** @type {number|undefined} */
35208
+ // Truncate everything.
35209
+ this.map.length = 0
35210
+ }
35211
+ }
34817
35212
 
34818
- let contentStart
34819
- /** @type {number|undefined} */
35213
+ /**
35214
+ * Create an edit.
35215
+ *
35216
+ * @param {EditMap} editMap
35217
+ * @param {number} at
35218
+ * @param {number} remove
35219
+ * @param {Array<Event>} add
35220
+ * @returns {void}
35221
+ */
35222
+ function addImpl(editMap, at, remove, add) {
35223
+ let index = 0
34820
35224
 
34821
- let contentEnd
34822
- /** @type {number|undefined} */
35225
+ /* c8 ignore next 3 -- `resolve` is never called without tables, so without edits. */
35226
+ if (remove === 0 && add.length === 0) {
35227
+ return
35228
+ }
35229
+ while (index < editMap.map.length) {
35230
+ if (editMap.map[index][0] === at) {
35231
+ editMap.map[index][1] += remove
34823
35232
 
34824
- let cellStart
34825
- /** @type {boolean|undefined} */
35233
+ // To do: before not used.
35234
+ // if (before) {
35235
+ // add.push(...editMap.map[index][2])
35236
+ // editMap.map[index][2] = add
35237
+ // } else {
35238
+ editMap.map[index][2].push(...add)
35239
+ // }
34826
35240
 
34827
- let seenCellInRow
35241
+ return
35242
+ }
35243
+ index += 1
35244
+ }
35245
+ editMap.map.push([at, remove, add])
35246
+ }
35247
+
35248
+ // /**
35249
+ // * Shift `previous` and `next` links according to `jumps`.
35250
+ // *
35251
+ // * This fixes links in case there are events removed or added between them.
35252
+ // *
35253
+ // * @param {Array<Event>} events
35254
+ // * @param {Array<Jump>} jumps
35255
+ // */
35256
+ // function shiftLinks(events, jumps) {
35257
+ // let jumpIndex = 0
35258
+ // let index = 0
35259
+ // let add = 0
35260
+ // let rm = 0
35261
+
35262
+ // while (index < events.length) {
35263
+ // const rmCurr = rm
35264
+
35265
+ // while (jumpIndex < jumps.length && jumps[jumpIndex][0] <= index) {
35266
+ // add = jumps[jumpIndex][2]
35267
+ // rm = jumps[jumpIndex][1]
35268
+ // jumpIndex += 1
35269
+ // }
35270
+
35271
+ // // Ignore items that will be removed.
35272
+ // if (rm > rmCurr) {
35273
+ // index += rm - rmCurr
35274
+ // } else {
35275
+ // console.log('to do: links?', add, rmCurr)
35276
+ // // ?
35277
+ // // if let Some(link) = &events[index].link {
35278
+ // // if let Some(next) = link.next {
35279
+ // // events[next].link.as_mut().unwrap().previous = Some(index + add - rm);
35280
+ // // while jumpIndex < jumps.len() && jumps[jumpIndex].0 <= next {
35281
+ // // add = jumps[jumpIndex].2;
35282
+ // // rm = jumps[jumpIndex].1;
35283
+ // // jumpIndex += 1;
35284
+ // // }
35285
+ // // events[index].link.as_mut().unwrap().next = Some(next + add - rm);
35286
+ // // index = next;
35287
+ // // continue;
35288
+ // // }
35289
+ // // }
35290
+ // index += 1
35291
+ // }
35292
+ // }
35293
+ // }
35294
+
35295
+ ;// CONCATENATED MODULE: ../node_modules/micromark-extension-gfm-table/lib/infer.js
35296
+ /**
35297
+ * @typedef {import('micromark-util-types').Event} Event
35298
+ */
34828
35299
 
34829
- while (++index < events.length) {
34830
- const token = events[index][1]
35300
+ /**
35301
+ * @typedef {'left' | 'center' | 'right' | 'none'} Align
35302
+ */
34831
35303
 
34832
- if (inRow) {
34833
- if (token.type === 'temporaryTableCellContent') {
34834
- contentStart = contentStart || index
34835
- contentEnd = index
35304
+ /**
35305
+ * Figure out the alignment of a GFM table.
35306
+ *
35307
+ * @param {Array<Event>} events
35308
+ * @param {number} index
35309
+ * @returns {Array<Align>}
35310
+ */
35311
+ function gfmTableAlign(events, index) {
35312
+ let inDelimiterRow = false
35313
+ /** @type {Array<Align>} */
35314
+ const align = []
35315
+ while (index < events.length) {
35316
+ const event = events[index]
35317
+ if (inDelimiterRow) {
35318
+ if (event[0] === 'enter') {
35319
+ // Start of alignment value: set a new column.
35320
+ // To do: `markdown-rs` uses `tableDelimiterCellValue`.
35321
+ if (event[1].type === 'tableContent') {
35322
+ align.push(
35323
+ events[index + 1][1].type === 'tableDelimiterMarker'
35324
+ ? 'left'
35325
+ : 'none'
35326
+ )
35327
+ }
34836
35328
  }
34837
-
34838
- if (
34839
- // Combine separate content parts into one.
34840
- (token.type === 'tableCellDivider' || token.type === 'tableRow') &&
34841
- contentEnd
34842
- ) {
34843
- const content = {
34844
- type: 'tableContent',
34845
- start: events[contentStart][1].start,
34846
- end: events[contentEnd][1].end
34847
- }
34848
- /** @type {Token} */
34849
-
34850
- const text = {
34851
- type: 'chunkText',
34852
- start: content.start,
34853
- end: content.end,
34854
- // @ts-expect-error It’s fine.
34855
- contentType: 'text'
34856
- }
34857
- events.splice(
34858
- contentStart,
34859
- contentEnd - contentStart + 1,
34860
- ['enter', content, context],
34861
- ['enter', text, context],
34862
- ['exit', text, context],
34863
- ['exit', content, context]
34864
- )
34865
- index -= contentEnd - contentStart - 3
34866
- contentStart = undefined
34867
- contentEnd = undefined
35329
+ // Exits:
35330
+ // End of alignment value: change the column.
35331
+ // To do: `markdown-rs` uses `tableDelimiterCellValue`.
35332
+ else if (event[1].type === 'tableContent') {
35333
+ if (events[index - 1][1].type === 'tableDelimiterMarker') {
35334
+ const alignIndex = align.length - 1
35335
+ align[alignIndex] = align[alignIndex] === 'left' ? 'center' : 'right'
35336
+ }
35337
+ }
35338
+ // Done!
35339
+ else if (event[1].type === 'tableDelimiterRow') {
35340
+ break
34868
35341
  }
35342
+ } else if (event[0] === 'enter' && event[1].type === 'tableDelimiterRow') {
35343
+ inDelimiterRow = true
34869
35344
  }
35345
+ index += 1
35346
+ }
35347
+ return align
35348
+ }
34870
35349
 
34871
- if (
34872
- events[index][0] === 'exit' &&
34873
- cellStart !== undefined &&
34874
- cellStart + (seenCellInRow ? 0 : 1) < index &&
34875
- (token.type === 'tableCellDivider' ||
34876
- (token.type === 'tableRow' &&
34877
- (cellStart + 3 < index ||
34878
- events[cellStart][1].type !== 'whitespace')))
34879
- ) {
34880
- const cell = {
34881
- type: inDelimiterRow
34882
- ? 'tableDelimiter'
34883
- : inHead
34884
- ? 'tableHeader'
34885
- : 'tableData',
34886
- start: events[cellStart][1].start,
34887
- end: events[index][1].end
34888
- }
34889
- events.splice(index + (token.type === 'tableCellDivider' ? 1 : 0), 0, [
34890
- 'exit',
34891
- cell,
34892
- context
34893
- ])
34894
- events.splice(cellStart, 0, ['enter', cell, context])
34895
- index += 2
34896
- cellStart = index + 1
34897
- seenCellInRow = true
34898
- }
35350
+ ;// CONCATENATED MODULE: ../node_modules/micromark-extension-gfm-table/lib/syntax.js
35351
+ /**
35352
+ * @typedef {import('micromark-util-types').Event} Event
35353
+ * @typedef {import('micromark-util-types').Extension} Extension
35354
+ * @typedef {import('micromark-util-types').Point} Point
35355
+ * @typedef {import('micromark-util-types').Resolver} Resolver
35356
+ * @typedef {import('micromark-util-types').State} State
35357
+ * @typedef {import('micromark-util-types').Token} Token
35358
+ * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext
35359
+ * @typedef {import('micromark-util-types').Tokenizer} Tokenizer
35360
+ */
34899
35361
 
34900
- if (token.type === 'tableRow') {
34901
- inRow = events[index][0] === 'enter'
35362
+ /**
35363
+ * @typedef {[number, number, number, number]} Range
35364
+ * Cell info.
35365
+ *
35366
+ * @typedef {0 | 1 | 2 | 3} RowKind
35367
+ * Where we are: `1` for head row, `2` for delimiter row, `3` for body row.
35368
+ */
34902
35369
 
34903
- if (inRow) {
34904
- cellStart = index + 1
34905
- seenCellInRow = false
34906
- }
34907
- }
34908
35370
 
34909
- if (token.type === 'tableDelimiterRow') {
34910
- inDelimiterRow = events[index][0] === 'enter'
34911
35371
 
34912
- if (inDelimiterRow) {
34913
- cellStart = index + 1
34914
- seenCellInRow = false
34915
- }
34916
- }
34917
35372
 
34918
- if (token.type === 'tableHead') {
34919
- inHead = events[index][0] === 'enter'
35373
+
35374
+
35375
+ // To do: next major: expose functions.
35376
+
35377
+ /**
35378
+ * Extension for `micromark` that can be passed in `extensions` to enable GFM
35379
+ * table syntax.
35380
+ *
35381
+ * @type {Extension}
35382
+ */
35383
+ const gfmTable = {
35384
+ flow: {
35385
+ null: {
35386
+ tokenize: tokenizeTable,
35387
+ resolveAll: resolveTable
34920
35388
  }
34921
35389
  }
34922
-
34923
- return events
34924
35390
  }
34925
- /** @type {Tokenizer} */
34926
35391
 
35392
+ /**
35393
+ * @this {TokenizeContext}
35394
+ * @type {Tokenizer}
35395
+ */
34927
35396
  function tokenizeTable(effects, ok, nok) {
34928
35397
  const self = this
34929
- /** @type {Array<Align>} */
34930
-
34931
- const align = []
34932
- let tableHeaderCount = 0
34933
- /** @type {boolean|undefined} */
34934
-
34935
- let seenDelimiter
34936
- /** @type {boolean|undefined} */
34937
-
34938
- let hasDash
35398
+ let size = 0
35399
+ let sizeB = 0
35400
+ /** @type {boolean | undefined} */
35401
+ let seen
34939
35402
  return start
34940
- /** @type {State} */
34941
35403
 
35404
+ /**
35405
+ * Start of a GFM table.
35406
+ *
35407
+ * If there is a valid table row or table head before, then we try to parse
35408
+ * another row.
35409
+ * Otherwise, we try to parse a head.
35410
+ *
35411
+ * ```markdown
35412
+ * > | | a |
35413
+ * ^
35414
+ * | | - |
35415
+ * > | | b |
35416
+ * ^
35417
+ * ```
35418
+ * @type {State}
35419
+ */
34942
35420
  function start(code) {
34943
- // @ts-expect-error Custom.
34944
- effects.enter('table')._align = align
35421
+ let index = self.events.length - 1
35422
+ while (index > -1) {
35423
+ const type = self.events[index][1].type
35424
+ if (
35425
+ type === 'lineEnding' ||
35426
+ // Note: markdown-rs uses `whitespace` instead of `linePrefix`
35427
+ type === 'linePrefix'
35428
+ )
35429
+ index--
35430
+ else break
35431
+ }
35432
+ const tail = index > -1 ? self.events[index][1].type : null
35433
+ const next =
35434
+ tail === 'tableHead' || tail === 'tableRow' ? bodyRowStart : headRowBefore
35435
+
35436
+ // Don’t allow lazy body rows.
35437
+ if (next === bodyRowStart && self.parser.lazy[self.now().line]) {
35438
+ return nok(code)
35439
+ }
35440
+ return next(code)
35441
+ }
35442
+
35443
+ /**
35444
+ * Before table head row.
35445
+ *
35446
+ * ```markdown
35447
+ * > | | a |
35448
+ * ^
35449
+ * | | - |
35450
+ * | | b |
35451
+ * ```
35452
+ *
35453
+ * @type {State}
35454
+ */
35455
+ function headRowBefore(code) {
34945
35456
  effects.enter('tableHead')
34946
- effects.enter('tableRow') // If we start with a pipe, we open a cell marker.
35457
+ effects.enter('tableRow')
35458
+ return headRowStart(code)
35459
+ }
34947
35460
 
35461
+ /**
35462
+ * Before table head row, after whitespace.
35463
+ *
35464
+ * ```markdown
35465
+ * > | | a |
35466
+ * ^
35467
+ * | | - |
35468
+ * | | b |
35469
+ * ```
35470
+ *
35471
+ * @type {State}
35472
+ */
35473
+ function headRowStart(code) {
34948
35474
  if (code === 124) {
34949
- return cellDividerHead(code)
35475
+ return headRowBreak(code)
34950
35476
  }
34951
35477
 
34952
- tableHeaderCount++
34953
- effects.enter('temporaryTableCellContent') // Can’t be space or eols at the start of a construct, so we’re in a cell.
34954
-
34955
- return inCellContentHead(code)
34956
- }
34957
- /** @type {State} */
35478
+ // To do: micromark-js should let us parse our own whitespace in extensions,
35479
+ // like `markdown-rs`:
35480
+ //
35481
+ // ```js
35482
+ // // 4+ spaces.
35483
+ // if (markdownSpace(code)) {
35484
+ // return nok(code)
35485
+ // }
35486
+ // ```
34958
35487
 
34959
- function cellDividerHead(code) {
34960
- effects.enter('tableCellDivider')
34961
- effects.consume(code)
34962
- effects.exit('tableCellDivider')
34963
- seenDelimiter = true
34964
- return cellBreakHead
35488
+ seen = true
35489
+ // Count the first character, that isn’t a pipe, double.
35490
+ sizeB += 1
35491
+ return headRowBreak(code)
34965
35492
  }
34966
- /** @type {State} */
34967
35493
 
34968
- function cellBreakHead(code) {
34969
- if (code === null || markdownLineEnding(code)) {
34970
- return atRowEndHead(code)
35494
+ /**
35495
+ * At break in table head row.
35496
+ *
35497
+ * ```markdown
35498
+ * > | | a |
35499
+ * ^
35500
+ * ^
35501
+ * ^
35502
+ * | | - |
35503
+ * | | b |
35504
+ * ```
35505
+ *
35506
+ * @type {State}
35507
+ */
35508
+ function headRowBreak(code) {
35509
+ if (code === null) {
35510
+ // Note: in `markdown-rs`, we need to reset, in `micromark-js` we don‘t.
35511
+ return nok(code)
34971
35512
  }
35513
+ if (markdownLineEnding(code)) {
35514
+ // If anything other than one pipe (ignoring whitespace) was used, it’s fine.
35515
+ if (sizeB > 1) {
35516
+ sizeB = 0
35517
+ // To do: check if this works.
35518
+ // Feel free to interrupt:
35519
+ self.interrupt = true
35520
+ effects.exit('tableRow')
35521
+ effects.enter('lineEnding')
35522
+ effects.consume(code)
35523
+ effects.exit('lineEnding')
35524
+ return headDelimiterStart
35525
+ }
34972
35526
 
35527
+ // Note: in `markdown-rs`, we need to reset, in `micromark-js` we don‘t.
35528
+ return nok(code)
35529
+ }
34973
35530
  if (markdownSpace(code)) {
34974
- effects.enter('whitespace')
34975
- effects.consume(code)
34976
- return inWhitespaceHead
35531
+ // To do: check if this is fine.
35532
+ // effects.attempt(State::Next(StateName::GfmTableHeadRowBreak), State::Nok)
35533
+ // State::Retry(space_or_tab(tokenizer))
35534
+ return factorySpace(effects, headRowBreak, 'whitespace')(code)
34977
35535
  }
34978
-
34979
- if (seenDelimiter) {
34980
- seenDelimiter = undefined
34981
- tableHeaderCount++
35536
+ sizeB += 1
35537
+ if (seen) {
35538
+ seen = false
35539
+ // Header cell count.
35540
+ size += 1
34982
35541
  }
34983
-
34984
35542
  if (code === 124) {
34985
- return cellDividerHead(code)
34986
- } // Anything else is cell content.
34987
-
34988
- effects.enter('temporaryTableCellContent')
34989
- return inCellContentHead(code)
34990
- }
34991
- /** @type {State} */
34992
-
34993
- function inWhitespaceHead(code) {
34994
- if (markdownSpace(code)) {
35543
+ effects.enter('tableCellDivider')
34995
35544
  effects.consume(code)
34996
- return inWhitespaceHead
35545
+ effects.exit('tableCellDivider')
35546
+ // Whether a delimiter was seen.
35547
+ seen = true
35548
+ return headRowBreak
34997
35549
  }
34998
35550
 
34999
- effects.exit('whitespace')
35000
- return cellBreakHead(code)
35551
+ // Anything else is cell data.
35552
+ effects.enter('data')
35553
+ return headRowData(code)
35001
35554
  }
35002
- /** @type {State} */
35003
35555
 
35004
- function inCellContentHead(code) {
35005
- // EOF, whitespace, pipe
35556
+ /**
35557
+ * In table head row data.
35558
+ *
35559
+ * ```markdown
35560
+ * > | | a |
35561
+ * ^
35562
+ * | | - |
35563
+ * | | b |
35564
+ * ```
35565
+ *
35566
+ * @type {State}
35567
+ */
35568
+ function headRowData(code) {
35006
35569
  if (code === null || code === 124 || markdownLineEndingOrSpace(code)) {
35007
- effects.exit('temporaryTableCellContent')
35008
- return cellBreakHead(code)
35570
+ effects.exit('data')
35571
+ return headRowBreak(code)
35009
35572
  }
35010
-
35011
35573
  effects.consume(code)
35012
- return code === 92 ? inCellContentEscapeHead : inCellContentHead
35574
+ return code === 92 ? headRowEscape : headRowData
35013
35575
  }
35014
- /** @type {State} */
35015
35576
 
35016
- function inCellContentEscapeHead(code) {
35577
+ /**
35578
+ * In table head row escape.
35579
+ *
35580
+ * ```markdown
35581
+ * > | | a\-b |
35582
+ * ^
35583
+ * | | ---- |
35584
+ * | | c |
35585
+ * ```
35586
+ *
35587
+ * @type {State}
35588
+ */
35589
+ function headRowEscape(code) {
35017
35590
  if (code === 92 || code === 124) {
35018
35591
  effects.consume(code)
35019
- return inCellContentHead
35020
- } // Anything else.
35021
-
35022
- return inCellContentHead(code)
35023
- }
35024
- /** @type {State} */
35025
-
35026
- function atRowEndHead(code) {
35027
- if (code === null) {
35028
- return nok(code)
35592
+ return headRowData
35029
35593
  }
35030
-
35031
- effects.exit('tableRow')
35032
- effects.exit('tableHead')
35033
- const originalInterrupt = self.interrupt
35034
- self.interrupt = true
35035
- return effects.attempt(
35036
- {
35037
- tokenize: tokenizeRowEnd,
35038
- partial: true
35039
- },
35040
- function (code) {
35041
- self.interrupt = originalInterrupt
35042
- effects.enter('tableDelimiterRow')
35043
- return atDelimiterRowBreak(code)
35044
- },
35045
- function (code) {
35046
- self.interrupt = originalInterrupt
35047
- return nok(code)
35048
- }
35049
- )(code)
35594
+ return headRowData(code)
35050
35595
  }
35051
- /** @type {State} */
35052
35596
 
35053
- function atDelimiterRowBreak(code) {
35054
- if (code === null || markdownLineEnding(code)) {
35055
- return rowEndDelimiter(code)
35056
- }
35597
+ /**
35598
+ * Before delimiter row.
35599
+ *
35600
+ * ```markdown
35601
+ * | | a |
35602
+ * > | | - |
35603
+ * ^
35604
+ * | | b |
35605
+ * ```
35606
+ *
35607
+ * @type {State}
35608
+ */
35609
+ function headDelimiterStart(code) {
35610
+ // Reset `interrupt`.
35611
+ self.interrupt = false
35057
35612
 
35613
+ // Note: in `markdown-rs`, we need to handle piercing here too.
35614
+ if (self.parser.lazy[self.now().line]) {
35615
+ return nok(code)
35616
+ }
35617
+ effects.enter('tableDelimiterRow')
35618
+ // Track if we’ve seen a `:` or `|`.
35619
+ seen = false
35058
35620
  if (markdownSpace(code)) {
35059
- effects.enter('whitespace')
35060
- effects.consume(code)
35061
- return inWhitespaceDelimiter
35621
+ return factorySpace(
35622
+ effects,
35623
+ headDelimiterBefore,
35624
+ 'linePrefix',
35625
+ self.parser.constructs.disable.null.includes('codeIndented')
35626
+ ? undefined
35627
+ : 4
35628
+ )(code)
35062
35629
  }
35630
+ return headDelimiterBefore(code)
35631
+ }
35063
35632
 
35064
- if (code === 45) {
35065
- effects.enter('tableDelimiterFiller')
35066
- effects.consume(code)
35067
- hasDash = true
35068
- align.push('none')
35069
- return inFillerDelimiter
35633
+ /**
35634
+ * Before delimiter row, after optional whitespace.
35635
+ *
35636
+ * Reused when a `|` is found later, to parse another cell.
35637
+ *
35638
+ * ```markdown
35639
+ * | | a |
35640
+ * > | | - |
35641
+ * ^
35642
+ * | | b |
35643
+ * ```
35644
+ *
35645
+ * @type {State}
35646
+ */
35647
+ function headDelimiterBefore(code) {
35648
+ if (code === 45 || code === 58) {
35649
+ return headDelimiterValueBefore(code)
35070
35650
  }
35071
-
35072
- if (code === 58) {
35073
- effects.enter('tableDelimiterAlignment')
35074
- effects.consume(code)
35075
- effects.exit('tableDelimiterAlignment')
35076
- align.push('left')
35077
- return afterLeftAlignment
35078
- } // If we start with a pipe, we open a cell marker.
35079
-
35080
35651
  if (code === 124) {
35652
+ seen = true
35653
+ // If we start with a pipe, we open a cell marker.
35081
35654
  effects.enter('tableCellDivider')
35082
35655
  effects.consume(code)
35083
35656
  effects.exit('tableCellDivider')
35084
- return atDelimiterRowBreak
35657
+ return headDelimiterCellBefore
35085
35658
  }
35086
35659
 
35087
- return nok(code)
35660
+ // More whitespace / empty row not allowed at start.
35661
+ return headDelimiterNok(code)
35088
35662
  }
35089
- /** @type {State} */
35090
35663
 
35091
- function inWhitespaceDelimiter(code) {
35664
+ /**
35665
+ * After `|`, before delimiter cell.
35666
+ *
35667
+ * ```markdown
35668
+ * | | a |
35669
+ * > | | - |
35670
+ * ^
35671
+ * ```
35672
+ *
35673
+ * @type {State}
35674
+ */
35675
+ function headDelimiterCellBefore(code) {
35092
35676
  if (markdownSpace(code)) {
35093
- effects.consume(code)
35094
- return inWhitespaceDelimiter
35677
+ return factorySpace(effects, headDelimiterValueBefore, 'whitespace')(code)
35095
35678
  }
35096
-
35097
- effects.exit('whitespace')
35098
- return atDelimiterRowBreak(code)
35679
+ return headDelimiterValueBefore(code)
35099
35680
  }
35100
- /** @type {State} */
35101
-
35102
- function inFillerDelimiter(code) {
35103
- if (code === 45) {
35104
- effects.consume(code)
35105
- return inFillerDelimiter
35106
- }
35107
-
35108
- effects.exit('tableDelimiterFiller')
35109
35681
 
35682
+ /**
35683
+ * Before delimiter cell value.
35684
+ *
35685
+ * ```markdown
35686
+ * | | a |
35687
+ * > | | - |
35688
+ * ^
35689
+ * ```
35690
+ *
35691
+ * @type {State}
35692
+ */
35693
+ function headDelimiterValueBefore(code) {
35694
+ // Align: left.
35110
35695
  if (code === 58) {
35111
- effects.enter('tableDelimiterAlignment')
35696
+ sizeB += 1
35697
+ seen = true
35698
+ effects.enter('tableDelimiterMarker')
35112
35699
  effects.consume(code)
35113
- effects.exit('tableDelimiterAlignment')
35114
- align[align.length - 1] =
35115
- align[align.length - 1] === 'left' ? 'center' : 'right'
35116
- return afterRightAlignment
35700
+ effects.exit('tableDelimiterMarker')
35701
+ return headDelimiterLeftAlignmentAfter
35117
35702
  }
35118
35703
 
35119
- return atDelimiterRowBreak(code)
35704
+ // Align: none.
35705
+ if (code === 45) {
35706
+ sizeB += 1
35707
+ // To do: seems weird that this *isn’t* left aligned, but that state is used?
35708
+ return headDelimiterLeftAlignmentAfter(code)
35709
+ }
35710
+ if (code === null || markdownLineEnding(code)) {
35711
+ return headDelimiterCellAfter(code)
35712
+ }
35713
+ return headDelimiterNok(code)
35120
35714
  }
35121
- /** @type {State} */
35122
35715
 
35123
- function afterLeftAlignment(code) {
35716
+ /**
35717
+ * After delimiter cell left alignment marker.
35718
+ *
35719
+ * ```markdown
35720
+ * | | a |
35721
+ * > | | :- |
35722
+ * ^
35723
+ * ```
35724
+ *
35725
+ * @type {State}
35726
+ */
35727
+ function headDelimiterLeftAlignmentAfter(code) {
35124
35728
  if (code === 45) {
35125
35729
  effects.enter('tableDelimiterFiller')
35126
- effects.consume(code)
35127
- hasDash = true
35128
- return inFillerDelimiter
35129
- } // Anything else is not ok.
35730
+ return headDelimiterFiller(code)
35731
+ }
35130
35732
 
35131
- return nok(code)
35733
+ // Anything else is not ok after the left-align colon.
35734
+ return headDelimiterNok(code)
35132
35735
  }
35133
- /** @type {State} */
35134
-
35135
- function afterRightAlignment(code) {
35136
- if (code === null || markdownLineEnding(code)) {
35137
- return rowEndDelimiter(code)
35138
- }
35139
35736
 
35140
- if (markdownSpace(code)) {
35141
- effects.enter('whitespace')
35737
+ /**
35738
+ * In delimiter cell filler.
35739
+ *
35740
+ * ```markdown
35741
+ * | | a |
35742
+ * > | | - |
35743
+ * ^
35744
+ * ```
35745
+ *
35746
+ * @type {State}
35747
+ */
35748
+ function headDelimiterFiller(code) {
35749
+ if (code === 45) {
35142
35750
  effects.consume(code)
35143
- return inWhitespaceDelimiter
35144
- } // `|`
35751
+ return headDelimiterFiller
35752
+ }
35145
35753
 
35146
- if (code === 124) {
35147
- effects.enter('tableCellDivider')
35754
+ // Align is `center` if it was `left`, `right` otherwise.
35755
+ if (code === 58) {
35756
+ seen = true
35757
+ effects.exit('tableDelimiterFiller')
35758
+ effects.enter('tableDelimiterMarker')
35148
35759
  effects.consume(code)
35149
- effects.exit('tableCellDivider')
35150
- return atDelimiterRowBreak
35760
+ effects.exit('tableDelimiterMarker')
35761
+ return headDelimiterRightAlignmentAfter
35151
35762
  }
35152
-
35153
- return nok(code)
35763
+ effects.exit('tableDelimiterFiller')
35764
+ return headDelimiterRightAlignmentAfter(code)
35154
35765
  }
35155
- /** @type {State} */
35156
-
35157
- function rowEndDelimiter(code) {
35158
- effects.exit('tableDelimiterRow') // Exit if there was no dash at all, or if the header cell count is not the
35159
- // delimiter cell count.
35160
35766
 
35161
- if (!hasDash || tableHeaderCount !== align.length) {
35162
- return nok(code)
35767
+ /**
35768
+ * After delimiter cell right alignment marker.
35769
+ *
35770
+ * ```markdown
35771
+ * | | a |
35772
+ * > | | -: |
35773
+ * ^
35774
+ * ```
35775
+ *
35776
+ * @type {State}
35777
+ */
35778
+ function headDelimiterRightAlignmentAfter(code) {
35779
+ if (markdownSpace(code)) {
35780
+ return factorySpace(effects, headDelimiterCellAfter, 'whitespace')(code)
35163
35781
  }
35782
+ return headDelimiterCellAfter(code)
35783
+ }
35164
35784
 
35165
- if (code === null) {
35166
- return tableClose(code)
35785
+ /**
35786
+ * After delimiter cell.
35787
+ *
35788
+ * ```markdown
35789
+ * | | a |
35790
+ * > | | -: |
35791
+ * ^
35792
+ * ```
35793
+ *
35794
+ * @type {State}
35795
+ */
35796
+ function headDelimiterCellAfter(code) {
35797
+ if (code === 124) {
35798
+ return headDelimiterBefore(code)
35167
35799
  }
35168
-
35169
- return effects.check(
35170
- nextPrefixedOrBlank,
35171
- tableClose,
35172
- effects.attempt(
35173
- {
35174
- tokenize: tokenizeRowEnd,
35175
- partial: true
35176
- },
35177
- factorySpace(effects, bodyStart, 'linePrefix', 4),
35178
- tableClose
35179
- )
35180
- )(code)
35800
+ if (code === null || markdownLineEnding(code)) {
35801
+ // Exit when:
35802
+ // * there was no `:` or `|` at all (it’s a thematic break or setext
35803
+ // underline instead)
35804
+ // * the header cell count is not the delimiter cell count
35805
+ if (!seen || size !== sizeB) {
35806
+ return headDelimiterNok(code)
35807
+ }
35808
+
35809
+ // Note: in markdown-rs`, a reset is needed here.
35810
+ effects.exit('tableDelimiterRow')
35811
+ effects.exit('tableHead')
35812
+ // To do: in `markdown-rs`, resolvers need to be registered manually.
35813
+ // effects.register_resolver(ResolveName::GfmTable)
35814
+ return ok(code)
35815
+ }
35816
+ return headDelimiterNok(code)
35181
35817
  }
35182
- /** @type {State} */
35183
35818
 
35184
- function tableClose(code) {
35185
- effects.exit('table')
35186
- return ok(code)
35819
+ /**
35820
+ * In delimiter row, at a disallowed byte.
35821
+ *
35822
+ * ```markdown
35823
+ * | | a |
35824
+ * > | | x |
35825
+ * ^
35826
+ * ```
35827
+ *
35828
+ * @type {State}
35829
+ */
35830
+ function headDelimiterNok(code) {
35831
+ // Note: in `markdown-rs`, we need to reset, in `micromark-js` we don‘t.
35832
+ return nok(code)
35187
35833
  }
35188
- /** @type {State} */
35189
35834
 
35190
- function bodyStart(code) {
35191
- effects.enter('tableBody')
35192
- return rowStartBody(code)
35835
+ /**
35836
+ * Before table body row.
35837
+ *
35838
+ * ```markdown
35839
+ * | | a |
35840
+ * | | - |
35841
+ * > | | b |
35842
+ * ^
35843
+ * ```
35844
+ *
35845
+ * @type {State}
35846
+ */
35847
+ function bodyRowStart(code) {
35848
+ // Note: in `markdown-rs` we need to manually take care of a prefix,
35849
+ // but in `micromark-js` that is done for us, so if we’re here, we’re
35850
+ // never at whitespace.
35851
+ effects.enter('tableRow')
35852
+ return bodyRowBreak(code)
35193
35853
  }
35194
- /** @type {State} */
35195
-
35196
- function rowStartBody(code) {
35197
- effects.enter('tableRow') // If we start with a pipe, we open a cell marker.
35198
35854
 
35855
+ /**
35856
+ * At break in table body row.
35857
+ *
35858
+ * ```markdown
35859
+ * | | a |
35860
+ * | | - |
35861
+ * > | | b |
35862
+ * ^
35863
+ * ^
35864
+ * ^
35865
+ * ```
35866
+ *
35867
+ * @type {State}
35868
+ */
35869
+ function bodyRowBreak(code) {
35199
35870
  if (code === 124) {
35200
- return cellDividerBody(code)
35871
+ effects.enter('tableCellDivider')
35872
+ effects.consume(code)
35873
+ effects.exit('tableCellDivider')
35874
+ return bodyRowBreak
35201
35875
  }
35202
-
35203
- effects.enter('temporaryTableCellContent') // Can’t be space or eols at the start of a construct, so we’re in a cell.
35204
-
35205
- return inCellContentBody(code)
35206
- }
35207
- /** @type {State} */
35208
-
35209
- function cellDividerBody(code) {
35210
- effects.enter('tableCellDivider')
35211
- effects.consume(code)
35212
- effects.exit('tableCellDivider')
35213
- return cellBreakBody
35214
- }
35215
- /** @type {State} */
35216
-
35217
- function cellBreakBody(code) {
35218
35876
  if (code === null || markdownLineEnding(code)) {
35219
- return atRowEndBody(code)
35877
+ effects.exit('tableRow')
35878
+ return ok(code)
35220
35879
  }
35221
-
35222
35880
  if (markdownSpace(code)) {
35223
- effects.enter('whitespace')
35224
- effects.consume(code)
35225
- return inWhitespaceBody
35226
- } // `|`
35227
-
35228
- if (code === 124) {
35229
- return cellDividerBody(code)
35230
- } // Anything else is cell content.
35231
-
35232
- effects.enter('temporaryTableCellContent')
35233
- return inCellContentBody(code)
35234
- }
35235
- /** @type {State} */
35236
-
35237
- function inWhitespaceBody(code) {
35238
- if (markdownSpace(code)) {
35239
- effects.consume(code)
35240
- return inWhitespaceBody
35881
+ return factorySpace(effects, bodyRowBreak, 'whitespace')(code)
35241
35882
  }
35242
35883
 
35243
- effects.exit('whitespace')
35244
- return cellBreakBody(code)
35884
+ // Anything else is cell content.
35885
+ effects.enter('data')
35886
+ return bodyRowData(code)
35245
35887
  }
35246
- /** @type {State} */
35247
35888
 
35248
- function inCellContentBody(code) {
35249
- // EOF, whitespace, pipe
35889
+ /**
35890
+ * In table body row data.
35891
+ *
35892
+ * ```markdown
35893
+ * | | a |
35894
+ * | | - |
35895
+ * > | | b |
35896
+ * ^
35897
+ * ```
35898
+ *
35899
+ * @type {State}
35900
+ */
35901
+ function bodyRowData(code) {
35250
35902
  if (code === null || code === 124 || markdownLineEndingOrSpace(code)) {
35251
- effects.exit('temporaryTableCellContent')
35252
- return cellBreakBody(code)
35903
+ effects.exit('data')
35904
+ return bodyRowBreak(code)
35253
35905
  }
35254
-
35255
35906
  effects.consume(code)
35256
- return code === 92 ? inCellContentEscapeBody : inCellContentBody
35907
+ return code === 92 ? bodyRowEscape : bodyRowData
35257
35908
  }
35258
- /** @type {State} */
35259
35909
 
35260
- function inCellContentEscapeBody(code) {
35910
+ /**
35911
+ * In table body row escape.
35912
+ *
35913
+ * ```markdown
35914
+ * | | a |
35915
+ * | | ---- |
35916
+ * > | | b\-c |
35917
+ * ^
35918
+ * ```
35919
+ *
35920
+ * @type {State}
35921
+ */
35922
+ function bodyRowEscape(code) {
35261
35923
  if (code === 92 || code === 124) {
35262
35924
  effects.consume(code)
35263
- return inCellContentBody
35264
- } // Anything else.
35265
-
35266
- return inCellContentBody(code)
35267
- }
35268
- /** @type {State} */
35269
-
35270
- function atRowEndBody(code) {
35271
- effects.exit('tableRow')
35272
-
35273
- if (code === null) {
35274
- return tableBodyClose(code)
35925
+ return bodyRowData
35275
35926
  }
35276
-
35277
- return effects.check(
35278
- nextPrefixedOrBlank,
35279
- tableBodyClose,
35280
- effects.attempt(
35281
- {
35282
- tokenize: tokenizeRowEnd,
35283
- partial: true
35284
- },
35285
- factorySpace(effects, rowStartBody, 'linePrefix', 4),
35286
- tableBodyClose
35287
- )
35288
- )(code)
35927
+ return bodyRowData(code)
35289
35928
  }
35290
- /** @type {State} */
35291
-
35292
- function tableBodyClose(code) {
35293
- effects.exit('tableBody')
35294
- return tableClose(code)
35295
- }
35296
- /** @type {Tokenizer} */
35929
+ }
35297
35930
 
35298
- function tokenizeRowEnd(effects, ok, nok) {
35299
- return start
35300
- /** @type {State} */
35931
+ /** @type {Resolver} */
35932
+ // eslint-disable-next-line complexity
35933
+ function resolveTable(events, context) {
35934
+ let index = -1
35935
+ let inFirstCellAwaitingPipe = true
35936
+ /** @type {RowKind} */
35937
+ let rowKind = 0
35938
+ /** @type {Range} */
35939
+ let lastCell = [0, 0, 0, 0]
35940
+ /** @type {Range} */
35941
+ let cell = [0, 0, 0, 0]
35942
+ let afterHeadAwaitingFirstBodyRow = false
35943
+ let lastTableEnd = 0
35944
+ /** @type {Token | undefined} */
35945
+ let currentTable
35946
+ /** @type {Token | undefined} */
35947
+ let currentBody
35948
+ /** @type {Token | undefined} */
35949
+ let currentCell
35950
+ const map = new EditMap()
35951
+ while (++index < events.length) {
35952
+ const event = events[index]
35953
+ const token = event[1]
35954
+ if (event[0] === 'enter') {
35955
+ // Start of head.
35956
+ if (token.type === 'tableHead') {
35957
+ afterHeadAwaitingFirstBodyRow = false
35301
35958
 
35302
- function start(code) {
35303
- effects.enter('lineEnding')
35304
- effects.consume(code)
35305
- effects.exit('lineEnding')
35306
- return factorySpace(effects, prefixed, 'linePrefix')
35307
- }
35308
- /** @type {State} */
35959
+ // Inject previous (body end and) table end.
35960
+ if (lastTableEnd !== 0) {
35961
+ flushTableEnd(map, context, lastTableEnd, currentTable, currentBody)
35962
+ currentBody = undefined
35963
+ lastTableEnd = 0
35964
+ }
35309
35965
 
35310
- function prefixed(code) {
35311
- // Blank or interrupting line.
35312
- if (
35313
- self.parser.lazy[self.now().line] ||
35314
- code === null ||
35315
- markdownLineEnding(code)
35966
+ // Inject table start.
35967
+ currentTable = {
35968
+ type: 'table',
35969
+ start: Object.assign({}, token.start),
35970
+ // Note: correct end is set later.
35971
+ end: Object.assign({}, token.end)
35972
+ }
35973
+ map.add(index, 0, [['enter', currentTable, context]])
35974
+ } else if (
35975
+ token.type === 'tableRow' ||
35976
+ token.type === 'tableDelimiterRow'
35316
35977
  ) {
35317
- return nok(code)
35978
+ inFirstCellAwaitingPipe = true
35979
+ currentCell = undefined
35980
+ lastCell = [0, 0, 0, 0]
35981
+ cell = [0, index + 1, 0, 0]
35982
+
35983
+ // Inject table body start.
35984
+ if (afterHeadAwaitingFirstBodyRow) {
35985
+ afterHeadAwaitingFirstBodyRow = false
35986
+ currentBody = {
35987
+ type: 'tableBody',
35988
+ start: Object.assign({}, token.start),
35989
+ // Note: correct end is set later.
35990
+ end: Object.assign({}, token.end)
35991
+ }
35992
+ map.add(index, 0, [['enter', currentBody, context]])
35993
+ }
35994
+ rowKind = token.type === 'tableDelimiterRow' ? 2 : currentBody ? 3 : 1
35318
35995
  }
35319
-
35320
- const tail = self.events[self.events.length - 1] // Indented code can interrupt delimiter and body rows.
35321
-
35322
- if (
35323
- !self.parser.constructs.disable.null.includes('codeIndented') &&
35324
- tail &&
35325
- tail[1].type === 'linePrefix' &&
35326
- tail[2].sliceSerialize(tail[1], true).length >= 4
35996
+ // Cell data.
35997
+ else if (
35998
+ rowKind &&
35999
+ (token.type === 'data' ||
36000
+ token.type === 'tableDelimiterMarker' ||
36001
+ token.type === 'tableDelimiterFiller')
35327
36002
  ) {
35328
- return nok(code)
36003
+ inFirstCellAwaitingPipe = false
36004
+
36005
+ // First value in cell.
36006
+ if (cell[2] === 0) {
36007
+ if (lastCell[1] !== 0) {
36008
+ cell[0] = cell[1]
36009
+ currentCell = flushCell(
36010
+ map,
36011
+ context,
36012
+ lastCell,
36013
+ rowKind,
36014
+ undefined,
36015
+ currentCell
36016
+ )
36017
+ lastCell = [0, 0, 0, 0]
36018
+ }
36019
+ cell[2] = index
36020
+ }
36021
+ } else if (token.type === 'tableCellDivider') {
36022
+ if (inFirstCellAwaitingPipe) {
36023
+ inFirstCellAwaitingPipe = false
36024
+ } else {
36025
+ if (lastCell[1] !== 0) {
36026
+ cell[0] = cell[1]
36027
+ currentCell = flushCell(
36028
+ map,
36029
+ context,
36030
+ lastCell,
36031
+ rowKind,
36032
+ undefined,
36033
+ currentCell
36034
+ )
36035
+ }
36036
+ lastCell = cell
36037
+ cell = [lastCell[1], index, 0, 0]
36038
+ }
35329
36039
  }
36040
+ }
36041
+ // Exit events.
36042
+ else if (token.type === 'tableHead') {
36043
+ afterHeadAwaitingFirstBodyRow = true
36044
+ lastTableEnd = index
36045
+ } else if (
36046
+ token.type === 'tableRow' ||
36047
+ token.type === 'tableDelimiterRow'
36048
+ ) {
36049
+ lastTableEnd = index
36050
+ if (lastCell[1] !== 0) {
36051
+ cell[0] = cell[1]
36052
+ currentCell = flushCell(
36053
+ map,
36054
+ context,
36055
+ lastCell,
36056
+ rowKind,
36057
+ index,
36058
+ currentCell
36059
+ )
36060
+ } else if (cell[1] !== 0) {
36061
+ currentCell = flushCell(map, context, cell, rowKind, index, currentCell)
36062
+ }
36063
+ rowKind = 0
36064
+ } else if (
36065
+ rowKind &&
36066
+ (token.type === 'data' ||
36067
+ token.type === 'tableDelimiterMarker' ||
36068
+ token.type === 'tableDelimiterFiller')
36069
+ ) {
36070
+ cell[3] = index
36071
+ }
36072
+ }
36073
+ if (lastTableEnd !== 0) {
36074
+ flushTableEnd(map, context, lastTableEnd, currentTable, currentBody)
36075
+ }
36076
+ map.consume(context.events)
35330
36077
 
35331
- self._gfmTableDynamicInterruptHack = true
35332
- return effects.check(
35333
- self.parser.constructs.flow,
35334
- function (code) {
35335
- self._gfmTableDynamicInterruptHack = false
35336
- return nok(code)
35337
- },
35338
- function (code) {
35339
- self._gfmTableDynamicInterruptHack = false
35340
- return ok(code)
35341
- }
35342
- )(code)
36078
+ // To do: move this into `html`, when events are exposed there.
36079
+ // That’s what `markdown-rs` does.
36080
+ // That needs updates to `mdast-util-gfm-table`.
36081
+ index = -1
36082
+ while (++index < context.events.length) {
36083
+ const event = context.events[index]
36084
+ if (event[0] === 'enter' && event[1].type === 'table') {
36085
+ // @ts-expect-error: custom field.
36086
+ event[1]._align = gfmTableAlign(context.events, index)
35343
36087
  }
35344
36088
  }
36089
+ return events
35345
36090
  }
35346
- /** @type {Tokenizer} */
35347
-
35348
- function tokenizeNextPrefixedOrBlank(effects, ok, nok) {
35349
- let size = 0
35350
- return start
35351
- /** @type {State} */
35352
-
35353
- function start(code) {
35354
- // This is a check, so we don’t care about tokens, but we open a bogus one
35355
- // so we’re valid.
35356
- effects.enter('check') // EOL.
35357
36091
 
35358
- effects.consume(code)
35359
- return whitespace
36092
+ /// Generate a cell.
36093
+ /**
36094
+ *
36095
+ * @param {EditMap} map
36096
+ * @param {TokenizeContext} context
36097
+ * @param {Range} range
36098
+ * @param {RowKind} rowKind
36099
+ * @param {number | undefined} rowEnd
36100
+ * @param {Token | undefined} previousCell
36101
+ * @returns {Token | undefined}
36102
+ */
36103
+ // eslint-disable-next-line max-params
36104
+ function flushCell(map, context, range, rowKind, rowEnd, previousCell) {
36105
+ // `markdown-rs` uses:
36106
+ // rowKind === 2 ? 'tableDelimiterCell' : 'tableCell'
36107
+ const groupName =
36108
+ rowKind === 1
36109
+ ? 'tableHeader'
36110
+ : rowKind === 2
36111
+ ? 'tableDelimiter'
36112
+ : 'tableData'
36113
+ // `markdown-rs` uses:
36114
+ // rowKind === 2 ? 'tableDelimiterCellValue' : 'tableCellText'
36115
+ const valueName = 'tableContent'
36116
+
36117
+ // Insert an exit for the previous cell, if there is one.
36118
+ //
36119
+ // ```markdown
36120
+ // > | | aa | bb | cc |
36121
+ // ^-- exit
36122
+ // ^^^^-- this cell
36123
+ // ```
36124
+ if (range[0] !== 0) {
36125
+ previousCell.end = Object.assign({}, getPoint(context.events, range[0]))
36126
+ map.add(range[0], 0, [['exit', previousCell, context]])
35360
36127
  }
35361
- /** @type {State} */
35362
36128
 
35363
- function whitespace(code) {
35364
- if (code === -1 || code === 32) {
35365
- effects.consume(code)
35366
- size++
35367
- return size === 4 ? ok : whitespace
35368
- } // EOF or whitespace
36129
+ // Insert enter of this cell.
36130
+ //
36131
+ // ```markdown
36132
+ // > | | aa | bb | cc |
36133
+ // ^-- enter
36134
+ // ^^^^-- this cell
36135
+ // ```
36136
+ const now = getPoint(context.events, range[1])
36137
+ previousCell = {
36138
+ type: groupName,
36139
+ start: Object.assign({}, now),
36140
+ // Note: correct end is set later.
36141
+ end: Object.assign({}, now)
36142
+ }
36143
+ map.add(range[1], 0, [['enter', previousCell, context]])
35369
36144
 
35370
- if (code === null || markdownLineEndingOrSpace(code)) {
35371
- return ok(code)
35372
- } // Anything else.
36145
+ // Insert text start at first data start and end at last data end, and
36146
+ // remove events between.
36147
+ //
36148
+ // ```markdown
36149
+ // > | | aa | bb | cc |
36150
+ // ^-- enter
36151
+ // ^-- exit
36152
+ // ^^^^-- this cell
36153
+ // ```
36154
+ if (range[2] !== 0) {
36155
+ const relatedStart = getPoint(context.events, range[2])
36156
+ const relatedEnd = getPoint(context.events, range[3])
36157
+ const valueToken = {
36158
+ type: valueName,
36159
+ start: Object.assign({}, relatedStart),
36160
+ end: Object.assign({}, relatedEnd)
36161
+ }
36162
+ map.add(range[2], 0, [['enter', valueToken, context]])
36163
+ if (rowKind !== 2) {
36164
+ // Fix positional info on remaining events
36165
+ const start = context.events[range[2]]
36166
+ const end = context.events[range[3]]
36167
+ start[1].end = Object.assign({}, end[1].end)
36168
+ start[1].type = 'chunkText'
36169
+ // @ts-expect-error It’s fine.
36170
+ start[1].contentType = 'text'
36171
+
36172
+ // Remove if needed.
36173
+ if (range[3] > range[2] + 1) {
36174
+ const a = range[2] + 1
36175
+ const b = range[3] - range[2] - 1
36176
+ map.add(a, b, [])
36177
+ }
36178
+ }
36179
+ map.add(range[3] + 1, 0, [['exit', valueToken, context]])
36180
+ }
36181
+
36182
+ // Insert an exit for the last cell, if at the row end.
36183
+ //
36184
+ // ```markdown
36185
+ // > | | aa | bb | cc |
36186
+ // ^-- exit
36187
+ // ^^^^^^-- this cell (the last one contains two “between” parts)
36188
+ // ```
36189
+ if (rowEnd !== undefined) {
36190
+ previousCell.end = Object.assign({}, getPoint(context.events, rowEnd))
36191
+ map.add(rowEnd, 0, [['exit', previousCell, context]])
36192
+ previousCell = undefined
36193
+ }
36194
+ return previousCell
36195
+ }
35373
36196
 
35374
- return nok(code)
36197
+ /**
36198
+ * Generate table end (and table body end).
36199
+ *
36200
+ * @param {EditMap} map
36201
+ * @param {TokenizeContext} context
36202
+ * @param {number} index
36203
+ * @param {Token} table
36204
+ * @param {Token | undefined} tableBody
36205
+ */
36206
+ // eslint-disable-next-line max-params
36207
+ function flushTableEnd(map, context, index, table, tableBody) {
36208
+ /** @type {Array<Event>} */
36209
+ const exits = []
36210
+ const related = getPoint(context.events, index)
36211
+ if (tableBody) {
36212
+ tableBody.end = Object.assign({}, related)
36213
+ exits.push(['exit', tableBody, context])
35375
36214
  }
36215
+ table.end = Object.assign({}, related)
36216
+ exits.push(['exit', table, context])
36217
+ map.add(index + 1, 0, exits)
36218
+ }
36219
+
36220
+ /**
36221
+ * @param {Array<Event>} events
36222
+ * @param {number} index
36223
+ * @returns {readonly Point}
36224
+ */
36225
+ function getPoint(events, index) {
36226
+ const event = events[index]
36227
+ const side = event[0] === 'enter' ? 'start' : 'end'
36228
+ return event[1][side]
35376
36229
  }
35377
36230
 
35378
36231
  ;// CONCATENATED MODULE: ../node_modules/micromark-extension-gfm-task-list-item/lib/syntax.js
@@ -35542,10 +36395,10 @@ function spaceThenNonSpace(effects, ok, nok) {
35542
36395
 
35543
36396
  ;// CONCATENATED MODULE: ../node_modules/micromark-extension-gfm/index.js
35544
36397
  /**
36398
+ * @typedef {import('micromark-extension-gfm-footnote').HtmlOptions} HtmlOptions
36399
+ * @typedef {import('micromark-extension-gfm-strikethrough').Options} Options
35545
36400
  * @typedef {import('micromark-util-types').Extension} Extension
35546
36401
  * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension
35547
- * @typedef {import('micromark-extension-gfm-strikethrough').Options} Options
35548
- * @typedef {import('micromark-extension-gfm-footnote').HtmlOptions} HtmlOptions
35549
36402
  */
35550
36403
 
35551
36404
 
@@ -35557,10 +36410,15 @@ function spaceThenNonSpace(effects, ok, nok) {
35557
36410
 
35558
36411
 
35559
36412
  /**
35560
- * Support GFM or markdown on github.com.
36413
+ * Create an extension for `micromark` to enable GFM syntax.
35561
36414
  *
35562
- * @param {Options} [options]
36415
+ * @param {Options | null | undefined} [options]
36416
+ * Configuration (optional).
36417
+ *
36418
+ * Passed to `micromark-extens-gfm-strikethrough`.
35563
36419
  * @returns {Extension}
36420
+ * Extension for `micromark` that can be passed in `extensions` to enable GFM
36421
+ * syntax.
35564
36422
  */
35565
36423
  function gfm(options) {
35566
36424
  return combineExtensions([
@@ -35573,10 +36431,15 @@ function gfm(options) {
35573
36431
  }
35574
36432
 
35575
36433
  /**
35576
- * Support to compile GFM to HTML.
36434
+ * Create an extension for `micromark` to support GFM when serializing to HTML.
36435
+ *
36436
+ * @param {HtmlOptions | null | undefined} [options]
36437
+ * Configuration.
35577
36438
  *
35578
- * @param {HtmlOptions} [options]
36439
+ * Passed to `micromark-extens-gfm-footnote`.
35579
36440
  * @returns {HtmlExtension}
36441
+ * Extension for `micromark` that can be passed in `htmlExtensions` to
36442
+ * support GFM when serializing to HTML.
35580
36443
  */
35581
36444
  function gfmHtml(options) {
35582
36445
  return combineHtmlExtensions([
@@ -73337,7 +74200,7 @@ var commands_getCommands=function getCommands(){return[bold,italic,strikeThrough
73337
74200
  */_createClass(TextAreaTextApi,[{key:"replaceSelection",value:function replaceSelection(text){insertTextAtPosition(this.textArea,text);return getStateFromTextArea(this.textArea);}/**
73338
74201
  * Selects the specified text range
73339
74202
  * @param selection
73340
- */},{key:"setSelectionRange",value:function setSelectionRange(selection){this.textArea.focus();this.textArea.selectionStart=selection.start;this.textArea.selectionEnd=selection.end;return getStateFromTextArea(this.textArea);}}]);return TextAreaTextApi;}();var TextAreaCommandOrchestrator=/*#__PURE__*/function(){function TextAreaCommandOrchestrator(textArea){_classCallCheck(this,TextAreaCommandOrchestrator);this.textArea=void 0;this.textApi=void 0;this.textArea=textArea;this.textApi=new TextAreaTextApi(textArea);}_createClass(TextAreaCommandOrchestrator,[{key:"getState",value:function getState(){if(!this.textArea)return false;return getStateFromTextArea(this.textArea);}},{key:"executeCommand",value:function executeCommand(command,dispatch,state,shortcuts){command.execute&&command.execute(_objectSpread2({command:command},getStateFromTextArea(this.textArea)),this.textApi,dispatch,state,shortcuts);}}]);return TextAreaCommandOrchestrator;}();
74203
+ */},{key:"setSelectionRange",value:function setSelectionRange(selection){this.textArea.focus();this.textArea.selectionStart=selection.start;this.textArea.selectionEnd=selection.end;return getStateFromTextArea(this.textArea);}}]);return TextAreaTextApi;}();var TextAreaCommandOrchestrator=/*#__PURE__*/function(){function TextAreaCommandOrchestrator(textArea){_classCallCheck(this,TextAreaCommandOrchestrator);this.textArea=void 0;this.textApi=void 0;this.textArea=textArea;this.textApi=new TextAreaTextApi(textArea);}_createClass(TextAreaCommandOrchestrator,[{key:"getState",value:function getState(){if(!this.textArea)return false;return getStateFromTextArea(this.textArea);}},{key:"executeCommand",value:function executeCommand(command,dispatch,state,shortcuts){console.log('state:',state);command.execute&&command.execute(_objectSpread2({command:command},getStateFromTextArea(this.textArea)),this.textApi,dispatch,state,shortcuts);}}]);return TextAreaCommandOrchestrator;}();
73341
74204
  ;// CONCATENATED MODULE: ./src/components/TextArea/handleKeyDown.tsx
73342
74205
  /**
73343
74206
  * - `13` - `Enter`
@@ -73351,8 +74214,8 @@ var commands_getCommands=function getCommands(){return[bold,italic,strikeThrough
73351
74214
  // extracted by mini-css-extract-plugin
73352
74215
  /* harmony default export */ const TextArea = ({});
73353
74216
  ;// CONCATENATED MODULE: ./src/components/TextArea/Textarea.tsx
73354
- var Textarea_excluded=["prefixCls","onChange"];function Textarea(props){var prefixCls=props.prefixCls,_onChange=props.onChange,other=_objectWithoutProperties(props,Textarea_excluded);var _useContext=(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useContext)(EditorContext),markdown=_useContext.markdown,commands=_useContext.commands,fullscreen=_useContext.fullscreen,preview=_useContext.preview,highlightEnable=_useContext.highlightEnable,extraCommands=_useContext.extraCommands,tabSize=_useContext.tabSize,defaultTabEnable=_useContext.defaultTabEnable,dispatch=_useContext.dispatch;var textRef=external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef(null);var executeRef=external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef();var statesRef=external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef({fullscreen:fullscreen,preview:preview});(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useEffect)(function(){statesRef.current={fullscreen:fullscreen,preview:preview,highlightEnable:highlightEnable};},[fullscreen,preview,highlightEnable]);(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useEffect)(function(){if(textRef.current&&dispatch){var commandOrchestrator=new TextAreaCommandOrchestrator(textRef.current);executeRef.current=commandOrchestrator;dispatch({textarea:textRef.current,commandOrchestrator:commandOrchestrator});}// eslint-disable-next-line react-hooks/exhaustive-deps
73355
- },[]);var onKeyDown=function onKeyDown(e){handleKeyDown(e,tabSize,defaultTabEnable);shortcutsHandle(e,[].concat(_toConsumableArray(commands||[]),_toConsumableArray(extraCommands||[])),executeRef.current,dispatch,statesRef.current);};(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useEffect)(function(){if(textRef.current){textRef.current.addEventListener('keydown',onKeyDown);}return function(){if(textRef.current){// eslint-disable-next-line react-hooks/exhaustive-deps
74217
+ var Textarea_excluded=["prefixCls","onChange"],_excluded2=["markdown","commands","fullscreen","preview","highlightEnable","extraCommands","tabSize","defaultTabEnable","dispatch"];function Textarea(props){var prefixCls=props.prefixCls,_onChange=props.onChange,other=_objectWithoutProperties(props,Textarea_excluded);var _useContext=(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useContext)(EditorContext),markdown=_useContext.markdown,commands=_useContext.commands,fullscreen=_useContext.fullscreen,preview=_useContext.preview,highlightEnable=_useContext.highlightEnable,extraCommands=_useContext.extraCommands,tabSize=_useContext.tabSize,defaultTabEnable=_useContext.defaultTabEnable,dispatch=_useContext.dispatch,otherStore=_objectWithoutProperties(_useContext,_excluded2);var textRef=external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef(null);var executeRef=external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef();var statesRef=external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef({fullscreen:fullscreen,preview:preview});(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useEffect)(function(){statesRef.current={fullscreen:fullscreen,preview:preview,highlightEnable:highlightEnable};},[fullscreen,preview,highlightEnable]);(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useEffect)(function(){if(textRef.current&&dispatch){var commandOrchestrator=new TextAreaCommandOrchestrator(textRef.current);executeRef.current=commandOrchestrator;dispatch({textarea:textRef.current,commandOrchestrator:commandOrchestrator});}// eslint-disable-next-line react-hooks/exhaustive-deps
74218
+ },[]);var onKeyDown=function onKeyDown(e){handleKeyDown(e,tabSize,defaultTabEnable);console.log('otherStore:',otherStore);shortcutsHandle(e,[].concat(_toConsumableArray(commands||[]),_toConsumableArray(extraCommands||[])),executeRef.current,dispatch,statesRef.current);};(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useEffect)(function(){if(textRef.current){textRef.current.addEventListener('keydown',onKeyDown);}return function(){if(textRef.current){// eslint-disable-next-line react-hooks/exhaustive-deps
73356
74219
  textRef.current.removeEventListener('keydown',onKeyDown);}};// eslint-disable-next-line react-hooks/exhaustive-deps
73357
74220
  },[]);return/*#__PURE__*/(0,jsx_runtime.jsx)("textarea",_objectSpread2(_objectSpread2({autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",spellCheck:false},other),{},{ref:textRef,className:"".concat(prefixCls,"-text-input ").concat(other.className?other.className:''),value:markdown,onChange:function onChange(e){dispatch&&dispatch({markdown:e.target.value});_onChange&&_onChange(e);}}));}
73358
74221
  ;// CONCATENATED MODULE: ./src/components/TextArea/index.tsx
@@ -73372,7 +74235,7 @@ function Child_Child(props){var _ref=props||{},prefixCls=_ref.prefixCls,groupNam
73372
74235
  function ToolbarItems(props){var prefixCls=props.prefixCls,overflow=props.overflow;var _useContext=(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useContext)(EditorContext),fullscreen=_useContext.fullscreen,preview=_useContext.preview,_useContext$barPopup=_useContext.barPopup,barPopup=_useContext$barPopup===void 0?{}:_useContext$barPopup,components=_useContext.components,commandOrchestrator=_useContext.commandOrchestrator,dispatch=_useContext.dispatch;var originalOverflow=(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)('');function handleClick(command,name){if(!dispatch)return;var state={barPopup:_objectSpread2({},barPopup)};if(command.keyCommand==='preview'){state.preview=command.value;}if(command.keyCommand==='fullscreen'){state.fullscreen=!fullscreen;}if(props.commands&&command.keyCommand==='group'){props.commands.forEach(function(item){if(name===item.groupName){state.barPopup[name]=true;}else if(item.keyCommand){state.barPopup[item.groupName]=false;}});}else if(name||command.parent){Object.keys(state.barPopup||{}).forEach(function(keyName){state.barPopup[keyName]=false;});}if(Object.keys(state).length){dispatch(_objectSpread2({},state));}commandOrchestrator&&commandOrchestrator.executeCommand(command);}(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useEffect)(function(){if(document&&overflow){if(fullscreen){// prevent scroll on fullscreen
73373
74236
  document.body.style.overflow='hidden';}else{// get the original overflow only the first time
73374
74237
  if(!originalOverflow.current){originalOverflow.current=window.getComputedStyle(document.body,null).overflow;}// reset to the original overflow
73375
- document.body.style.overflow=originalOverflow.current;}}},[fullscreen,originalOverflow,overflow]);return/*#__PURE__*/(0,jsx_runtime.jsx)("ul",{children:(props.commands||[]).map(function(item,idx){if(item.keyCommand==='divider'){return/*#__PURE__*/(0,jsx_runtime.jsx)("li",_objectSpread2(_objectSpread2({},item.liProps),{},{className:"".concat(prefixCls,"-toolbar-divider")}),idx);}if(!item.keyCommand)return/*#__PURE__*/(0,jsx_runtime.jsx)(external_root_React_commonjs2_react_commonjs_react_amd_react_.Fragment,{},idx);var activeBtn=fullscreen&&item.keyCommand==='fullscreen'||item.keyCommand==='preview'&&preview===item.value;var childNode=item.children&&typeof item.children==='function'?item.children({getState:function getState(){return commandOrchestrator.getState();},textApi:commandOrchestrator?commandOrchestrator.textApi:undefined,close:function close(){return handleClick({},item.groupName);},execute:function execute(){return handleClick({execute:item.execute});}}):undefined;var disabled=barPopup&&preview&&preview==='preview'&&!/(preview|fullscreen)/.test(item.keyCommand);var render=(components===null||components===void 0?void 0:components.toolbar)||item.render;var com=render&&typeof render==='function'?render(item,!!disabled,handleClick,idx):null;return/*#__PURE__*/(0,jsx_runtime.jsxs)("li",_objectSpread2(_objectSpread2({},item.liProps),{},{className:activeBtn?"active":'',children:[com&&/*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().isValidElement(com)&&com,!com&&!item.buttonProps&&item.icon,!com&&item.buttonProps&&/*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement('button',_objectSpread2(_objectSpread2({type:'button',key:idx,disabled:disabled,'data-name':item.name},item.buttonProps),{},{onClick:function onClick(evn){evn.stopPropagation();handleClick(item,item.groupName);}}),item.icon),item.children&&/*#__PURE__*/(0,jsx_runtime.jsx)(Child_Child,{overflow:overflow,groupName:item.groupName,prefixCls:prefixCls,children:childNode,commands:Array.isArray(item.children)?item.children:undefined})]}),idx);})});}function Toolbar_Toolbar(){var props=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};var prefixCls=props.prefixCls,toolbarBottom=props.toolbarBottom,isChild=props.isChild;var _useContext2=(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useContext)(EditorContext),commands=_useContext2.commands,extraCommands=_useContext2.extraCommands;var bottomClassName=toolbarBottom?'bottom':'';return/*#__PURE__*/(0,jsx_runtime.jsxs)("div",{className:"".concat(prefixCls,"-toolbar ").concat(bottomClassName),children:[/*#__PURE__*/(0,jsx_runtime.jsx)(ToolbarItems,_objectSpread2(_objectSpread2({},props),{},{commands:props.commands||commands||[]})),!isChild&&/*#__PURE__*/(0,jsx_runtime.jsx)(ToolbarItems,_objectSpread2(_objectSpread2({},props),{},{commands:extraCommands||[]}))]});}
74238
+ document.body.style.overflow=originalOverflow.current;}}},[fullscreen,originalOverflow,overflow]);return/*#__PURE__*/(0,jsx_runtime.jsx)("ul",{children:(props.commands||[]).map(function(item,idx){if(item.keyCommand==='divider'){return/*#__PURE__*/(0,jsx_runtime.jsx)("li",_objectSpread2(_objectSpread2({},item.liProps),{},{className:"".concat(prefixCls,"-toolbar-divider")}),idx);}if(!item.keyCommand)return/*#__PURE__*/(0,jsx_runtime.jsx)(external_root_React_commonjs2_react_commonjs_react_amd_react_.Fragment,{},idx);var activeBtn=fullscreen&&item.keyCommand==='fullscreen'||item.keyCommand==='preview'&&preview===item.value;var childNode=item.children&&typeof item.children==='function'?item.children({getState:function getState(){return commandOrchestrator.getState();},textApi:commandOrchestrator?commandOrchestrator.textApi:undefined,close:function close(){return handleClick({},item.groupName);},execute:function execute(){return handleClick({execute:item.execute});},dispatch:dispatch}):undefined;var disabled=barPopup&&preview&&preview==='preview'&&!/(preview|fullscreen)/.test(item.keyCommand);var render=(components===null||components===void 0?void 0:components.toolbar)||item.render;var com=render&&typeof render==='function'?render(item,!!disabled,handleClick,idx):null;return/*#__PURE__*/(0,jsx_runtime.jsxs)("li",_objectSpread2(_objectSpread2({},item.liProps),{},{className:activeBtn?"active":'',children:[com&&/*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().isValidElement(com)&&com,!com&&!item.buttonProps&&item.icon,!com&&item.buttonProps&&/*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement('button',_objectSpread2(_objectSpread2({type:'button',key:idx,disabled:disabled,'data-name':item.name},item.buttonProps),{},{onClick:function onClick(evn){evn.stopPropagation();handleClick(item,item.groupName);}}),item.icon),item.children&&/*#__PURE__*/(0,jsx_runtime.jsx)(Child_Child,{overflow:overflow,groupName:item.groupName,prefixCls:prefixCls,children:childNode,commands:Array.isArray(item.children)?item.children:undefined})]}),idx);})});}function Toolbar_Toolbar(){var props=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};var prefixCls=props.prefixCls,toolbarBottom=props.toolbarBottom,isChild=props.isChild;var _useContext2=(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useContext)(EditorContext),commands=_useContext2.commands,extraCommands=_useContext2.extraCommands;var bottomClassName=toolbarBottom?'bottom':'';return/*#__PURE__*/(0,jsx_runtime.jsxs)("div",{className:"".concat(prefixCls,"-toolbar ").concat(bottomClassName),children:[/*#__PURE__*/(0,jsx_runtime.jsx)(ToolbarItems,_objectSpread2(_objectSpread2({},props),{},{commands:props.commands||commands||[]})),!isChild&&/*#__PURE__*/(0,jsx_runtime.jsx)(ToolbarItems,_objectSpread2(_objectSpread2({},props),{},{commands:extraCommands||[]}))]});}
73376
74239
  ;// CONCATENATED MODULE: ./src/components/DragBar/index.less
73377
74240
  // extracted by mini-css-extract-plugin
73378
74241
  /* harmony default export */ const DragBar = ({});