From 71b9042148383fd8f690ff98ff56d09860d45c64 Mon Sep 17 00:00:00 2001 From: Jason Dent Date: Sat, 28 Jan 2023 13:03:49 +0100 Subject: [PATCH] feat: Support GitHub Flavored Markdown (#24) --- fixtures/code/README.md | 10 ++ package.json | 1 + pnpm-lock.yaml | 160 ++++++++++++++++++ src/FileInjector/FileInjector.ts | 14 +- src/FileInjector/VFileEx.test.ts | 9 + src/FileInjector/VFileEx.ts | 2 +- .../__snapshots__/FileInjector.test.ts.snap | 10 ++ 7 files changed, 200 insertions(+), 6 deletions(-) create mode 100644 src/FileInjector/VFileEx.test.ts diff --git a/fixtures/code/README.md b/fixtures/code/README.md index 70f0080..16e2141 100644 --- a/fixtures/code/README.md +++ b/fixtures/code/README.md @@ -29,3 +29,13 @@ It is also possible to inject markdown: ``` + +## GitHub Footnote + +| | version | Node | Support | End-Of-Life | +| :----- | :------ | :--- | :-------------------- | :---------- | +| cspell | 6.x | 14.x | In Active Development | TBD | +| cspell | 5.x | 12.x | Paid support only[^1] | 2022-10-01 | +| cspell | 4.x | 10.x | Paid support only[^1] | 2022-05-01 | + +[^1]: [Support - Street Side Software](https://streetsidesoftware.com/support/#maintenance-agreements) diff --git a/package.json b/package.json index b73e49a..13e63df 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "globby": "^13.1.3", "node-fetch": "^3.3.0", "remark": "^14.0.2", + "remark-gfm": "^3.0.1", "remark-mdx": "^2.2.1", "remark-parse": "^10.0.1", "remark-stringify": "^10.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 13185d8..3166e74 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,6 +21,7 @@ specifiers: node-fetch: ^3.3.0 prettier: ^2.8.1 remark: ^14.0.2 + remark-gfm: ^3.0.1 remark-mdx: ^2.2.1 remark-parse: ^10.0.1 remark-stringify: ^10.0.2 @@ -40,6 +41,7 @@ dependencies: globby: 13.1.3 node-fetch: 3.3.0 remark: 14.0.2 + remark-gfm: 3.0.1 remark-mdx: 2.2.1 remark-parse: 10.0.1 remark-stringify: 10.0.2 @@ -1016,6 +1018,11 @@ packages: engines: {node: '>=10'} dev: true + /escape-string-regexp/5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + dev: false + /eslint-config-prettier/8.5.0_eslint@8.30.0: resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} hasBin: true @@ -1873,6 +1880,19 @@ packages: semver: 6.3.0 dev: true + /markdown-table/3.0.3: + resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==} + dev: false + + /mdast-util-find-and-replace/2.2.2: + resolution: {integrity: sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==} + dependencies: + '@types/mdast': 3.0.10 + escape-string-regexp: 5.0.0 + unist-util-is: 5.1.1 + unist-util-visit-parents: 5.1.1 + dev: false + /mdast-util-from-markdown/1.2.0: resolution: {integrity: sha512-iZJyyvKD1+K7QX1b5jXdE7Sc5dtoTry1vzV28UZZe8Z1xVnB/czKntJ7ZAkG0tANqRnBF6p3p7GpU1y19DTf2Q==} dependencies: @@ -1892,6 +1912,62 @@ packages: - supports-color dev: false + /mdast-util-gfm-autolink-literal/1.0.2: + resolution: {integrity: sha512-FzopkOd4xTTBeGXhXSBU0OCDDh5lUj2rd+HQqG92Ld+jL4lpUfgX2AT2OHAVP9aEeDKp7G92fuooSZcYJA3cRg==} + dependencies: + '@types/mdast': 3.0.10 + ccount: 2.0.1 + mdast-util-find-and-replace: 2.2.2 + micromark-util-character: 1.1.0 + dev: false + + /mdast-util-gfm-footnote/1.0.1: + resolution: {integrity: sha512-p+PrYlkw9DeCRkTVw1duWqPRHX6Ywh2BNKJQcZbCwAuP/59B0Lk9kakuAd7KbQprVO4GzdW8eS5++A9PUSqIyw==} + dependencies: + '@types/mdast': 3.0.10 + mdast-util-to-markdown: 1.4.0 + micromark-util-normalize-identifier: 1.0.0 + dev: false + + /mdast-util-gfm-strikethrough/1.0.2: + resolution: {integrity: sha512-T/4DVHXcujH6jx1yqpcAYYwd+z5lAYMw4Ls6yhTfbMMtCt0PHY4gEfhW9+lKsLBtyhUGKRIzcUA2FATVqnvPDA==} + dependencies: + '@types/mdast': 3.0.10 + mdast-util-to-markdown: 1.4.0 + dev: false + + /mdast-util-gfm-table/1.0.6: + resolution: {integrity: sha512-uHR+fqFq3IvB3Rd4+kzXW8dmpxUhvgCQZep6KdjsLK4O6meK5dYZEayLtIxNus1XO3gfjfcIFe8a7L0HZRGgag==} + dependencies: + '@types/mdast': 3.0.10 + markdown-table: 3.0.3 + mdast-util-from-markdown: 1.2.0 + mdast-util-to-markdown: 1.4.0 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-gfm-task-list-item/1.0.1: + resolution: {integrity: sha512-KZ4KLmPdABXOsfnM6JHUIjxEvcx2ulk656Z/4Balw071/5qgnhz+H1uGtf2zIGnrnvDC8xR4Fj9uKbjAFGNIeA==} + dependencies: + '@types/mdast': 3.0.10 + mdast-util-to-markdown: 1.4.0 + dev: false + + /mdast-util-gfm/2.0.1: + resolution: {integrity: sha512-42yHBbfWIFisaAfV1eixlabbsa6q7vHeSPY+cg+BBjX51M8xhgMacqH9g6TftB/9+YkcI0ooV4ncfrJslzm/RQ==} + dependencies: + mdast-util-from-markdown: 1.2.0 + mdast-util-gfm-autolink-literal: 1.0.2 + mdast-util-gfm-footnote: 1.0.1 + mdast-util-gfm-strikethrough: 1.0.2 + mdast-util-gfm-table: 1.0.6 + mdast-util-gfm-task-list-item: 1.0.1 + mdast-util-to-markdown: 1.4.0 + transitivePeerDependencies: + - supports-color + dev: false + /mdast-util-mdx-expression/1.3.1: resolution: {integrity: sha512-TTb6cKyTA1RD+1su1iStZ5PAv3rFfOUKcoU5EstUpv/IZo63uDX03R8+jXjMEhcobXnNOiG6/ccekvVl4eV1zQ==} dependencies: @@ -1982,6 +2058,79 @@ packages: uvu: 0.5.6 dev: false + /micromark-extension-gfm-autolink-literal/1.0.3: + resolution: {integrity: sha512-i3dmvU0htawfWED8aHMMAzAVp/F0Z+0bPh3YrbTPPL1v4YAlCZpy5rBO5p0LPYiZo0zFVkoYh7vDU7yQSiCMjg==} + dependencies: + micromark-util-character: 1.1.0 + micromark-util-sanitize-uri: 1.1.0 + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + uvu: 0.5.6 + dev: false + + /micromark-extension-gfm-footnote/1.0.4: + resolution: {integrity: sha512-E/fmPmDqLiMUP8mLJ8NbJWJ4bTw6tS+FEQS8CcuDtZpILuOb2kjLqPEeAePF1djXROHXChM/wPJw0iS4kHCcIg==} + dependencies: + micromark-core-commonmark: 1.0.6 + micromark-factory-space: 1.0.0 + micromark-util-character: 1.1.0 + micromark-util-normalize-identifier: 1.0.0 + micromark-util-sanitize-uri: 1.1.0 + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + uvu: 0.5.6 + dev: false + + /micromark-extension-gfm-strikethrough/1.0.4: + resolution: {integrity: sha512-/vjHU/lalmjZCT5xt7CcHVJGq8sYRm80z24qAKXzaHzem/xsDYb2yLL+NNVbYvmpLx3O7SYPuGL5pzusL9CLIQ==} + dependencies: + micromark-util-chunked: 1.0.0 + micromark-util-classify-character: 1.0.0 + micromark-util-resolve-all: 1.0.0 + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + uvu: 0.5.6 + dev: false + + /micromark-extension-gfm-table/1.0.5: + resolution: {integrity: sha512-xAZ8J1X9W9K3JTJTUL7G6wSKhp2ZYHrFk5qJgY/4B33scJzE2kpfRL6oiw/veJTbt7jiM/1rngLlOKPWr1G+vg==} + dependencies: + micromark-factory-space: 1.0.0 + micromark-util-character: 1.1.0 + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + uvu: 0.5.6 + dev: false + + /micromark-extension-gfm-tagfilter/1.0.1: + resolution: {integrity: sha512-Ty6psLAcAjboRa/UKUbbUcwjVAv5plxmpUTy2XC/3nJFL37eHej8jrHrRzkqcpipJliuBH30DTs7+3wqNcQUVA==} + dependencies: + micromark-util-types: 1.0.2 + dev: false + + /micromark-extension-gfm-task-list-item/1.0.3: + resolution: {integrity: sha512-PpysK2S1Q/5VXi72IIapbi/jliaiOFzv7THH4amwXeYXLq3l1uo8/2Be0Ac1rEwK20MQEsGH2ltAZLNY2KI/0Q==} + dependencies: + micromark-factory-space: 1.0.0 + micromark-util-character: 1.1.0 + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + uvu: 0.5.6 + dev: false + + /micromark-extension-gfm/2.0.1: + resolution: {integrity: sha512-p2sGjajLa0iYiGQdT0oelahRYtMWvLjy8J9LOCxzIQsllMCGLbsLW+Nc+N4vi02jcRJvedVJ68cjelKIO6bpDA==} + dependencies: + micromark-extension-gfm-autolink-literal: 1.0.3 + micromark-extension-gfm-footnote: 1.0.4 + micromark-extension-gfm-strikethrough: 1.0.4 + micromark-extension-gfm-table: 1.0.5 + micromark-extension-gfm-tagfilter: 1.0.1 + micromark-extension-gfm-task-list-item: 1.0.3 + micromark-util-combine-extensions: 1.0.0 + micromark-util-types: 1.0.2 + dev: false + /micromark-extension-mdx-expression/1.0.3: resolution: {integrity: sha512-TjYtjEMszWze51NJCZmhv7MEBcgYRgb3tJeMAJ+HQCAaZHHRBaDCccqQzGizR/H4ODefP44wRTgOn2vE5I6nZA==} dependencies: @@ -2479,6 +2628,17 @@ packages: engines: {node: '>=8'} dev: true + /remark-gfm/3.0.1: + resolution: {integrity: sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==} + dependencies: + '@types/mdast': 3.0.10 + mdast-util-gfm: 2.0.1 + micromark-extension-gfm: 2.0.1 + unified: 10.1.2 + transitivePeerDependencies: + - supports-color + dev: false + /remark-mdx/2.2.1: resolution: {integrity: sha512-R9wcN+/THRXTKyRBp6Npo/mcbGA2iT3N4G8qUqLA5pOEg7kBidHv8K2hHidCMYZ6DXmwK18umu0K4cicgA2PPQ==} dependencies: diff --git a/src/FileInjector/FileInjector.ts b/src/FileInjector/FileInjector.ts index e126e8b..ddc3581 100644 --- a/src/FileInjector/FileInjector.ts +++ b/src/FileInjector/FileInjector.ts @@ -3,9 +3,10 @@ import * as path from 'node:path'; import assert from 'assert'; import chalk, { supportsColor } from 'chalk'; import type { Code, Content, Heading, HTML, Parent, Root } from 'mdast'; +import remarkGfm from 'remark-gfm'; import remarkParse from 'remark-parse'; import remarkStringify from 'remark-stringify'; -import { unified } from 'unified'; +import { type Processor, unified } from 'unified'; import { is } from 'unist-util-is'; import { remove } from 'unist-util-remove'; import { visit } from 'unist-util-visit'; @@ -262,8 +263,7 @@ async function processFileInjections( file.data.hasInjections = false; return file; } - const result = await unified() - .use(remarkParse) + const result = await initParser() .use(processHasInjections) .use(processInjections) .use(remarkStringify, outputOptions) @@ -403,7 +403,7 @@ async function processFileInjections( } function parseMarkdownFile(file: VFileEx): Root { - return unified().use(remarkParse).parse(file); + return initParser().parse(file); } function relativePathNormalized(path: URL, relDir?: URL): string { @@ -675,7 +675,7 @@ function toError(e: unknown): Error { function errorToComment(err: Error): Root { const msg = (err.message || err.toString()).split('\n').join('\n '); - return unified().use(remarkParse).parse(`\ + return initParser().parse(`\ `); @@ -699,3 +699,7 @@ function extractLines(content: string, lines: [number, number] | undefined): str function refersToTheSameFile(a: RelURL | URL, b: RelURL | URL): boolean { return a.pathname === b.pathname && a.search === b.search; } + +function initParser(): Processor { + return unified().use(remarkParse).use(remarkGfm); +} diff --git a/src/FileInjector/VFileEx.test.ts b/src/FileInjector/VFileEx.test.ts new file mode 100644 index 0000000..8823202 --- /dev/null +++ b/src/FileInjector/VFileEx.test.ts @@ -0,0 +1,9 @@ +import { describe, expect, test } from 'vitest'; + +import * as VFileEx from './VFileEx.js'; + +describe('VFileEx', () => { + test('VFileEx', () => { + expect(VFileEx).toBeDefined(); + }); +}); diff --git a/src/FileInjector/VFileEx.ts b/src/FileInjector/VFileEx.ts index 2748a8f..aae3b6e 100644 --- a/src/FileInjector/VFileEx.ts +++ b/src/FileInjector/VFileEx.ts @@ -1,6 +1,6 @@ import { Data as VFileData, VFile } from 'vfile'; -import { BufferEncoding } from '../FileSystemAdapter/FileSystemAdapter.js'; +import type { BufferEncoding } from '../FileSystemAdapter/FileSystemAdapter.js'; export interface FileData extends VFileData { encoding: BufferEncoding; diff --git a/src/FileInjector/__snapshots__/FileInjector.test.ts.snap b/src/FileInjector/__snapshots__/FileInjector.test.ts.snap index 180954a..ae0ae7f 100644 --- a/src/FileInjector/__snapshots__/FileInjector.test.ts.snap +++ b/src/FileInjector/__snapshots__/FileInjector.test.ts.snap @@ -111,6 +111,16 @@ async function version(): Promise { \`\`\` + +## GitHub Footnote + +| | version | Node | Support | End-Of-Life | +| :----- | :------ | :--- | :-------------------- | :---------- | +| cspell | 6.x | 14.x | In Active Development | TBD | +| cspell | 5.x | 12.x | Paid support only[^1] | 2022-10-01 | +| cspell | 4.x | 10.x | Paid support only[^1] | 2022-05-01 | + +[^1]: [Support - Street Side Software](https://streetsidesoftware.com/support/#maintenance-agreements) ", "utf8", ],