From bebc73601673428fcc357e52603c06f73de3d26a Mon Sep 17 00:00:00 2001 From: akabeko Date: Sun, 17 Jan 2021 18:37:34 +0900 Subject: [PATCH] feat: Change automatic line breaks to optional --- src/index.ts | 26 +++++++++++++++++-- src/revive-parse.ts | 53 +++++++++++++++++++++++++++------------ tests/index.test.ts | 31 +++++++++++++++++------ tests/inline/ruby.test.ts | 1 + tests/utils.ts | 8 ++++++ 5 files changed, 93 insertions(+), 26 deletions(-) diff --git a/src/index.ts b/src/index.ts index b631eba..ee31e39 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,31 +3,47 @@ import rehypeStringify from 'rehype-stringify'; import unified, { Processor } from 'unified'; import { hast as clearHtmlLang } from './plugins/clear-html-lang'; import { replace as handleReplace, ReplaceRule } from './plugins/replace'; -import markdown from './revive-parse'; +import { reviveParse as markdown } from './revive-parse'; import html from './revive-rehype'; import { debug } from './utils/debug'; +/** + * Option for convert Markdown to a stringify (HTML). + */ export interface StringifyMarkdownOptions { + /** Custom stylesheet path/URL. */ style?: string | string[]; + /** Output markdown fragments. */ partial?: boolean; + /** Document title (ignored in partial mode). */ title?: string; + /** Document language (ignored in partial mode). */ language?: string; + /** Replacement handler for HTML string. */ replace?: ReplaceRule[]; + /** Converts line breaks to `
`. */ + autoLineBreaks?: boolean; } export interface Hooks { afterParse: ReplaceRule[]; } +/** + * Create Unified processor for MDAST and HAST. + * @param options Options. + * @returns Unified processor. + */ export function VFM({ style = undefined, partial = false, title = undefined, language = undefined, replace = undefined, + autoLineBreaks = false, }: StringifyMarkdownOptions = {}): Processor { const processor = unified() - .use(markdown) + .use(markdown({ autoLineBreaks })) .data('settings', { position: false }) .use(html); @@ -47,6 +63,12 @@ export function VFM({ return processor; } +/** + * Convert Markdown to a stringify (HTML). + * @param markdownString Markdown string. + * @param options Options. + * @returns HTML string. + */ export function stringify( markdownString: string, options: StringifyMarkdownOptions = {}, diff --git a/src/revive-parse.ts b/src/revive-parse.ts index 6e9969c..08f402d 100644 --- a/src/revive-parse.ts +++ b/src/revive-parse.ts @@ -14,19 +14,40 @@ import { mdast as section } from './plugins/section'; import { mdast as toc } from './plugins/toc'; import { inspect } from './utils/debug'; -export default [ - [markdown, { gfm: true, commonmark: true }], - fencedBlock, - ruby, - breaks, - [footnotes, { inlineNotes: true }], - math, - attr, - slug, - section, - code, - toc, - frontmatter, - metadata, - inspect('mdast'), -] as unified.PluggableList; +/** + * Options for Markdown conversion. + */ +export interface MarkdownOptions { + /** Converts line breaks to `
`. */ + autoLineBreaks: boolean; +} + +/** + * Create MDAST parsers. + * @param options Options. + * @returns Parsers. + */ +export const reviveParse = (options: MarkdownOptions) => { + const results = [ + [markdown, { gfm: true, commonmark: true }], + fencedBlock, + ruby, + [footnotes, { inlineNotes: true }], + math, + attr, + slug, + section, + code, + toc, + frontmatter, + metadata, + inspect('mdast'), + ] as unified.PluggableList; + + if (options.autoLineBreaks) { + // Line breaks are processed immediately after ruby + results.splice(3, 0, breaks); + } + + return results; +}; diff --git a/tests/index.test.ts b/tests/index.test.ts index 61e1116..a9412d1 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -1,8 +1,14 @@ import * as lib from '../src'; import { ReplaceRule } from '../src/plugins/replace'; -function partial(body: string) { - return lib.stringify(body, { partial: true }); +/** + * Run VFM stringify in partial mode. + * @param body Markdown string that becomes `` part. + * @param autoLineBreaks Converts line breaks to `
`. + * @returns HTML string. + */ +function partial(body: string, autoLineBreaks = false) { + return lib.stringify(body, { partial: true, autoLineBreaks }); } // Snippet @@ -66,13 +72,16 @@ it('handle role', () => { it('reject incorrect fences', () => { expect( - partial(` + partial( + ` ::::appendix :::::nested # Title ::::: :::: -`), +`, + true, + ), ).toBe( `

::::appendix
:::::nested
@@ -82,13 +91,16 @@ it('reject incorrect fences', () => { ); expect( - partial(` + partial( + ` :::appendix :::::nested # Title ::::: ::: -`), +`, + true, + ), ).toBe( `

:::::nested
# Title
@@ -143,9 +155,12 @@ A it('handle hard line break', () => { expect( - partial(` + partial( + ` a -b`), +b`, + true, + ), ).toBe(`

a
b

`); }); diff --git a/tests/inline/ruby.test.ts b/tests/inline/ruby.test.ts index 4fa6553..a1b506c 100644 --- a/tests/inline/ruby.test.ts +++ b/tests/inline/ruby.test.ts @@ -74,5 +74,6 @@ it( └─2 text "b|c}" `, `

{a
\nb|c}

`, + { autoLineBreaks: true, partial: true }, ), ); diff --git a/tests/utils.ts b/tests/utils.ts index a34c904..c77d4d3 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -1,6 +1,13 @@ import unistInspect from 'unist-util-inspect'; import { StringifyMarkdownOptions, VFM } from '../src'; +/** + * Utility for testing MDAST and HTML strings generated from Markdown. + * @param input Markdown string. + * @param expectedMdast Expected MDAST string. + * @param expectedHtml Expected HTML string. + * @param options Option for convert Markdown to VFM (HTML). + */ export const buildProcessorTestingCode = ( input: string, expectedMdast: string, @@ -11,6 +18,7 @@ export const buildProcessorTestingCode = ( title: undefined, language: undefined, replace: undefined, + autoLineBreaks: false, }, ) => (): any => { const vfm = VFM(options).freeze();