diff --git a/AGENTS.md b/AGENTS.md index fed0afd9..93839c47 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -152,12 +152,12 @@ Located at `packages/comark-ansi/`. ANSI terminal renderer. ### Usage ```typescript -import { createAnsiRenderer, createAnsiWriter, renderAnsi, renderAnsiFromDocument, writeAnsi } from '@comark/ansi' +import { createAnsiRenderer, createAnsiPrinter, printAnsi, renderAnsi, renderAnsiFromDocument } from '@comark/ansi' import shiki from '@comark/ansi/plugins/shiki' import math, { Math } from '@comark/ansi/plugins/math' // Flat options — ParserOptions & AnsiRendererOptions merged at top level -const writeAnsi = createAnsiWriter({ +const printAnsi = createAnsiPrinter({ plugins: [shiki(), math()], components: { Math }, width: 120, // terminal width @@ -165,7 +165,7 @@ const writeAnsi = createAnsiWriter({ writer: (output) => process.stderr.write(output), }) -await writeAnsi(markdownString) +await printAnsi(markdownString) ``` --- @@ -382,7 +382,7 @@ import { parseMarkdown, autoCloseMarkdown } from 'comark' import { createHtmlRenderer, renderHtml, renderHtmlFromDocument } from '@comark/html' // ANSI terminal rendering -import { createAnsiRenderer, createAnsiWriter, renderAnsi, renderAnsiFromDocument, writeAnsi } from '@comark/ansi' +import { createAnsiRenderer, createAnsiPrinter, printAnsi, renderAnsi, renderAnsiFromDocument } from '@comark/ansi' // Markdown string rendering (AST → markdown) import { renderMarkdown } from 'comark/render' @@ -425,7 +425,7 @@ import math, { Math } from '@comark/html/plugins/math' import mermaid, { Mermaid } from '@comark/html/plugins/mermaid' // ANSI terminal rendering — parse + render to styled terminal string -import { createAnsiRenderer, createAnsiWriter, renderAnsi, renderAnsiFromDocument, writeAnsi } from '@comark/ansi' +import { createAnsiRenderer, createAnsiPrinter, printAnsi, renderAnsi, renderAnsiFromDocument } from '@comark/ansi' import shiki from '@comark/ansi/plugins/shiki' import math from '@comark/ansi/plugins/math' diff --git a/benchmarks/plugin-punctuation.ts b/benchmarks/plugin-punctuation.ts index 337ae188..c7a013b3 100644 --- a/benchmarks/plugin-punctuation.ts +++ b/benchmarks/plugin-punctuation.ts @@ -3,7 +3,7 @@ import MarkdownExit from 'markdown-exit' import { markdownItComponents } from 'comark/plugins/components' import { markdownItAttributes } from 'comark/plugins/attributes' import { createMarkdownParser } from 'comark' -import { writeAnsi } from '@comark/ansi' +import { printAnsi } from '@comark/ansi' import punctuation from '../packages/comark/src/plugins/punctuation' // ── Test content (exercises ALL features: quotes, dashes, ellipsis, symbols, normalization) ── @@ -146,7 +146,7 @@ console.log('comark punctuation: ', JSON.stringify(flattenText(comarkTree.no console.log('\n🏃 Running benchmarks...\n') await run() -await writeAnsi(`> [!NOTE] +await printAnsi(`> [!NOTE] > The goal of this benchmark is to compare the additional time each parser takes when > using punctuation plugins. > diff --git a/docs/content/3.rendering/8.ansi.md b/docs/content/3.rendering/8.ansi.md index 75e1fca8..2b63de4c 100644 --- a/docs/content/3.rendering/8.ansi.md +++ b/docs/content/3.rendering/8.ansi.md @@ -172,16 +172,20 @@ Same as [`renderAnsi()`](#renderansi-options). --- -## `writeAnsi()` +## `printAnsi()` Parse and print markdown directly to `stdout` in one call. +::note +`printAnsi()` replaces `writeAnsi()`, which is deprecated and will be removed in the next major version. +:: + ### Usage ```ts -import { writeAnsi } from '@comark/ansi' +import { printAnsi } from '@comark/ansi' -await writeAnsi(` +await printAnsi(` # Hello World This is **bold**, _italic_, and \`inline code\`. @@ -196,10 +200,10 @@ This is **bold**, _italic_, and \`inline code\`. Pass options to configure the parser, renderer, or output destination using `writer`: ```ts -import { writeAnsi } from '@comark/ansi' +import { printAnsi } from '@comark/ansi' import math, { Math } from '@comark/ansi/plugins/math' -await writeAnsi('Inline $E = mc^2$', { +await printAnsi('Inline $E = mc^2$', { plugins: [math()], components: { Math }, width: 100, @@ -209,31 +213,35 @@ await writeAnsi('Inline $E = mc^2$', { They are the same options as [`renderAnsi()`](#renderansi-options) plus the `writer?: (string: string) => void` option. -### `createAnsiWriter()` +### `createAnsiPrinter()` -Creates a reusable writer with pre-configured options. The underlying parser is initialized once and reused on every call, which is more efficient when writing many documents. +Creates a reusable printer with pre-configured options. The underlying parser is initialized once and reused on every call, which is more efficient when printing many documents. + +::note +`createAnsiPrinter()` replaces `createAnsiWriter()`, which is deprecated and will be removed in the next major version. +:: #### Usage ```ts -import { createAnsiWriter } from '@comark/ansi' +import { createAnsiPrinter } from '@comark/ansi' import math, { Math } from '@comark/ansi/plugins/math' import shiki from '@comark/ansi/plugins/shiki' -const write = createAnsiWriter({ +const print = createAnsiPrinter({ plugins: [math(), shiki()], components: { Math }, width: 120, }) -// Reuse the same configured parser & writer -await write('# Document 1\n\n...') -await write('# Document 2\n\n...') +// Reuse the same configured parser & printer +await print('# Document 1\n\n...') +await print('# Document 2\n\n...') ``` #### Options -Same as [`writeAnsi()`](#writeansi-options). +Same as [`printAnsi()`](#printansi-options). --- @@ -329,12 +337,12 @@ Each type has its own color: NOTE → blue, TIP → green, IMPORTANT → magenta Code blocks show the language and filename in a header line. When the `shiki` plugin is used, tokens are rendered with true-color ANSI (`\x1b[38;2;R;G;Bm`) derived from Shiki's dark theme: ```typescript -import { createAnsiWriter } from '@comark/ansi' +import { createAnsiPrinter } from '@comark/ansi' import shiki from '@comark/ansi/plugins/shiki' -const writeAnsi = createAnsiWriter({ plugins: [shiki()] }) +const printAnsi = createAnsiPrinter({ plugins: [shiki()] }) -await writeAnsi('```typescript [app.ts]\nconsole.log("hello")\n```') +await printAnsi('```typescript [app.ts]\nconsole.log("hello")\n```') // typescript app.ts // console.log("hello") ← syntax highlighted ``` @@ -344,12 +352,12 @@ await writeAnsi('```typescript [app.ts]\nconsole.log("hello")\n```') Math expressions from the `math` plugin render as colored LaTeX source: inline in yellow, block in magenta: ```typescript -import { createAnsiWriter } from '@comark/ansi' +import { createAnsiPrinter } from '@comark/ansi' import math, { Math } from '@comark/ansi/plugins/math' -const writeAnsi = createAnsiWriter({ plugins: [math()], components: { Math } }) +const printAnsi = createAnsiPrinter({ plugins: [math()], components: { Math } }) -await writeAnsi('Inline $E = mc^2$ and block:\n\n$$\n\\frac{a}{b}\n$$') +await printAnsi('Inline $E = mc^2$ and block:\n\n$$\n\\frac{a}{b}\n$$') ``` ### Tables diff --git a/docs/content/5.reference/3.reference.md b/docs/content/5.reference/3.reference.md index 7410ad2d..9988cb9f 100644 --- a/docs/content/5.reference/3.reference.md +++ b/docs/content/5.reference/3.reference.md @@ -160,28 +160,28 @@ const output = await renderAnsiFromDocument(document) process.stdout.write(output) ``` -#### `writeAnsi(markdown, options?)` +#### `printAnsi(markdown, options?)` -Parse and render markdown directly to stdout. +Parse and render markdown directly to stdout. Replaces the deprecated `writeAnsi` alias. ```typescript -import { writeAnsi } from '@comark/ansi' +import { printAnsi } from '@comark/ansi' -await writeAnsi('# Hello\n\nThis is **bold**.') +await printAnsi('# Hello\n\nThis is **bold**.') ``` -#### `createAnsiWriter(options?)` +#### `createAnsiPrinter(options?)` -Create a reusable Markdown writer. Pass `writer` to target something other than `process.stdout`. +Create a reusable Markdown printer. Pass `writer` to target something other than `process.stdout`. Replaces the deprecated `createAnsiWriter` alias. ```typescript -import { createAnsiWriter } from '@comark/ansi' +import { createAnsiPrinter } from '@comark/ansi' -const writeAnsi = createAnsiWriter({ +const printAnsi = createAnsiPrinter({ writer: (output) => process.stderr.write(output), }) -await writeAnsi('# Hello') +await printAnsi('# Hello') ``` --- @@ -353,8 +353,8 @@ import { renderAnsi, renderAnsiFromDocument, createAnsiRenderer, - writeAnsi, - createAnsiWriter, + printAnsi, + createAnsiPrinter, } from '@comark/ansi' // Vue diff --git a/docs/skills/comark/AGENTS.md b/docs/skills/comark/AGENTS.md index ad1ddd67..48ae692a 100644 --- a/docs/skills/comark/AGENTS.md +++ b/docs/skills/comark/AGENTS.md @@ -177,18 +177,18 @@ export class ChatComponent { Use `@comark/ansi` to render LLM markdown output in terminal-based agents: ```typescript -import { writeAnsi } from '@comark/ansi' +import { printAnsi } from '@comark/ansi' // Print a complete LLM response to stdout with ANSI styling -await writeAnsi(llmResponse) +await printAnsi(llmResponse) ``` -For repeated terminal output, use `createAnsiWriter` with a custom `writer` function: +For repeated terminal output, use `createAnsiPrinter` with a custom `writer` function: ```typescript -import { createAnsiWriter } from '@comark/ansi' +import { createAnsiPrinter } from '@comark/ansi' -const writeMarkdown = createAnsiWriter({ +const writeMarkdown = createAnsiPrinter({ writer: (output) => process.stdout.write(output), }) diff --git a/examples/3.cli/ansi/render.ts b/examples/3.cli/ansi/render.ts index 9fd44d71..12158c09 100644 --- a/examples/3.cli/ansi/render.ts +++ b/examples/3.cli/ansi/render.ts @@ -1,10 +1,10 @@ import { readFile } from 'node:fs/promises' -import { writeAnsi } from '@comark/ansi' +import { printAnsi } from '@comark/ansi' import shiki from '@comark/ansi/plugins/shiki' import math, { Math } from '@comark/ansi/plugins/math' const md = await readFile('source.md', 'utf-8') -await writeAnsi(md, { +await printAnsi(md, { plugins: [shiki(), math()], components: { Math }, }) diff --git a/packages/comark-ansi/README.md b/packages/comark-ansi/README.md index 547b8291..702a0a29 100644 --- a/packages/comark-ansi/README.md +++ b/packages/comark-ansi/README.md @@ -71,18 +71,18 @@ const output = await renderAnsi('```ts\nconsole.log("hi")\n```', { - `renderAnsi(markdown, options?)` parses and renders Markdown to an ANSI string. - `createAnsiRenderer(options?)` creates a reusable parse-and-render function. - `renderAnsiFromDocument(document, options?)` renders a pre-parsed `MarkdownDocument`. -- `writeAnsi(markdown, options?)` parses and writes Markdown to `process.stdout` or a custom `writer`. -- `createAnsiWriter(options?)` creates a reusable writer. +- `printAnsi(markdown, options?)` parses and writes Markdown to `process.stdout` or a custom `writer`. (`writeAnsi` is a deprecated alias.) +- `createAnsiPrinter(options?)` creates a reusable printer. (`createAnsiWriter` is a deprecated alias.) ```ts -import { createAnsiWriter } from '@comark/ansi' +import { createAnsiPrinter } from '@comark/ansi' -const writeAnsi = createAnsiWriter({ +const printAnsi = createAnsiPrinter({ colors: false, writer: (output) => process.stderr.write(output), }) -await writeAnsi('# Build complete') +await printAnsi('# Build complete') ``` ## Documentation diff --git a/packages/comark-ansi/src/index.ts b/packages/comark-ansi/src/index.ts index 51c6104a..c5adee6a 100644 --- a/packages/comark-ansi/src/index.ts +++ b/packages/comark-ansi/src/index.ts @@ -13,34 +13,41 @@ function defaultWriter(string: string) { } /** - * Options for creating an ANSI writer. + * Options for creating an ANSI printer. */ -export interface AnsiWriterOptions extends AnsiRendererOptions, ParserOptions { +export interface AnsiPrinterOptions extends AnsiRendererOptions, ParserOptions { writer?: (string: string) => void } /** - * Creates a reusable writer with pre-configured parse and render options. + * Options for creating an ANSI printer. + * + * @deprecated Use {@link AnsiPrinterOptions} instead. Will be removed in the next major version. + */ +export type AnsiWriterOptions = AnsiPrinterOptions + +/** + * Creates a reusable printer with pre-configured parse and render options. * * @param options - Comark parse and render options (plugins, autoClose, etc.) * @returns An async function `(markdown) => Promise` that prints to stdout * * @example * ```typescript - * import { createAnsiWriter } from '@comark/ansi' + * import { createAnsiPrinter } from '@comark/ansi' * import math, { Math } from '@comark/ansi/plugins/math' * - * const writeAnsi = createAnsiWriter({ + * const printAnsi = createAnsiPrinter({ * plugins: [math()], * components: { Math }, * width: 120, * writer: (s) => process.stderr.write(s) * }) * - * await writeAnsi('# Hello\n\nThis is **bold**.') + * await printAnsi('# Hello\n\nThis is **bold**.') * ``` */ -export function createAnsiWriter(options?: AnsiWriterOptions): (markdown: string) => Promise { +export function createAnsiPrinter(options?: AnsiPrinterOptions): (markdown: string) => Promise { const renderAnsi = createAnsiRenderer(options as AnsiRendererOptions) const write = options?.writer ?? defaultWriter return async (markdown: string) => { @@ -49,6 +56,13 @@ export function createAnsiWriter(options?: AnsiWriterOptions): (markdown: string } } +/** + * Creates a reusable printer with pre-configured parse and render options. + * + * @deprecated Use {@link createAnsiPrinter} instead. Will be removed in the next major version. + */ +export const createAnsiWriter = createAnsiPrinter + /** * Parse markdown and print it as ANSI-styled output to stdout. * @@ -57,15 +71,22 @@ export function createAnsiWriter(options?: AnsiWriterOptions): (markdown: string * * @example * ```typescript - * import { writeAnsi } from '@comark/ansi' + * import { printAnsi } from '@comark/ansi' * - * await writeAnsi('# Hello\n\nThis is **bold** and _italic_.') + * await printAnsi('# Hello\n\nThis is **bold** and _italic_.') * ``` */ -export async function writeAnsi(markdown: string, options?: AnsiWriterOptions): Promise { - return createAnsiWriter(options)(markdown) +export async function printAnsi(markdown: string, options?: AnsiPrinterOptions): Promise { + return createAnsiPrinter(options)(markdown) } +/** + * Parse markdown and print it as ANSI-styled output to stdout. + * + * @deprecated Use {@link printAnsi} instead. Will be removed in the next major version. + */ +export const writeAnsi = printAnsi + /** * Creates a reusable render function with pre-configured parse and render options. * diff --git a/packages/comark-ansi/test/index.test.ts b/packages/comark-ansi/test/index.test.ts index d8e38212..0439a89d 100644 --- a/packages/comark-ansi/test/index.test.ts +++ b/packages/comark-ansi/test/index.test.ts @@ -2,7 +2,15 @@ import { afterEach, describe, it, expect, vi } from 'vitest' import { parseMarkdown } from 'comark' import shiki from 'comark/plugins/shiki' import githubDark from 'shiki/dist/themes/github-dark.mjs' -import { createAnsiRenderer, createAnsiWriter, renderAnsi, renderAnsiFromDocument, writeAnsi } from '../src/index' +import { + createAnsiPrinter, + createAnsiRenderer, + createAnsiWriter, + printAnsi, + renderAnsi, + renderAnsiFromDocument, + writeAnsi, +} from '../src/index' afterEach(() => { vi.unstubAllEnvs() @@ -468,59 +476,67 @@ describe('createAnsiRenderer', () => { }) }) -describe('createAnsiWriter', () => { +describe('createAnsiPrinter', () => { it('returns a function', () => { - const write = createAnsiWriter() - expect(typeof write).toBe('function') + const print = createAnsiPrinter() + expect(typeof print).toBe('function') }) it('calls writer with rendered output', async () => { const written: string[] = [] - const write = createAnsiWriter({ writer: (string) => written.push(string) }) - await write('# Hello') + const print = createAnsiPrinter({ writer: (string) => written.push(string) }) + await print('# Hello') expect(written).toHaveLength(1) expect(written[0]).toContain('Hello') }) it('appends newline to output', async () => { const written: string[] = [] - const write = createAnsiWriter({ writer: (string) => written.push(string) }) - await write('Hello') + const print = createAnsiPrinter({ writer: (string) => written.push(string) }) + await print('Hello') expect(written[0]).toMatch(/\n$/) }) it('reuses parser across calls', async () => { const written: string[] = [] - const write = createAnsiWriter({ writer: (string) => written.push(string) }) - await write('# Doc 1') - await write('# Doc 2') + const print = createAnsiPrinter({ writer: (string) => written.push(string) }) + await print('# Doc 1') + await print('# Doc 2') expect(written[0]).toContain('Doc 1') expect(written[1]).toContain('Doc 2') }) it('passes render options through', async () => { const written: string[] = [] - const write = createAnsiWriter({ + const print = createAnsiPrinter({ colors: false, writer: (string) => written.push(string), }) - await write('**bold**') + await print('**bold**') expect(written[0]).not.toContain('\x1B[') expect(written[0]).toContain('bold') }) }) -describe('writeAnsi', () => { +describe('printAnsi', () => { it('calls writer with rendered output', async () => { const written: string[] = [] - await writeAnsi('# Title', { writer: (string) => written.push(string) }) + await printAnsi('# Title', { writer: (string) => written.push(string) }) expect(written).toHaveLength(1) expect(written[0]).toContain('Title') }) it('calls writer once per invocation', async () => { const writer = vi.fn() - await writeAnsi('Hello', { writer }) + await printAnsi('Hello', { writer }) expect(writer).toHaveBeenCalledTimes(1) }) + + it('keeps writeAnsi as a deprecated alias', () => { + expect(writeAnsi).toBe(printAnsi) + }) + + it('keeps createAnsiWriter as a deprecated alias', () => { + expect(createAnsiWriter).toBe(createAnsiPrinter) + }) }) diff --git a/test/bundle.test.ts b/test/bundle.test.ts index 6f5c8055..be448f89 100644 --- a/test/bundle.test.ts +++ b/test/bundle.test.ts @@ -61,7 +61,7 @@ describe('package bundle size', { timeout: 60_000 }, () => { expect(report).toMatchInlineSnapshot(` { "@comark/angular": "54.3k (70 files)", - "@comark/ansi": "38.7k (98 files)", + "@comark/ansi": "39.9k (98 files)", "@comark/html": "18.6k (58 files)", "@comark/nuxt": "11.8k (58 files)", "@comark/react": "43.6k (74 files)",