@uiw/react-md-editor 3.20.9 → 3.20.10
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 +668 -349
- package/dist/mdeditor.min.js +1 -1
- package/esm/index.d.ts +1 -0
- package/esm/index.js +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +12 -0
- package/package.json +1 -1
- package/src/index.tsx +1 -0
package/dist/mdeditor.js
CHANGED
|
@@ -17389,6 +17389,8 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
17389
17389
|
"group": () => (/* reexport */ group),
|
|
17390
17390
|
"hr": () => (/* reexport */ hr),
|
|
17391
17391
|
"image": () => (/* reexport */ commands_image_image),
|
|
17392
|
+
"insertAtLineStart": () => (/* reexport */ insertAtLineStart),
|
|
17393
|
+
"insertTextAtPosition": () => (/* reexport */ insertTextAtPosition),
|
|
17392
17394
|
"italic": () => (/* reexport */ italic),
|
|
17393
17395
|
"link": () => (/* reexport */ commands_link_link),
|
|
17394
17396
|
"orderedListCommand": () => (/* reexport */ orderedListCommand),
|
|
@@ -33434,17 +33436,19 @@ ReactMarkdown.propTypes = {
|
|
|
33434
33436
|
|
|
33435
33437
|
;// CONCATENATED MODULE: ../node_modules/micromark-extension-gfm-autolink-literal/lib/syntax.js
|
|
33436
33438
|
/**
|
|
33437
|
-
* @typedef {import('micromark-util-types').
|
|
33439
|
+
* @typedef {import('micromark-util-types').Code} Code
|
|
33438
33440
|
* @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord
|
|
33439
|
-
* @typedef {import('micromark-util-types').
|
|
33441
|
+
* @typedef {import('micromark-util-types').Event} Event
|
|
33442
|
+
* @typedef {import('micromark-util-types').Extension} Extension
|
|
33440
33443
|
* @typedef {import('micromark-util-types').Previous} Previous
|
|
33441
33444
|
* @typedef {import('micromark-util-types').State} State
|
|
33442
|
-
* @typedef {import('micromark-util-types').
|
|
33443
|
-
* @typedef {import('micromark-util-types').
|
|
33445
|
+
* @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext
|
|
33446
|
+
* @typedef {import('micromark-util-types').Tokenizer} Tokenizer
|
|
33444
33447
|
*/
|
|
33445
33448
|
|
|
33446
|
-
|
|
33447
|
-
|
|
33449
|
+
|
|
33450
|
+
const wwwPrefix = {
|
|
33451
|
+
tokenize: tokenizeWwwPrefix,
|
|
33448
33452
|
partial: true
|
|
33449
33453
|
}
|
|
33450
33454
|
const domain = {
|
|
@@ -33455,546 +33459,886 @@ const syntax_path = {
|
|
|
33455
33459
|
tokenize: tokenizePath,
|
|
33456
33460
|
partial: true
|
|
33457
33461
|
}
|
|
33458
|
-
const
|
|
33459
|
-
tokenize:
|
|
33462
|
+
const trail = {
|
|
33463
|
+
tokenize: tokenizeTrail,
|
|
33460
33464
|
partial: true
|
|
33461
33465
|
}
|
|
33462
|
-
const
|
|
33463
|
-
tokenize:
|
|
33466
|
+
const emailDomainDotTrail = {
|
|
33467
|
+
tokenize: tokenizeEmailDomainDotTrail,
|
|
33464
33468
|
partial: true
|
|
33465
33469
|
}
|
|
33466
33470
|
const wwwAutolink = {
|
|
33467
33471
|
tokenize: tokenizeWwwAutolink,
|
|
33468
33472
|
previous: previousWww
|
|
33469
33473
|
}
|
|
33470
|
-
const
|
|
33471
|
-
tokenize:
|
|
33472
|
-
previous:
|
|
33474
|
+
const protocolAutolink = {
|
|
33475
|
+
tokenize: tokenizeProtocolAutolink,
|
|
33476
|
+
previous: previousProtocol
|
|
33473
33477
|
}
|
|
33474
33478
|
const emailAutolink = {
|
|
33475
33479
|
tokenize: tokenizeEmailAutolink,
|
|
33476
33480
|
previous: previousEmail
|
|
33477
33481
|
}
|
|
33478
|
-
/** @type {ConstructRecord} */
|
|
33479
33482
|
|
|
33483
|
+
/** @type {ConstructRecord} */
|
|
33480
33484
|
const syntax_text = {}
|
|
33481
|
-
/** @type {Extension} */
|
|
33482
33485
|
|
|
33486
|
+
// To do: next major: expose functions that yields extension.
|
|
33487
|
+
|
|
33488
|
+
/**
|
|
33489
|
+
* Extension for `micromark` that can be passed in `extensions` to enable GFM
|
|
33490
|
+
* autolink literal syntax.
|
|
33491
|
+
*
|
|
33492
|
+
* @type {Extension}
|
|
33493
|
+
*/
|
|
33483
33494
|
const gfmAutolinkLiteral = {
|
|
33484
33495
|
text: syntax_text
|
|
33485
33496
|
}
|
|
33486
|
-
let syntax_code = 48
|
|
33497
|
+
let syntax_code = 48
|
|
33487
33498
|
|
|
33499
|
+
// Add alphanumerics.
|
|
33488
33500
|
while (syntax_code < 123) {
|
|
33489
33501
|
syntax_text[syntax_code] = emailAutolink
|
|
33490
33502
|
syntax_code++
|
|
33491
33503
|
if (syntax_code === 58) syntax_code = 65
|
|
33492
33504
|
else if (syntax_code === 91) syntax_code = 97
|
|
33493
33505
|
}
|
|
33494
|
-
|
|
33495
33506
|
syntax_text[43] = emailAutolink
|
|
33496
33507
|
syntax_text[45] = emailAutolink
|
|
33497
33508
|
syntax_text[46] = emailAutolink
|
|
33498
33509
|
syntax_text[95] = emailAutolink
|
|
33499
|
-
syntax_text[72] = [emailAutolink,
|
|
33500
|
-
syntax_text[104] = [emailAutolink,
|
|
33510
|
+
syntax_text[72] = [emailAutolink, protocolAutolink]
|
|
33511
|
+
syntax_text[104] = [emailAutolink, protocolAutolink]
|
|
33501
33512
|
syntax_text[87] = [emailAutolink, wwwAutolink]
|
|
33502
33513
|
syntax_text[119] = [emailAutolink, wwwAutolink]
|
|
33503
|
-
/** @type {Tokenizer} */
|
|
33504
33514
|
|
|
33515
|
+
// To do: perform email autolink literals on events, afterwards.
|
|
33516
|
+
// That’s where `markdown-rs` and `cmark-gfm` perform it.
|
|
33517
|
+
// It should look for `@`, then for atext backwards, and then for a label
|
|
33518
|
+
// forwards.
|
|
33519
|
+
// To do: `mailto:`, `xmpp:` protocol as prefix.
|
|
33520
|
+
|
|
33521
|
+
/**
|
|
33522
|
+
* Email autolink literal.
|
|
33523
|
+
*
|
|
33524
|
+
* ```markdown
|
|
33525
|
+
* > | a contact@example.org b
|
|
33526
|
+
* ^^^^^^^^^^^^^^^^^^^
|
|
33527
|
+
* ```
|
|
33528
|
+
*
|
|
33529
|
+
* @this {TokenizeContext}
|
|
33530
|
+
* @type {Tokenizer}
|
|
33531
|
+
*/
|
|
33505
33532
|
function tokenizeEmailAutolink(effects, ok, nok) {
|
|
33506
33533
|
const self = this
|
|
33534
|
+
/** @type {boolean | undefined} */
|
|
33535
|
+
let dot
|
|
33507
33536
|
/** @type {boolean} */
|
|
33508
|
-
|
|
33509
|
-
let hasDot
|
|
33510
|
-
/** @type {boolean|undefined} */
|
|
33511
|
-
|
|
33512
|
-
let hasDigitInLastSegment
|
|
33537
|
+
let data
|
|
33513
33538
|
return start
|
|
33514
|
-
/** @type {State} */
|
|
33515
33539
|
|
|
33540
|
+
/**
|
|
33541
|
+
* Start of email autolink literal.
|
|
33542
|
+
*
|
|
33543
|
+
* ```markdown
|
|
33544
|
+
* > | a contact@example.org b
|
|
33545
|
+
* ^
|
|
33546
|
+
* ```
|
|
33547
|
+
*
|
|
33548
|
+
* @type {State}
|
|
33549
|
+
*/
|
|
33516
33550
|
function start(code) {
|
|
33517
33551
|
if (
|
|
33518
33552
|
!gfmAtext(code) ||
|
|
33519
|
-
!previousEmail(self.previous) ||
|
|
33553
|
+
!previousEmail.call(self, self.previous) ||
|
|
33520
33554
|
previousUnbalanced(self.events)
|
|
33521
33555
|
) {
|
|
33522
33556
|
return nok(code)
|
|
33523
33557
|
}
|
|
33524
|
-
|
|
33525
33558
|
effects.enter('literalAutolink')
|
|
33526
33559
|
effects.enter('literalAutolinkEmail')
|
|
33527
33560
|
return atext(code)
|
|
33528
33561
|
}
|
|
33529
|
-
/** @type {State} */
|
|
33530
33562
|
|
|
33563
|
+
/**
|
|
33564
|
+
* In email atext.
|
|
33565
|
+
*
|
|
33566
|
+
* ```markdown
|
|
33567
|
+
* > | a contact@example.org b
|
|
33568
|
+
* ^
|
|
33569
|
+
* ```
|
|
33570
|
+
*
|
|
33571
|
+
* @type {State}
|
|
33572
|
+
*/
|
|
33531
33573
|
function atext(code) {
|
|
33532
33574
|
if (gfmAtext(code)) {
|
|
33533
33575
|
effects.consume(code)
|
|
33534
33576
|
return atext
|
|
33535
33577
|
}
|
|
33536
|
-
|
|
33537
33578
|
if (code === 64) {
|
|
33538
33579
|
effects.consume(code)
|
|
33539
|
-
return
|
|
33580
|
+
return emailDomain
|
|
33540
33581
|
}
|
|
33541
|
-
|
|
33542
33582
|
return nok(code)
|
|
33543
33583
|
}
|
|
33544
|
-
/** @type {State} */
|
|
33545
33584
|
|
|
33546
|
-
|
|
33585
|
+
/**
|
|
33586
|
+
* In email domain.
|
|
33587
|
+
*
|
|
33588
|
+
* The reference code is a bit overly complex as it handles the `@`, of which
|
|
33589
|
+
* there may be just one.
|
|
33590
|
+
* Source: <https://github.com/github/cmark-gfm/blob/ef1cfcb/extensions/autolink.c#L318>
|
|
33591
|
+
*
|
|
33592
|
+
* ```markdown
|
|
33593
|
+
* > | a contact@example.org b
|
|
33594
|
+
* ^
|
|
33595
|
+
* ```
|
|
33596
|
+
*
|
|
33597
|
+
* @type {State}
|
|
33598
|
+
*/
|
|
33599
|
+
function emailDomain(code) {
|
|
33600
|
+
// Dot followed by alphanumerical (not `-` or `_`).
|
|
33547
33601
|
if (code === 46) {
|
|
33548
|
-
return effects.check(
|
|
33549
|
-
|
|
33550
|
-
|
|
33551
|
-
|
|
33552
|
-
|
|
33602
|
+
return effects.check(
|
|
33603
|
+
emailDomainDotTrail,
|
|
33604
|
+
emailDomainAfter,
|
|
33605
|
+
emailDomainDot
|
|
33606
|
+
)(code)
|
|
33553
33607
|
}
|
|
33554
33608
|
|
|
33555
|
-
|
|
33556
|
-
|
|
33557
|
-
|
|
33558
|
-
}
|
|
33559
|
-
|
|
33609
|
+
// Alphanumerical, `-`, and `_`.
|
|
33610
|
+
if (code === 45 || code === 95 || asciiAlphanumeric(code)) {
|
|
33611
|
+
data = true
|
|
33560
33612
|
effects.consume(code)
|
|
33561
|
-
return
|
|
33613
|
+
return emailDomain
|
|
33562
33614
|
}
|
|
33563
33615
|
|
|
33564
|
-
|
|
33565
|
-
}
|
|
33566
|
-
/** @type {State} */
|
|
33616
|
+
// To do: `/` if xmpp.
|
|
33567
33617
|
|
|
33568
|
-
|
|
33569
|
-
|
|
33570
|
-
|
|
33571
|
-
|
|
33572
|
-
return
|
|
33618
|
+
// Note: normally we’d truncate trailing punctuation from the link.
|
|
33619
|
+
// However, email autolink literals cannot contain any of those markers,
|
|
33620
|
+
// except for `.`, but that can only occur if it isn’t trailing.
|
|
33621
|
+
// So we can ignore truncating!
|
|
33622
|
+
return emailDomainAfter(code)
|
|
33573
33623
|
}
|
|
33574
|
-
/** @type {State} */
|
|
33575
33624
|
|
|
33576
|
-
|
|
33625
|
+
/**
|
|
33626
|
+
* In email domain, on dot that is not a trail.
|
|
33627
|
+
*
|
|
33628
|
+
* ```markdown
|
|
33629
|
+
* > | a contact@example.org b
|
|
33630
|
+
* ^
|
|
33631
|
+
* ```
|
|
33632
|
+
*
|
|
33633
|
+
* @type {State}
|
|
33634
|
+
*/
|
|
33635
|
+
function emailDomainDot(code) {
|
|
33577
33636
|
effects.consume(code)
|
|
33578
|
-
|
|
33579
|
-
|
|
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)
|
|
33637
|
+
dot = true
|
|
33638
|
+
return emailDomain
|
|
33588
33639
|
}
|
|
33589
|
-
/** @type {State} */
|
|
33590
33640
|
|
|
33591
|
-
|
|
33592
|
-
|
|
33641
|
+
/**
|
|
33642
|
+
* After email domain.
|
|
33643
|
+
*
|
|
33644
|
+
* ```markdown
|
|
33645
|
+
* > | a contact@example.org b
|
|
33646
|
+
* ^
|
|
33647
|
+
* ```
|
|
33648
|
+
*
|
|
33649
|
+
* @type {State}
|
|
33650
|
+
*/
|
|
33651
|
+
function emailDomainAfter(code) {
|
|
33652
|
+
// Domain must not be empty, must include a dot, and must end in alphabetical.
|
|
33653
|
+
// Source: <https://github.com/github/cmark-gfm/blob/ef1cfcb/extensions/autolink.c#L332>.
|
|
33654
|
+
if (data && dot && asciiAlpha(self.previous)) {
|
|
33593
33655
|
effects.exit('literalAutolinkEmail')
|
|
33594
33656
|
effects.exit('literalAutolink')
|
|
33595
33657
|
return ok(code)
|
|
33596
33658
|
}
|
|
33597
|
-
|
|
33598
33659
|
return nok(code)
|
|
33599
33660
|
}
|
|
33600
33661
|
}
|
|
33601
|
-
/** @type {Tokenizer} */
|
|
33602
33662
|
|
|
33663
|
+
/**
|
|
33664
|
+
* `www` autolink literal.
|
|
33665
|
+
*
|
|
33666
|
+
* ```markdown
|
|
33667
|
+
* > | a www.example.org b
|
|
33668
|
+
* ^^^^^^^^^^^^^^^
|
|
33669
|
+
* ```
|
|
33670
|
+
*
|
|
33671
|
+
* @this {TokenizeContext}
|
|
33672
|
+
* @type {Tokenizer}
|
|
33673
|
+
*/
|
|
33603
33674
|
function tokenizeWwwAutolink(effects, ok, nok) {
|
|
33604
33675
|
const self = this
|
|
33605
|
-
return
|
|
33606
|
-
/** @type {State} */
|
|
33676
|
+
return wwwStart
|
|
33607
33677
|
|
|
33608
|
-
|
|
33678
|
+
/**
|
|
33679
|
+
* Start of www autolink literal.
|
|
33680
|
+
*
|
|
33681
|
+
* ```markdown
|
|
33682
|
+
* > | www.example.com/a?b#c
|
|
33683
|
+
* ^
|
|
33684
|
+
* ```
|
|
33685
|
+
*
|
|
33686
|
+
* @type {State}
|
|
33687
|
+
*/
|
|
33688
|
+
function wwwStart(code) {
|
|
33609
33689
|
if (
|
|
33610
33690
|
(code !== 87 && code !== 119) ||
|
|
33611
|
-
!previousWww(self.previous) ||
|
|
33691
|
+
!previousWww.call(self, self.previous) ||
|
|
33612
33692
|
previousUnbalanced(self.events)
|
|
33613
33693
|
) {
|
|
33614
33694
|
return nok(code)
|
|
33615
33695
|
}
|
|
33616
|
-
|
|
33617
33696
|
effects.enter('literalAutolink')
|
|
33618
|
-
effects.enter('literalAutolinkWww')
|
|
33619
|
-
//
|
|
33620
|
-
//
|
|
33621
|
-
|
|
33697
|
+
effects.enter('literalAutolinkWww')
|
|
33698
|
+
// Note: we *check*, so we can discard the `www.` we parsed.
|
|
33699
|
+
// If it worked, we consider it as a part of the domain.
|
|
33622
33700
|
return effects.check(
|
|
33623
|
-
|
|
33624
|
-
effects.attempt(domain, effects.attempt(syntax_path,
|
|
33701
|
+
wwwPrefix,
|
|
33702
|
+
effects.attempt(domain, effects.attempt(syntax_path, wwwAfter), nok),
|
|
33625
33703
|
nok
|
|
33626
33704
|
)(code)
|
|
33627
33705
|
}
|
|
33628
|
-
/** @type {State} */
|
|
33629
33706
|
|
|
33630
|
-
|
|
33707
|
+
/**
|
|
33708
|
+
* After a www autolink literal.
|
|
33709
|
+
*
|
|
33710
|
+
* ```markdown
|
|
33711
|
+
* > | www.example.com/a?b#c
|
|
33712
|
+
* ^
|
|
33713
|
+
* ```
|
|
33714
|
+
*
|
|
33715
|
+
* @type {State}
|
|
33716
|
+
*/
|
|
33717
|
+
function wwwAfter(code) {
|
|
33631
33718
|
effects.exit('literalAutolinkWww')
|
|
33632
33719
|
effects.exit('literalAutolink')
|
|
33633
33720
|
return ok(code)
|
|
33634
33721
|
}
|
|
33635
33722
|
}
|
|
33636
|
-
/** @type {Tokenizer} */
|
|
33637
33723
|
|
|
33638
|
-
|
|
33724
|
+
/**
|
|
33725
|
+
* Protocol autolink literal.
|
|
33726
|
+
*
|
|
33727
|
+
* ```markdown
|
|
33728
|
+
* > | a https://example.org b
|
|
33729
|
+
* ^^^^^^^^^^^^^^^^^^^
|
|
33730
|
+
* ```
|
|
33731
|
+
*
|
|
33732
|
+
* @this {TokenizeContext}
|
|
33733
|
+
* @type {Tokenizer}
|
|
33734
|
+
*/
|
|
33735
|
+
function tokenizeProtocolAutolink(effects, ok, nok) {
|
|
33639
33736
|
const self = this
|
|
33640
|
-
|
|
33641
|
-
|
|
33737
|
+
let buffer = ''
|
|
33738
|
+
let seen = false
|
|
33739
|
+
return protocolStart
|
|
33642
33740
|
|
|
33643
|
-
|
|
33741
|
+
/**
|
|
33742
|
+
* Start of protocol autolink literal.
|
|
33743
|
+
*
|
|
33744
|
+
* ```markdown
|
|
33745
|
+
* > | https://example.com/a?b#c
|
|
33746
|
+
* ^
|
|
33747
|
+
* ```
|
|
33748
|
+
*
|
|
33749
|
+
* @type {State}
|
|
33750
|
+
*/
|
|
33751
|
+
function protocolStart(code) {
|
|
33644
33752
|
if (
|
|
33645
|
-
(code
|
|
33646
|
-
|
|
33647
|
-
previousUnbalanced(self.events)
|
|
33753
|
+
(code === 72 || code === 104) &&
|
|
33754
|
+
previousProtocol.call(self, self.previous) &&
|
|
33755
|
+
!previousUnbalanced(self.events)
|
|
33648
33756
|
) {
|
|
33649
|
-
|
|
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) {
|
|
33757
|
+
effects.enter('literalAutolink')
|
|
33758
|
+
effects.enter('literalAutolinkHttp')
|
|
33759
|
+
buffer += String.fromCodePoint(code)
|
|
33661
33760
|
effects.consume(code)
|
|
33662
|
-
return
|
|
33761
|
+
return protocolPrefixInside
|
|
33663
33762
|
}
|
|
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
33763
|
return nok(code)
|
|
33676
33764
|
}
|
|
33677
|
-
/** @type {State} */
|
|
33678
|
-
|
|
33679
|
-
function p(code) {
|
|
33680
|
-
if (code === 80 || code === 112) {
|
|
33681
|
-
effects.consume(code)
|
|
33682
|
-
return s
|
|
33683
|
-
}
|
|
33684
|
-
|
|
33685
|
-
return nok(code)
|
|
33686
|
-
}
|
|
33687
|
-
/** @type {State} */
|
|
33688
33765
|
|
|
33689
|
-
|
|
33690
|
-
|
|
33766
|
+
/**
|
|
33767
|
+
* In protocol.
|
|
33768
|
+
*
|
|
33769
|
+
* ```markdown
|
|
33770
|
+
* > | https://example.com/a?b#c
|
|
33771
|
+
* ^^^^^
|
|
33772
|
+
* ```
|
|
33773
|
+
*
|
|
33774
|
+
* @type {State}
|
|
33775
|
+
*/
|
|
33776
|
+
function protocolPrefixInside(code) {
|
|
33777
|
+
// `5` is size of `https`
|
|
33778
|
+
if (asciiAlpha(code) && buffer.length < 5) {
|
|
33779
|
+
buffer += String.fromCodePoint(code)
|
|
33691
33780
|
effects.consume(code)
|
|
33692
|
-
return
|
|
33781
|
+
return protocolPrefixInside
|
|
33693
33782
|
}
|
|
33694
|
-
|
|
33695
|
-
return colon(code)
|
|
33696
|
-
}
|
|
33697
|
-
/** @type {State} */
|
|
33698
|
-
|
|
33699
|
-
function colon(code) {
|
|
33700
33783
|
if (code === 58) {
|
|
33701
|
-
|
|
33702
|
-
|
|
33703
|
-
|
|
33704
|
-
|
|
33705
|
-
|
|
33706
|
-
}
|
|
33707
|
-
/** @type {State} */
|
|
33708
|
-
|
|
33709
|
-
function slash1(code) {
|
|
33710
|
-
if (code === 47) {
|
|
33711
|
-
effects.consume(code)
|
|
33712
|
-
return slash2
|
|
33784
|
+
const protocol = buffer.toLowerCase()
|
|
33785
|
+
if (protocol === 'http' || protocol === 'https') {
|
|
33786
|
+
effects.consume(code)
|
|
33787
|
+
return protocolSlashesInside
|
|
33788
|
+
}
|
|
33713
33789
|
}
|
|
33714
|
-
|
|
33715
33790
|
return nok(code)
|
|
33716
33791
|
}
|
|
33717
|
-
/** @type {State} */
|
|
33718
33792
|
|
|
33719
|
-
|
|
33793
|
+
/**
|
|
33794
|
+
* In slashes.
|
|
33795
|
+
*
|
|
33796
|
+
* ```markdown
|
|
33797
|
+
* > | https://example.com/a?b#c
|
|
33798
|
+
* ^^
|
|
33799
|
+
* ```
|
|
33800
|
+
*
|
|
33801
|
+
* @type {State}
|
|
33802
|
+
*/
|
|
33803
|
+
function protocolSlashesInside(code) {
|
|
33720
33804
|
if (code === 47) {
|
|
33721
33805
|
effects.consume(code)
|
|
33722
|
-
|
|
33806
|
+
if (seen) {
|
|
33807
|
+
return afterProtocol
|
|
33808
|
+
}
|
|
33809
|
+
seen = true
|
|
33810
|
+
return protocolSlashesInside
|
|
33723
33811
|
}
|
|
33724
|
-
|
|
33725
33812
|
return nok(code)
|
|
33726
33813
|
}
|
|
33727
|
-
/** @type {State} */
|
|
33728
33814
|
|
|
33729
|
-
|
|
33815
|
+
/**
|
|
33816
|
+
* After protocol, before domain.
|
|
33817
|
+
*
|
|
33818
|
+
* ```markdown
|
|
33819
|
+
* > | https://example.com/a?b#c
|
|
33820
|
+
* ^
|
|
33821
|
+
* ```
|
|
33822
|
+
*
|
|
33823
|
+
* @type {State}
|
|
33824
|
+
*/
|
|
33825
|
+
function afterProtocol(code) {
|
|
33826
|
+
// To do: this is different from `markdown-rs`:
|
|
33827
|
+
// https://github.com/wooorm/markdown-rs/blob/b3a921c761309ae00a51fe348d8a43adbc54b518/src/construct/gfm_autolink_literal.rs#L172-L182
|
|
33730
33828
|
return code === null ||
|
|
33731
33829
|
asciiControl(code) ||
|
|
33830
|
+
markdownLineEndingOrSpace(code) ||
|
|
33732
33831
|
unicodeWhitespace(code) ||
|
|
33733
33832
|
unicodePunctuation(code)
|
|
33734
33833
|
? nok(code)
|
|
33735
|
-
: effects.attempt(domain, effects.attempt(syntax_path,
|
|
33834
|
+
: effects.attempt(domain, effects.attempt(syntax_path, protocolAfter), nok)(code)
|
|
33736
33835
|
}
|
|
33737
|
-
/** @type {State} */
|
|
33738
33836
|
|
|
33739
|
-
|
|
33837
|
+
/**
|
|
33838
|
+
* After a protocol autolink literal.
|
|
33839
|
+
*
|
|
33840
|
+
* ```markdown
|
|
33841
|
+
* > | https://example.com/a?b#c
|
|
33842
|
+
* ^
|
|
33843
|
+
* ```
|
|
33844
|
+
*
|
|
33845
|
+
* @type {State}
|
|
33846
|
+
*/
|
|
33847
|
+
function protocolAfter(code) {
|
|
33740
33848
|
effects.exit('literalAutolinkHttp')
|
|
33741
33849
|
effects.exit('literalAutolink')
|
|
33742
33850
|
return ok(code)
|
|
33743
33851
|
}
|
|
33744
33852
|
}
|
|
33745
|
-
/** @type {Tokenizer} */
|
|
33746
|
-
|
|
33747
|
-
function tokenizeWww(effects, ok, nok) {
|
|
33748
|
-
return start
|
|
33749
|
-
/** @type {State} */
|
|
33750
33853
|
|
|
33751
|
-
|
|
33752
|
-
|
|
33753
|
-
|
|
33754
|
-
|
|
33755
|
-
|
|
33854
|
+
/**
|
|
33855
|
+
* `www` prefix.
|
|
33856
|
+
*
|
|
33857
|
+
* ```markdown
|
|
33858
|
+
* > | a www.example.org b
|
|
33859
|
+
* ^^^^
|
|
33860
|
+
* ```
|
|
33861
|
+
*
|
|
33862
|
+
* @this {TokenizeContext}
|
|
33863
|
+
* @type {Tokenizer}
|
|
33864
|
+
*/
|
|
33865
|
+
function tokenizeWwwPrefix(effects, ok, nok) {
|
|
33866
|
+
let size = 0
|
|
33867
|
+
return wwwPrefixInside
|
|
33756
33868
|
|
|
33757
|
-
|
|
33758
|
-
|
|
33869
|
+
/**
|
|
33870
|
+
* In www prefix.
|
|
33871
|
+
*
|
|
33872
|
+
* ```markdown
|
|
33873
|
+
* > | www.example.com
|
|
33874
|
+
* ^^^^
|
|
33875
|
+
* ```
|
|
33876
|
+
*
|
|
33877
|
+
* @type {State}
|
|
33878
|
+
*/
|
|
33879
|
+
function wwwPrefixInside(code) {
|
|
33880
|
+
if ((code === 87 || code === 119) && size < 3) {
|
|
33881
|
+
size++
|
|
33759
33882
|
effects.consume(code)
|
|
33760
|
-
return
|
|
33883
|
+
return wwwPrefixInside
|
|
33884
|
+
}
|
|
33885
|
+
if (code === 46 && size === 3) {
|
|
33886
|
+
effects.consume(code)
|
|
33887
|
+
return wwwPrefixAfter
|
|
33761
33888
|
}
|
|
33762
|
-
|
|
33763
33889
|
return nok(code)
|
|
33764
33890
|
}
|
|
33765
|
-
/** @type {State} */
|
|
33766
|
-
|
|
33767
|
-
function w3(code) {
|
|
33768
|
-
if (code === 87 || code === 119) {
|
|
33769
|
-
effects.consume(code)
|
|
33770
|
-
return dot
|
|
33771
|
-
}
|
|
33772
|
-
|
|
33773
|
-
return nok(code)
|
|
33774
|
-
}
|
|
33775
|
-
/** @type {State} */
|
|
33776
|
-
|
|
33777
|
-
function dot(code) {
|
|
33778
|
-
if (code === 46) {
|
|
33779
|
-
effects.consume(code)
|
|
33780
|
-
return after
|
|
33781
|
-
}
|
|
33782
|
-
|
|
33783
|
-
return nok(code)
|
|
33784
|
-
}
|
|
33785
|
-
/** @type {State} */
|
|
33786
33891
|
|
|
33787
|
-
|
|
33788
|
-
|
|
33892
|
+
/**
|
|
33893
|
+
* After www prefix.
|
|
33894
|
+
*
|
|
33895
|
+
* ```markdown
|
|
33896
|
+
* > | www.example.com
|
|
33897
|
+
* ^
|
|
33898
|
+
* ```
|
|
33899
|
+
*
|
|
33900
|
+
* @type {State}
|
|
33901
|
+
*/
|
|
33902
|
+
function wwwPrefixAfter(code) {
|
|
33903
|
+
// If there is *anything*, we can link.
|
|
33904
|
+
return code === null ? nok(code) : ok(code)
|
|
33789
33905
|
}
|
|
33790
33906
|
}
|
|
33791
|
-
/** @type {Tokenizer} */
|
|
33792
33907
|
|
|
33908
|
+
/**
|
|
33909
|
+
* Domain.
|
|
33910
|
+
*
|
|
33911
|
+
* ```markdown
|
|
33912
|
+
* > | a https://example.org b
|
|
33913
|
+
* ^^^^^^^^^^^
|
|
33914
|
+
* ```
|
|
33915
|
+
*
|
|
33916
|
+
* @this {TokenizeContext}
|
|
33917
|
+
* @type {Tokenizer}
|
|
33918
|
+
*/
|
|
33793
33919
|
function tokenizeDomain(effects, ok, nok) {
|
|
33794
|
-
/** @type {boolean|undefined} */
|
|
33795
|
-
let
|
|
33796
|
-
/** @type {boolean|undefined} */
|
|
33797
|
-
|
|
33798
|
-
|
|
33799
|
-
|
|
33800
|
-
|
|
33920
|
+
/** @type {boolean | undefined} */
|
|
33921
|
+
let underscoreInLastSegment
|
|
33922
|
+
/** @type {boolean | undefined} */
|
|
33923
|
+
let underscoreInLastLastSegment
|
|
33924
|
+
/** @type {boolean | undefined} */
|
|
33925
|
+
let seen
|
|
33926
|
+
return domainInside
|
|
33801
33927
|
|
|
33802
|
-
|
|
33803
|
-
|
|
33804
|
-
|
|
33805
|
-
|
|
33806
|
-
|
|
33807
|
-
|
|
33808
|
-
|
|
33928
|
+
/**
|
|
33929
|
+
* In domain.
|
|
33930
|
+
*
|
|
33931
|
+
* ```markdown
|
|
33932
|
+
* > | https://example.com/a
|
|
33933
|
+
* ^^^^^^^^^^^
|
|
33934
|
+
* ```
|
|
33935
|
+
*
|
|
33936
|
+
* @type {State}
|
|
33937
|
+
*/
|
|
33938
|
+
function domainInside(code) {
|
|
33939
|
+
// Check whether this marker, which is a trailing punctuation
|
|
33940
|
+
// marker, optionally followed by more trailing markers, and then
|
|
33941
|
+
// followed by an end.
|
|
33942
|
+
if (code === 46 || code === 95) {
|
|
33943
|
+
return effects.check(trail, domainAfter, domainAtPunctuation)(code)
|
|
33809
33944
|
}
|
|
33810
33945
|
|
|
33811
|
-
|
|
33812
|
-
return effects.check(punctuation, done, punctuationContinuation)(code)
|
|
33813
|
-
} // GH documents that only alphanumerics (other than `-`, `.`, and `_`) can
|
|
33946
|
+
// GH documents that only alphanumerics (other than `-`, `.`, and `_`) can
|
|
33814
33947
|
// occur, which sounds like ASCII only, but they also support `www.點看.com`,
|
|
33815
33948
|
// so that’s Unicode.
|
|
33816
33949
|
// Instead of some new production for Unicode alphanumerics, markdown
|
|
33817
33950
|
// already has that for Unicode punctuation and whitespace, so use those.
|
|
33818
|
-
|
|
33951
|
+
// Source: <https://github.com/github/cmark-gfm/blob/ef1cfcb/extensions/autolink.c#L12>.
|
|
33819
33952
|
if (
|
|
33820
33953
|
code === null ||
|
|
33821
|
-
|
|
33954
|
+
markdownLineEndingOrSpace(code) ||
|
|
33822
33955
|
unicodeWhitespace(code) ||
|
|
33823
33956
|
(code !== 45 && unicodePunctuation(code))
|
|
33824
33957
|
) {
|
|
33825
|
-
return
|
|
33958
|
+
return domainAfter(code)
|
|
33826
33959
|
}
|
|
33827
|
-
|
|
33960
|
+
seen = true
|
|
33828
33961
|
effects.consume(code)
|
|
33829
|
-
return
|
|
33962
|
+
return domainInside
|
|
33830
33963
|
}
|
|
33831
|
-
/** @type {State} */
|
|
33832
33964
|
|
|
33833
|
-
|
|
33834
|
-
|
|
33835
|
-
|
|
33836
|
-
|
|
33837
|
-
|
|
33838
|
-
|
|
33965
|
+
/**
|
|
33966
|
+
* In domain, at potential trailing punctuation, that was not trailing.
|
|
33967
|
+
*
|
|
33968
|
+
* ```markdown
|
|
33969
|
+
* > | https://example.com
|
|
33970
|
+
* ^
|
|
33971
|
+
* ```
|
|
33972
|
+
*
|
|
33973
|
+
* @type {State}
|
|
33974
|
+
*/
|
|
33975
|
+
function domainAtPunctuation(code) {
|
|
33976
|
+
// There is an underscore in the last segment of the domain
|
|
33977
|
+
if (code === 95) {
|
|
33978
|
+
underscoreInLastSegment = true
|
|
33979
|
+
}
|
|
33980
|
+
// Otherwise, it’s a `.`: save the last segment underscore in the
|
|
33981
|
+
// penultimate segment slot.
|
|
33982
|
+
else {
|
|
33983
|
+
underscoreInLastLastSegment = underscoreInLastSegment
|
|
33984
|
+
underscoreInLastSegment = undefined
|
|
33839
33985
|
}
|
|
33840
|
-
|
|
33841
|
-
if (code === 95) hasUnderscoreInLastSegment = true
|
|
33842
33986
|
effects.consume(code)
|
|
33843
|
-
return
|
|
33987
|
+
return domainInside
|
|
33844
33988
|
}
|
|
33845
|
-
/** @type {State} */
|
|
33846
33989
|
|
|
33847
|
-
|
|
33848
|
-
|
|
33849
|
-
|
|
33990
|
+
/**
|
|
33991
|
+
* After domain.
|
|
33992
|
+
*
|
|
33993
|
+
* ```markdown
|
|
33994
|
+
* > | https://example.com/a
|
|
33995
|
+
* ^
|
|
33996
|
+
* ```
|
|
33997
|
+
*
|
|
33998
|
+
* @type {State} */
|
|
33999
|
+
function domainAfter(code) {
|
|
34000
|
+
// Note: that’s GH says a dot is needed, but it’s not true:
|
|
34001
|
+
// <https://github.com/github/cmark-gfm/issues/279>
|
|
34002
|
+
if (underscoreInLastLastSegment || underscoreInLastSegment || !seen) {
|
|
34003
|
+
return nok(code)
|
|
33850
34004
|
}
|
|
33851
|
-
|
|
33852
|
-
return nok(code)
|
|
34005
|
+
return ok(code)
|
|
33853
34006
|
}
|
|
33854
34007
|
}
|
|
33855
|
-
/** @type {Tokenizer} */
|
|
33856
34008
|
|
|
34009
|
+
/**
|
|
34010
|
+
* Path.
|
|
34011
|
+
*
|
|
34012
|
+
* ```markdown
|
|
34013
|
+
* > | a https://example.org/stuff b
|
|
34014
|
+
* ^^^^^^
|
|
34015
|
+
* ```
|
|
34016
|
+
*
|
|
34017
|
+
* @this {TokenizeContext}
|
|
34018
|
+
* @type {Tokenizer}
|
|
34019
|
+
*/
|
|
33857
34020
|
function tokenizePath(effects, ok) {
|
|
33858
|
-
let
|
|
33859
|
-
|
|
33860
|
-
|
|
33861
|
-
|
|
33862
|
-
function inPath(code) {
|
|
33863
|
-
if (code === 38) {
|
|
33864
|
-
return effects.check(
|
|
33865
|
-
namedCharacterReference,
|
|
33866
|
-
ok,
|
|
33867
|
-
continuedPunctuation
|
|
33868
|
-
)(code)
|
|
33869
|
-
}
|
|
34021
|
+
let sizeOpen = 0
|
|
34022
|
+
let sizeClose = 0
|
|
34023
|
+
return pathInside
|
|
33870
34024
|
|
|
34025
|
+
/**
|
|
34026
|
+
* In path.
|
|
34027
|
+
*
|
|
34028
|
+
* ```markdown
|
|
34029
|
+
* > | https://example.com/a
|
|
34030
|
+
* ^^
|
|
34031
|
+
* ```
|
|
34032
|
+
*
|
|
34033
|
+
* @type {State}
|
|
34034
|
+
*/
|
|
34035
|
+
function pathInside(code) {
|
|
33871
34036
|
if (code === 40) {
|
|
33872
|
-
|
|
34037
|
+
sizeOpen++
|
|
34038
|
+
effects.consume(code)
|
|
34039
|
+
return pathInside
|
|
33873
34040
|
}
|
|
33874
34041
|
|
|
33875
|
-
|
|
33876
|
-
|
|
33877
|
-
|
|
33878
|
-
|
|
33879
|
-
|
|
33880
|
-
)(code)
|
|
34042
|
+
// To do: `markdown-rs` also needs this.
|
|
34043
|
+
// If this is a paren, and there are less closings than openings,
|
|
34044
|
+
// we don’t check for a trail.
|
|
34045
|
+
if (code === 41 && sizeClose < sizeOpen) {
|
|
34046
|
+
return pathAtPunctuation(code)
|
|
33881
34047
|
}
|
|
33882
34048
|
|
|
33883
|
-
|
|
33884
|
-
|
|
34049
|
+
// Check whether this trailing punctuation marker is optionally
|
|
34050
|
+
// followed by more trailing markers, and then followed
|
|
34051
|
+
// by an end.
|
|
34052
|
+
if (
|
|
34053
|
+
code === 33 ||
|
|
34054
|
+
code === 34 ||
|
|
34055
|
+
code === 38 ||
|
|
34056
|
+
code === 39 ||
|
|
34057
|
+
code === 41 ||
|
|
34058
|
+
code === 42 ||
|
|
34059
|
+
code === 44 ||
|
|
34060
|
+
code === 46 ||
|
|
34061
|
+
code === 58 ||
|
|
34062
|
+
code === 59 ||
|
|
34063
|
+
code === 60 ||
|
|
34064
|
+
code === 63 ||
|
|
34065
|
+
code === 93 ||
|
|
34066
|
+
code === 95 ||
|
|
34067
|
+
code === 126
|
|
34068
|
+
) {
|
|
34069
|
+
return effects.check(trail, ok, pathAtPunctuation)(code)
|
|
33885
34070
|
}
|
|
33886
|
-
|
|
33887
|
-
|
|
33888
|
-
|
|
34071
|
+
if (
|
|
34072
|
+
code === null ||
|
|
34073
|
+
markdownLineEndingOrSpace(code) ||
|
|
34074
|
+
unicodeWhitespace(code)
|
|
34075
|
+
) {
|
|
34076
|
+
return ok(code)
|
|
33889
34077
|
}
|
|
33890
|
-
|
|
33891
34078
|
effects.consume(code)
|
|
33892
|
-
return
|
|
34079
|
+
return pathInside
|
|
33893
34080
|
}
|
|
33894
|
-
/** @type {State} */
|
|
33895
34081
|
|
|
33896
|
-
|
|
34082
|
+
/**
|
|
34083
|
+
* In path, at potential trailing punctuation, that was not trailing.
|
|
34084
|
+
*
|
|
34085
|
+
* ```markdown
|
|
34086
|
+
* > | https://example.com/a"b
|
|
34087
|
+
* ^
|
|
34088
|
+
* ```
|
|
34089
|
+
*
|
|
34090
|
+
* @type {State}
|
|
34091
|
+
*/
|
|
34092
|
+
function pathAtPunctuation(code) {
|
|
34093
|
+
// Count closing parens.
|
|
34094
|
+
if (code === 41) {
|
|
34095
|
+
sizeClose++
|
|
34096
|
+
}
|
|
33897
34097
|
effects.consume(code)
|
|
33898
|
-
return
|
|
33899
|
-
}
|
|
33900
|
-
/** @type {State} */
|
|
33901
|
-
|
|
33902
|
-
function parenAtPathEnd(code) {
|
|
33903
|
-
balance--
|
|
33904
|
-
return balance < 0 ? ok(code) : continuedPunctuation(code)
|
|
34098
|
+
return pathInside
|
|
33905
34099
|
}
|
|
33906
34100
|
}
|
|
33907
|
-
/** @type {Tokenizer} */
|
|
33908
34101
|
|
|
33909
|
-
|
|
33910
|
-
|
|
33911
|
-
|
|
33912
|
-
|
|
33913
|
-
|
|
33914
|
-
|
|
33915
|
-
|
|
33916
|
-
|
|
33917
|
-
|
|
34102
|
+
/**
|
|
34103
|
+
* Trail.
|
|
34104
|
+
*
|
|
34105
|
+
* This calls `ok` if this *is* the trail, followed by an end, which means
|
|
34106
|
+
* the entire trail is not part of the link.
|
|
34107
|
+
* It calls `nok` if this *is* part of the link.
|
|
34108
|
+
*
|
|
34109
|
+
* ```markdown
|
|
34110
|
+
* > | https://example.com").
|
|
34111
|
+
* ^^^
|
|
34112
|
+
* ```
|
|
34113
|
+
*
|
|
34114
|
+
* @this {TokenizeContext}
|
|
34115
|
+
* @type {Tokenizer}
|
|
34116
|
+
*/
|
|
34117
|
+
function tokenizeTrail(effects, ok, nok) {
|
|
34118
|
+
return trail
|
|
33918
34119
|
|
|
33919
|
-
|
|
33920
|
-
|
|
34120
|
+
/**
|
|
34121
|
+
* In trail of domain or path.
|
|
34122
|
+
*
|
|
34123
|
+
* ```markdown
|
|
34124
|
+
* > | https://example.com").
|
|
34125
|
+
* ^
|
|
34126
|
+
* ```
|
|
34127
|
+
*
|
|
34128
|
+
* @type {State}
|
|
34129
|
+
*/
|
|
34130
|
+
function trail(code) {
|
|
34131
|
+
// Regular trailing punctuation.
|
|
34132
|
+
if (
|
|
34133
|
+
code === 33 ||
|
|
34134
|
+
code === 34 ||
|
|
34135
|
+
code === 39 ||
|
|
34136
|
+
code === 41 ||
|
|
34137
|
+
code === 42 ||
|
|
34138
|
+
code === 44 ||
|
|
34139
|
+
code === 46 ||
|
|
34140
|
+
code === 58 ||
|
|
34141
|
+
code === 59 ||
|
|
34142
|
+
code === 63 ||
|
|
34143
|
+
code === 95 ||
|
|
34144
|
+
code === 126
|
|
34145
|
+
) {
|
|
33921
34146
|
effects.consume(code)
|
|
33922
|
-
return
|
|
34147
|
+
return trail
|
|
33923
34148
|
}
|
|
33924
34149
|
|
|
33925
|
-
|
|
34150
|
+
// `&` followed by one or more alphabeticals and then a `;`, is
|
|
34151
|
+
// as a whole considered as trailing punctuation.
|
|
34152
|
+
// In all other cases, it is considered as continuation of the URL.
|
|
34153
|
+
if (code === 38) {
|
|
33926
34154
|
effects.consume(code)
|
|
33927
|
-
return
|
|
34155
|
+
return trailCharRefStart
|
|
33928
34156
|
}
|
|
33929
34157
|
|
|
34158
|
+
// Needed because we allow literals after `[`, as we fix:
|
|
34159
|
+
// <https://github.com/github/cmark-gfm/issues/278>.
|
|
34160
|
+
// Check that it is not followed by `(` or `[`.
|
|
34161
|
+
if (code === 93) {
|
|
34162
|
+
effects.consume(code)
|
|
34163
|
+
return trailBracketAfter
|
|
34164
|
+
}
|
|
34165
|
+
if (
|
|
34166
|
+
// `<` is an end.
|
|
34167
|
+
code === 60 ||
|
|
34168
|
+
// So is whitespace.
|
|
34169
|
+
code === null ||
|
|
34170
|
+
markdownLineEndingOrSpace(code) ||
|
|
34171
|
+
unicodeWhitespace(code)
|
|
34172
|
+
) {
|
|
34173
|
+
return ok(code)
|
|
34174
|
+
}
|
|
33930
34175
|
return nok(code)
|
|
33931
34176
|
}
|
|
33932
|
-
/** @type {State} */
|
|
33933
34177
|
|
|
33934
|
-
|
|
33935
|
-
|
|
33936
|
-
|
|
33937
|
-
|
|
34178
|
+
/**
|
|
34179
|
+
* In trail, after `]`.
|
|
34180
|
+
*
|
|
34181
|
+
* > 👉 **Note**: this deviates from `cmark-gfm` to fix a bug.
|
|
34182
|
+
* > See end of <https://github.com/github/cmark-gfm/issues/278> for more.
|
|
34183
|
+
*
|
|
34184
|
+
* ```markdown
|
|
34185
|
+
* > | https://example.com](
|
|
34186
|
+
* ^
|
|
34187
|
+
* ```
|
|
34188
|
+
*
|
|
34189
|
+
* @type {State}
|
|
34190
|
+
*/
|
|
34191
|
+
function trailBracketAfter(code) {
|
|
34192
|
+
// Whitespace or something that could start a resource or reference is the end.
|
|
34193
|
+
// Switch back to trail otherwise.
|
|
34194
|
+
if (
|
|
34195
|
+
code === null ||
|
|
34196
|
+
code === 40 ||
|
|
34197
|
+
code === 91 ||
|
|
34198
|
+
markdownLineEndingOrSpace(code) ||
|
|
34199
|
+
unicodeWhitespace(code)
|
|
34200
|
+
) {
|
|
34201
|
+
return ok(code)
|
|
34202
|
+
}
|
|
34203
|
+
return trail(code)
|
|
34204
|
+
}
|
|
34205
|
+
|
|
34206
|
+
/**
|
|
34207
|
+
* In character-reference like trail, after `&`.
|
|
34208
|
+
*
|
|
34209
|
+
* ```markdown
|
|
34210
|
+
* > | https://example.com&).
|
|
34211
|
+
* ^
|
|
34212
|
+
* ```
|
|
34213
|
+
*
|
|
34214
|
+
* @type {State}
|
|
34215
|
+
*/
|
|
34216
|
+
function trailCharRefStart(code) {
|
|
34217
|
+
// When non-alpha, it’s not a trail.
|
|
34218
|
+
return asciiAlpha(code) ? trailCharRefInside(code) : nok(code)
|
|
34219
|
+
}
|
|
34220
|
+
|
|
34221
|
+
/**
|
|
34222
|
+
* In character-reference like trail.
|
|
34223
|
+
*
|
|
34224
|
+
* ```markdown
|
|
34225
|
+
* > | https://example.com&).
|
|
34226
|
+
* ^
|
|
34227
|
+
* ```
|
|
34228
|
+
*
|
|
34229
|
+
* @type {State}
|
|
34230
|
+
*/
|
|
34231
|
+
function trailCharRefInside(code) {
|
|
34232
|
+
// Switch back to trail if this is well-formed.
|
|
34233
|
+
if (code === 59) {
|
|
34234
|
+
effects.consume(code)
|
|
34235
|
+
return trail
|
|
34236
|
+
}
|
|
34237
|
+
if (asciiAlpha(code)) {
|
|
34238
|
+
effects.consume(code)
|
|
34239
|
+
return trailCharRefInside
|
|
34240
|
+
}
|
|
34241
|
+
|
|
34242
|
+
// It’s not a trail.
|
|
34243
|
+
return nok(code)
|
|
33938
34244
|
}
|
|
33939
34245
|
}
|
|
33940
|
-
/** @type {Tokenizer} */
|
|
33941
34246
|
|
|
33942
|
-
|
|
34247
|
+
/**
|
|
34248
|
+
* Dot in email domain trail.
|
|
34249
|
+
*
|
|
34250
|
+
* This calls `ok` if this *is* the trail, followed by an end, which means
|
|
34251
|
+
* the trail is not part of the link.
|
|
34252
|
+
* It calls `nok` if this *is* part of the link.
|
|
34253
|
+
*
|
|
34254
|
+
* ```markdown
|
|
34255
|
+
* > | contact@example.org.
|
|
34256
|
+
* ^
|
|
34257
|
+
* ```
|
|
34258
|
+
*
|
|
34259
|
+
* @this {TokenizeContext}
|
|
34260
|
+
* @type {Tokenizer}
|
|
34261
|
+
*/
|
|
34262
|
+
function tokenizeEmailDomainDotTrail(effects, ok, nok) {
|
|
33943
34263
|
return start
|
|
33944
|
-
/** @type {State} */
|
|
33945
34264
|
|
|
34265
|
+
/**
|
|
34266
|
+
* Dot.
|
|
34267
|
+
*
|
|
34268
|
+
* ```markdown
|
|
34269
|
+
* > | contact@example.org.
|
|
34270
|
+
* ^ ^
|
|
34271
|
+
* ```
|
|
34272
|
+
*
|
|
34273
|
+
* @type {State}
|
|
34274
|
+
*/
|
|
33946
34275
|
function start(code) {
|
|
34276
|
+
// Must be dot.
|
|
33947
34277
|
effects.consume(code)
|
|
33948
34278
|
return after
|
|
33949
34279
|
}
|
|
33950
|
-
/** @type {State} */
|
|
33951
34280
|
|
|
34281
|
+
/**
|
|
34282
|
+
* After dot.
|
|
34283
|
+
*
|
|
34284
|
+
* ```markdown
|
|
34285
|
+
* > | contact@example.org.
|
|
34286
|
+
* ^ ^
|
|
34287
|
+
* ```
|
|
34288
|
+
*
|
|
34289
|
+
* @type {State}
|
|
34290
|
+
*/
|
|
33952
34291
|
function after(code) {
|
|
33953
|
-
//
|
|
33954
|
-
|
|
33955
|
-
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.
|
|
33959
|
-
|
|
33960
|
-
return pathEnd(code) ? ok(code) : nok(code)
|
|
34292
|
+
// Not a trail if alphanumeric.
|
|
34293
|
+
return asciiAlphanumeric(code) ? nok(code) : ok(code)
|
|
33961
34294
|
}
|
|
33962
34295
|
}
|
|
34296
|
+
|
|
33963
34297
|
/**
|
|
33964
|
-
*
|
|
33965
|
-
*
|
|
34298
|
+
* See:
|
|
34299
|
+
* <https://github.com/github/cmark-gfm/blob/ef1cfcb/extensions/autolink.c#L156>.
|
|
34300
|
+
*
|
|
34301
|
+
* @type {Previous}
|
|
33966
34302
|
*/
|
|
33967
|
-
|
|
33968
|
-
function trailingPunctuation(code) {
|
|
34303
|
+
function previousWww(code) {
|
|
33969
34304
|
return (
|
|
33970
|
-
code ===
|
|
33971
|
-
code ===
|
|
33972
|
-
code === 39 ||
|
|
33973
|
-
code === 41 ||
|
|
34305
|
+
code === null ||
|
|
34306
|
+
code === 40 ||
|
|
33974
34307
|
code === 42 ||
|
|
33975
|
-
code === 44 ||
|
|
33976
|
-
code === 46 ||
|
|
33977
|
-
code === 58 ||
|
|
33978
|
-
code === 59 ||
|
|
33979
|
-
code === 60 ||
|
|
33980
|
-
code === 63 ||
|
|
33981
34308
|
code === 95 ||
|
|
33982
|
-
code ===
|
|
34309
|
+
code === 91 ||
|
|
34310
|
+
code === 93 ||
|
|
34311
|
+
code === 126 ||
|
|
34312
|
+
markdownLineEndingOrSpace(code)
|
|
33983
34313
|
)
|
|
33984
34314
|
}
|
|
34315
|
+
|
|
33985
34316
|
/**
|
|
33986
|
-
*
|
|
33987
|
-
*
|
|
34317
|
+
* See:
|
|
34318
|
+
* <https://github.com/github/cmark-gfm/blob/ef1cfcb/extensions/autolink.c#L214>.
|
|
34319
|
+
*
|
|
34320
|
+
* @type {Previous}
|
|
33988
34321
|
*/
|
|
34322
|
+
function previousProtocol(code) {
|
|
34323
|
+
return !asciiAlpha(code)
|
|
34324
|
+
}
|
|
33989
34325
|
|
|
33990
|
-
|
|
33991
|
-
|
|
34326
|
+
/**
|
|
34327
|
+
* @this {TokenizeContext}
|
|
34328
|
+
* @type {Previous}
|
|
34329
|
+
*/
|
|
34330
|
+
function previousEmail(code) {
|
|
34331
|
+
// Do not allow a slash “inside” atext.
|
|
34332
|
+
// The reference code is a bit weird, but that’s what it results in.
|
|
34333
|
+
// Source: <https://github.com/github/cmark-gfm/blob/ef1cfcb/extensions/autolink.c#L307>.
|
|
34334
|
+
// Other than slash, every preceding character is allowed.
|
|
34335
|
+
return !(code === 47 || gfmAtext(code))
|
|
33992
34336
|
}
|
|
34337
|
+
|
|
33993
34338
|
/**
|
|
33994
34339
|
* @param {Code} code
|
|
33995
34340
|
* @returns {boolean}
|
|
33996
34341
|
*/
|
|
33997
|
-
|
|
33998
34342
|
function gfmAtext(code) {
|
|
33999
34343
|
return (
|
|
34000
34344
|
code === 43 ||
|
|
@@ -34004,61 +34348,36 @@ function gfmAtext(code) {
|
|
|
34004
34348
|
asciiAlphanumeric(code)
|
|
34005
34349
|
)
|
|
34006
34350
|
}
|
|
34007
|
-
/** @type {Previous} */
|
|
34008
|
-
|
|
34009
|
-
function previousWww(code) {
|
|
34010
|
-
return (
|
|
34011
|
-
code === null ||
|
|
34012
|
-
code === 40 ||
|
|
34013
|
-
code === 42 ||
|
|
34014
|
-
code === 95 ||
|
|
34015
|
-
code === 126 ||
|
|
34016
|
-
markdownLineEndingOrSpace(code)
|
|
34017
|
-
)
|
|
34018
|
-
}
|
|
34019
|
-
/** @type {Previous} */
|
|
34020
34351
|
|
|
34021
|
-
function previousHttp(code) {
|
|
34022
|
-
return code === null || !asciiAlpha(code)
|
|
34023
|
-
}
|
|
34024
|
-
/** @type {Previous} */
|
|
34025
|
-
|
|
34026
|
-
function previousEmail(code) {
|
|
34027
|
-
return code !== 47 && previousHttp(code)
|
|
34028
|
-
}
|
|
34029
34352
|
/**
|
|
34030
34353
|
* @param {Array<Event>} events
|
|
34031
34354
|
* @returns {boolean}
|
|
34032
34355
|
*/
|
|
34033
|
-
|
|
34034
34356
|
function previousUnbalanced(events) {
|
|
34035
34357
|
let index = events.length
|
|
34036
34358
|
let result = false
|
|
34037
|
-
|
|
34038
34359
|
while (index--) {
|
|
34039
34360
|
const token = events[index][1]
|
|
34040
|
-
|
|
34041
34361
|
if (
|
|
34042
34362
|
(token.type === 'labelLink' || token.type === 'labelImage') &&
|
|
34043
34363
|
!token._balanced
|
|
34044
34364
|
) {
|
|
34045
34365
|
result = true
|
|
34046
34366
|
break
|
|
34047
|
-
}
|
|
34048
|
-
// having any unbalanced bracket before it, we can exit.
|
|
34367
|
+
}
|
|
34049
34368
|
|
|
34369
|
+
// @ts-expect-error If we’ve seen this token, and it was marked as not
|
|
34370
|
+
// having any unbalanced bracket before it, we can exit.
|
|
34050
34371
|
if (token._gfmAutolinkLiteralWalkedInto) {
|
|
34051
34372
|
result = false
|
|
34052
34373
|
break
|
|
34053
34374
|
}
|
|
34054
34375
|
}
|
|
34055
|
-
|
|
34056
34376
|
if (events.length > 0 && !result) {
|
|
34057
34377
|
// @ts-expect-error Mark the last token as “walked into” w/o finding
|
|
34058
34378
|
// anything.
|
|
34059
34379
|
events[events.length - 1][1]._gfmAutolinkLiteralWalkedInto = true
|
|
34060
34380
|
}
|
|
34061
|
-
|
|
34062
34381
|
return result
|
|
34063
34382
|
}
|
|
34064
34383
|
|