Skip to content

Str.Code.Md

Str.Code / Md

Import

typescript
import { Str } from '@wollybeard/kit'

// Access via namespace
Str.Code.Md.someFunction()
typescript
import * as Str from '@wollybeard/kit/str'

// Access via namespace
Str.Code.Md.someFunction()

Namespaces

  • md - Structured markdown helpers.

These helpers generate properly formatted markdown elements. All helpers return Raw (already formatted) or null for graceful handling.

Functions

[F] raw

typescript
(content: string): Raw

Mark content as already-formatted markdown (won't be processed further).

Use this for pre-formatted markdown syntax that should be injected as-is.

Examples:

typescript
const 
formattedLink
=
Str
.Code.Md.raw('[Example](https://example.com)')
const
doc
= builder()
doc
`Check out ${
formattedLink
}`

[F] code

typescript
(value: string): string

Wrap value in markdown inline code (backticks).

Examples:

typescript
Str
.Code.Md.code('hello') // '`hello`'
Str
.Code.Md.code('Array<T>') // '`Array<T>`'
typescript
(url: string, text?: string | undefined): string

Create a markdown inline link.

If text is not provided, the URL is used as both the link text and target.

Examples:

typescript
Str
.Code.Md.link('https://example.com', 'Example')
// '[Example](https://example.com)'
Str
.Code.Md.link('https://example.com')
// '[https://example.com](https://example.com)' // Compose for bold code links:
Str
.Code.Md.link('/api/foo', `**${code('Foo')}**`)
// '[**`Foo`**](/api/foo)'

[F] heading

typescript
(level: number, text: string): string

Create a markdown heading.

[F] codeFence

typescript
(code: string, language?: string = 'typescript', modifiers?: string | undefined): string

Create a code fence with optional language and modifiers.

[F] codeGroup

typescript
(tabs: { label: string; code: string; language?: string; modifiers?: string; }[]): string

Create a VitePress code group with multiple tabs.

Examples:

typescript
Str
.Code.Md.codeGroup([
{
label
: 'npm',
code
: 'npm install foo',
language
: 'bash' },
{
label
: 'pnpm',
code
: 'pnpm add foo',
language
: 'bash' },
])

[F] container

typescript
(type: "warning" | "tip" | "info" | "danger", title: string, content: string): string

Create a VitePress custom container (warning, tip, etc.).

[F] deprecation

typescript
(message: string): string

Create a deprecation warning with proper link conversion.

[F] listItem

typescript
(text: string, level?: number = 0): string

Create an unordered list item.

[F] sub

typescript
(text: string): string

Create a sub-text annotation (smaller font).

typescript
(text: string): string

Convert JSDoc

tags to markdown links.

Patterns:

description

For Effect library references (String., Array., etc.), links to Effect documentation.

[F] demoteHeadings

typescript
(markdown: string, levels: number): string

Parameters:

  • markdown - The markdown content to transform
  • levels - Number of heading levels to add (e.g., 2 transforms ## to ####)

Returns: Transformed markdown with demoted headings

Demote markdown headings by adding a specified number of levels.

This is used to ensure JSDoc descriptions don't break the document hierarchy. For example, if an export is h3, its description headings should be h4+.

[F] sections

typescript
(...parts?: (string | false | null | undefined)[]): string

Join markdown sections with double newlines, filtering out empty sections.

[F] kebab

typescript
(str: string): string

Convert string to kebab-case.

[F] table

typescript
(rows: Record<string, string | null | undefined>): string

Generate a markdown table from key-value pairs.

Automatically filters out undefined and null values. Returns empty string if no valid entries remain after filtering.

Examples:

typescript
Str
.Code.Md.table({
'Name': 'Alice', 'Age': '30', 'City':
undefined
, // filtered out
}) // | | | // | - | - | // | **Name** | Alice | // | **Age** | 30 |

[F] builder

typescript
(): Builder

Create a new markdown builder for imperative construction.

Perfect for markdown generation with conditionals, loops, and complex logic.

Examples:

typescript
const 
doc
=
Str
.Code.Md.builder()
doc
`# ${title}`
doc
.blank()
doc
`Main description`
if (showExample) {
doc
.codeFence('const x = 1', 'ts')
} return
doc
.build()

Constants

[C] template

typescript
Template

Tagged template for building markdown content. Also provides .builder() for imperative construction and .md for element helpers.

Examples:

typescript
// Template mode
const 
doc
= template`
# API Reference ${description} ${
Str
.Code.Md.template.md.link('Docs', 'https://example.com')}
` // Builder mode for complex logic const
doc
=
Str
.Code.Md.template.builder()
doc
.heading(1, 'API Reference')
doc
.blank()
if (hasDescription) {
doc
.add(description)
} return
doc
.build()

Types

[I] Raw

typescript
interface Raw {
  readonly __markdownFormatted: true
  readonly content: string
}

Branded type for markdown content that's already formatted and safe.

Use raw to create values of this type.

[I] Builder

typescript
interface Builder {
  /**
   * Add a line to the markdown via tagged template.
   * Use empty template for blank lines: `doc\`\``
   */
  (
    strings: TemplateStringsArray,
    ...values: Array<string | number | Raw | null | undefined>
  ): Builder

  /**
 * Add content directly. Skips if null/undefined.
 * Perfect for chaining with optional content.
 *
 * @example
 *
```ts
   * doc
   *   .add(description)  // skips if null/undefined
   *   .add('## Info')
   * ```
   */
  add(content: string | null | undefined): Builder

  /**
   * Add raw formatted markdown without processing. Skips if null/undefined.
   *
   * @example
   * ```ts
   * doc.addRaw(preFormattedMarkdown)
   * ```
   */
  addRaw(content: string | null | undefined): Builder

  /**
   * Add a blank line.
   *
   * @example
   * ```ts
   * doc
   *   .add('First paragraph')
   *   .blank()
   *   .add('Second paragraph')
   * ```
   */
  blank(): Builder

  /**
   * Add a markdown heading.
   *
   * @example
   * ```ts
   * doc.heading(2, 'API Reference')
   * ```
   */
  heading(level: number, text: string): Builder

  /**
   * Add a markdown link.
   * If text is not provided, url is used as both text and URL.
   *
   * @example
   * ```ts
   * doc.link('https://example.com', 'Example')
   * doc.link('https://example.com')  // text defaults to URL
   * // Compose for bold code: doc`[**\`Foo\`**](/api/foo)`
   * ```
   */
  link(url: string, text?: string): Builder

  /**
   * Add a code fence with optional language.
   * Skips if code is null/undefined.
   *
   * @example
   * ```ts
   * doc.codeFence('const x = 1', 'typescript')
   * ```
   */
  codeFence(
    code: string | null | undefined,
    language?: string,
    modifiers?: string,
  ): Builder

  /**
   * Add a VitePress code group with multiple tabs.
   *
   * @example
   * ```ts
   * doc.codeGroup([
   *   { label: 'npm', code: 'npm install foo', language: 'bash' },
   *   { label: 'pnpm', code: 'pnpm add foo', language: 'bash' }
   * ])
   * ```
   */
  codeGroup(
    tabs: Array<
      { label: string; code: string; language?: string; modifiers?: string }
    >,
  ): Builder

  /**
   * Add a list item.
   *
   * @example
   * ```ts
   * doc.listItem('First item')
   * doc.listItem('Nested item', 1)
   * ```
   */
  listItem(text: string, level?: number): Builder

  /**
   * Add a markdown table from key-value pairs.
   * Automatically filters out undefined/null values.
   *
   * @example
   * ```ts
   * doc.table({
   *   'Type': 'string',
   *   'Required': 'Yes'
   * })
   * ```
   */
  table(rows: Record<string, string | Raw | undefined | null>): Builder

  /**
   * Add a VitePress container.
   *
   * @example
   * ```ts
   * doc.container('warning', 'Deprecated', 'Use newMethod() instead')
   * ```
   */
  container(
    type: 'warning' | 'tip' | 'info' | 'danger',
    title: string,
    content: string,
  ): Builder

  /**
   * Build the final markdown string with whitespace normalization.
   */
  build(): string
}

Markdown builder interface for imperative markdown construction.

Provides a fluent API for building markdown with conditionals, loops, and helpers.

Examples:

typescript
const 
doc
= builder()
doc
`# API Reference`
doc
.blank()
doc
`Main description here.`
if (showTable) {
doc
.table({ 'Type': 'string', 'Required': 'Yes' })
}
doc
.codeFence('const x = 1', 'typescript')
return
doc
.build()

[I] Template

typescript
interface Template {
  /**
 * Tagged template for building markdown content.
 *
 * @example
 *
```ts
   * const doc = template`
   *   # ${title}
   *
   *   ${description}
   *
   *   ${md.link('Example', 'https://example.com')}
   * `
   * ```
   */
  (
    strings: TemplateStringsArray,
    ...values: Array<string | number | Raw | null | undefined>
  ): string

  /**
   * Create a new markdown builder for imperative construction.
   */
  builder: typeof builder

  /**
   * Create a markdown generator function from a builder callback.
   * Automatically calls `.build()` and returns the result.
   *
   * @example
   * ```ts
   * export const getDoc = factory<[title: string, items: string[]]>((doc, title, items) => {
   *   doc.heading(1, title)
   *   doc.blank()
   *   items.forEach(item => doc.listItem(item))
   * })
   *
   * // Usage: getDoc('My Title', ['item1', 'item2']) -> string
   * ```
   */
  factory: <$Args extends any[]>(
    fn: (doc: Builder, ...args: $Args) => void,
  ) => (...args: $Args) => string

  /**
   * Markdown element helpers for generating formatted elements.
   */
  md: typeof md
}

Markdown template function type with builder property.