11const findAndReplace = require ( 'mdast-util-find-and-replace' ) ;
2+ const markdownLineEnding = require ( 'micromark/dist/character/markdown-line-ending' ) ;
3+
4+ const link = '@link' ;
5+ const tutorial = '@tutorial' ;
6+
7+ function tokenizeJsDoclink ( effects , ok , nok ) {
8+ let index = 0 ;
9+ let focus = link ;
10+
11+ function atext ( code ) {
12+ if ( index !== link . length ) {
13+ if ( focus . charCodeAt ( index ) === code ) {
14+ effects . consume ( code ) ;
15+ index ++ ;
16+ return atext ;
17+ } else if ( tutorial . charCodeAt ( index ) === code ) {
18+ focus = tutorial ;
19+ }
20+ return nok ( code ) ;
21+ }
22+ if ( code === 125 ) {
23+ effects . consume ( code ) ;
24+ effects . exit ( 'literalJsDoclink' ) ;
25+ return ok ( code ) ;
26+ }
27+
28+ if ( markdownLineEnding ( code ) ) {
29+ return nok ( code ) ;
30+ }
31+
32+ effects . consume ( code ) ;
33+ return atext ;
34+ }
35+
36+ return function ( code ) {
37+ effects . enter ( 'literalJsDoclink' ) ;
38+ effects . consume ( code ) ;
39+ return atext ;
40+ } ;
41+ }
42+
43+ const text = { } ;
44+ text [ 123 ] = {
45+ tokenize : tokenizeJsDoclink ,
46+ previous ( code ) {
47+ return code === null || code === 32 || markdownLineEnding ( code ) ;
48+ }
49+ } ;
50+
51+ const linkRegExp = / \{ @ l i n k \s + ( .+ ?) (?: [ \s | ] ( .* ?) ) ? \} / ;
52+ const tutorialRegExp = / \{ @ t u t o r i a l \s + ( .+ ?) (?: [ \s | ] ( .* ?) ) ? \} / ;
253
354/**
455 * A remark plugin that installs
@@ -10,6 +61,7 @@ const findAndReplace = require('mdast-util-find-and-replace');
1061 * @returns {Function }
1162 */
1263module . exports = function ( ) {
64+ const data = this . data ( ) ;
1365 function replace ( type ) {
1466 return ( match , matchUrl , matchValue ) => {
1567 return {
@@ -27,10 +79,37 @@ module.exports = function () {
2779 } ;
2880 }
2981
30- return function transform ( markdownAST ) {
31- return findAndReplace ( markdownAST , [
32- [ / \{ @ l i n k \s + ( .+ ?) (?: [ \s | ] ( .* ?) ) ? \} / g, replace ( 'link' ) ] ,
33- [ / \{ @ t u t o r i a l \s + ( .+ ?) (?: [ \s | ] ( .* ?) ) ? \} / g, replace ( 'tutorial' ) ]
34- ] ) ;
35- } ;
82+ add ( 'micromarkExtensions' , { text } ) ;
83+ add ( 'fromMarkdownExtensions' , {
84+ transforms : [
85+ function ( markdownAST ) {
86+ return findAndReplace ( markdownAST , [
87+ [ new RegExp ( linkRegExp . source , 'g' ) , replace ( 'link' ) ] ,
88+ [ new RegExp ( tutorialRegExp . source , 'g' ) , replace ( 'tutorial' ) ]
89+ ] ) ;
90+ }
91+ ] ,
92+ enter : {
93+ literalJsDoclink ( token ) {
94+ const str = this . sliceSerialize ( token ) ;
95+ let match = null ;
96+ if ( str . startsWith ( '{@link' ) ) {
97+ match = linkRegExp . exec ( str ) ;
98+ } else {
99+ match = tutorialRegExp . exec ( str ) ;
100+ }
101+
102+ this . enter ( replace ( 'link' ) ( ...match ) , token ) ;
103+ }
104+ } ,
105+ exit : {
106+ literalJsDoclink ( token ) {
107+ this . exit ( token ) ;
108+ }
109+ }
110+ } ) ;
111+ function add ( field , value ) {
112+ if ( data [ field ] ) data [ field ] . push ( value ) ;
113+ else data [ field ] = [ value ] ;
114+ }
36115} ;
0 commit comments