import * as Uni from "unist" ; import * as Md from "@common/markdown/markdown-ast" ; import { Token } from "micromark/dist/shared-types" ; import { Context } from "mdast-util-to-markdown" ; export interface ThematicBreak extends Uni . Node { type : 'thematicBreak' ; ruleContent ? : string ; } export interface ListItem extends Md . Parent { type : 'listItem' ; checked ? : boolean ; spread ? : boolean ; children : Md . BlockContent [ ] ; marker ? : string | undefined ; } export function concreteFromMarkdown ( ) { function top < T > ( stack ) { return stack [ stack . length - 1 ] ; } function point ( d ) { return { line : d . line , column : d . column , offset : d . offset } ; } function opener ( this , create , and ? ) { return open ; function open ( this , token ) { enter . call ( this , create ( token ) , token ) ; if ( and ) and . call ( this , token ) ; } } function enter ( this , node , token ) { this . stack [ this . stack . length - 1 ] . children . push ( node ) ; this . stack . push ( node ) ; this . tokenStack . push ( token ) ; node . position = { start : point ( token . start ) } ; return node ; } function enterThematicBreak ( this , token ) { return { type : 'thematicBreak' , ruleContent : undefined } ; } function exitThematicBreak ( this , token ) { let hruleNode = this . exit ( token ) ; hruleNode . ruleContent = this . sliceSerialize ( token ) ; } function exitListItemMarker ( this , token ) { let marker = this . sliceSerialize ( token ) ; let listItem = top ( this . stack ) as Md . ListItem ; let listNode = this . stack [ this . stack . length - 2 ] as Md . List ; if ( ! listNode . ordered ) { listItem . marker = marker ; } } return { enter : { thematicBreak : opener ( enterThematicBreak ) } , exit : { thematicBreak : exitThematicBreak , listItemMarker : exitListItemMarker } } ; } import repeat from "repeat-string" ; import checkRepeat from "mdast-util-to-markdown/lib/util/check-rule-repeat" ; import checkRule from "mdast-util-to-markdown/lib/util/check-rule" ; import checkBullet from "mdast-util-to-markdown/lib/util/check-bullet" ; import checkListItemIndent from "mdast-util-to-markdown/lib/util/check-list-item-indent" ; import flow from "mdast-util-to-markdown/lib/util/container-flow" ; import indentLines from "mdast-util-to-markdown/lib/util/indent-lines" ; export function concreteToMarkdown ( ) { function handleThematicBreak ( node , parent , context ) { let rule ; if ( node . ruleContent ) { rule = node . ruleContent ; } else { rule = repeat ( checkRule ( context ) + ( context . options . ruleSpaces ? ' ' : '' ) , checkRepeat ( context ) ) ; rule = context . options . ruleSpaces ? rule . slice ( 0 , - 1 ) : rule ; } return rule ; } /**
     * Same as the default ListItem serialization code, except
     * that we use the ListItem's `marker`, if present.
     *
     * https://github.com/syntax-tree/mdast-util-to-markdown/blob/main/lib/handle/list-item.js#L9
     */ function handleListItem ( node , parent , context ) { var bullet = node . marker || checkBullet ( context ) ; if ( parent && parent . ordered ) { bullet = ( ( parent . start !== undefined && parent . start > - 1 ) ? parent . start : 1 ) + ( context . options . incrementListMarker === false ? 0 : parent . children . indexOf ( node ) ) + '.' ; } var listItemIndent = checkListItemIndent ( context ) ; let size = bullet . length + 1 ; if ( listItemIndent === 'tab' || ( listItemIndent === 'mixed' && ( ( parent && parent . spread ) || node . spread ) ) ) { size = Math . ceil ( size / 4 ) * 4 ; } let exit = context . enter ( 'listItem' ) ; let value = indentLines ( flow ( node , context ) , map ) ; exit ( ) ; return value ; function map ( line , index , blank ) { if ( index ) { return ( blank ? '' : repeat ( ' ' , size ) ) + line ; } return ( blank ? bullet : bullet + repeat ( ' ' , size - bullet . length ) ) + line ; } } return { handlers : { thematicBreak : handleThematicBreak , listItem : handleListItem } } ; }