import * as Uni from "unist" ; import * as Mdast from "mdast" ; import { Token } from "micromark/dist/shared-types" ; import { MdastExtension } from "mdast-util-from-markdown/types" ; import { Context } from "mdast-util-to-markdown" ; export interface MdastWikilinkOptions_FromMarkdown { default permalinks : string [ ] ; default pageResolver : ( pageName : string ) => string [ ] ; default hrefTemplate : ( permalink : string ) => string ; default wikiLinkClassName : string ; default newClassName : string ; } export interface MdastWikilinkOptions_ToMarkdown { default aliasDivider : string ; } export type MdastWikilinkOptions = MdastWikilinkOptions_FromMarkdown & MdastWikilinkOptions_ToMarkdown ; export interface MdWikilink extends Mdast . Literal { value : string ; data : { alias : string ; permalink : string ; exists : boolean ; hName ? : string ; hProperties ? : { className : string ; href : string ; } ; hChildren : [ { type : "text" ; value : string ; } ] ; } ; } export function fromMarkdown ( opts = { } ) { const permalinks = opts . permalinks || [ ] ; const defaultPageResolver = ( name ) => [ name . replace ( / /g , '_' ) . toLowerCase ( ) ] ; const pageResolver = opts . pageResolver || defaultPageResolver ; const newClassName = opts . newClassName || 'new' ; const wikiLinkClassName = opts . wikiLinkClassName || 'internal' ; const defaultHrefTemplate = ( permalink ) => `#/page/${ permalink }` ; const hrefTemplate = opts . hrefTemplate || defaultHrefTemplate ; function enterWikiLink ( this , token ) { this . enter ( { type : 'wikiLink' , value : null , data : { alias : null , permalink : null , exists : null } } , token ) ; } function top < T > ( stack ) { return stack [ stack . length - 1 ] ; } function exitWikiLinkAlias ( this , token ) { const alias = this . sliceSerialize ( token ) ; const current = top ( this . stack ) as MdWikilink ; current . data . alias = alias ; } function exitWikiLinkTarget ( this , token ) { const target = this . sliceSerialize ( token ) ; const current = top ( this . stack ) as MdWikilink ; current . value = target ; } function exitWikiLink ( this , token ) { const wikiLink = this . exit ( token ) ; const pagePermalinks = pageResolver ( wikiLink . value ) ; let permalink = pagePermalinks . find ( p => permalinks . indexOf ( p ) !== - 1 ) ; const exists = permalink !== undefined ; if ( permalink === undefined ) { permalink = pagePermalinks [ 0 ] ; } let displayName = wikiLink . value ; if ( wikiLink . data . alias ) { displayName = wikiLink . data . alias ; } let classNames = wikiLinkClassName ; if ( ! exists ) { classNames += ' ' + newClassName ; } wikiLink . data . alias = displayName ; wikiLink . data . permalink = permalink ; wikiLink . data . exists = exists ; wikiLink . data . hName = 'a' ; wikiLink . data . hProperties = { className : classNames , href : hrefTemplate ( permalink ) } ; wikiLink . data . hChildren = [ { type : 'text' , value : displayName } ] ; } return { enter : { wikiLink : enterWikiLink } , exit : { wikiLinkTarget : exitWikiLinkTarget , wikiLinkAlias : exitWikiLinkAlias , wikiLink : exitWikiLink } } ; } import safe from 'mdast-util-to-markdown/lib/util/safe.js' ; export function toMarkdown ( opts = { } ) { const aliasDivider = opts . aliasDivider || ':' ; const unsafe = [ { character : '[' , inConstruct : [ 'phrasing' , 'label' , 'reference' ] } , { character : ']' , inConstruct : [ 'label' , 'reference' ] } ] ; function handler ( node , _ , context ) { const exit = context . enter ( 'wikiLink' ) ; const nodeValue = safe ( context , node . value , { before : '[' , after : ']' } ) ; const nodeAlias = safe ( context , node . data . alias , { before : '[' , after : ']' } ) ; let value ; if ( nodeAlias !== nodeValue ) { value = `[[${ nodeValue }${ aliasDivider }${ nodeAlias }]]` ; } else { value = `[[${ nodeValue }]]` ; } exit ( ) ; return value ; } return { unsafe : unsafe , handlers : { wikiLink : handler } } ; }