API Reference

This page describes all public APIs (functions, types, utilities) provided by md2form v2.

Export List

// Main functions
import { parseForm, createParser, isParsedDocument } from "md2form"
 
// Validation and diagnostic utilities
import { validateDocument, computeOk, hasErrorSeverity, diagnostic } from "md2form"
 
// Type definitions
import type {
  ParseOptions,
  ResolvedParseOptions,
  ParseResult,
  ParsedFormDocument,
  Diagnostic,
  DiagnosticCode,
  Severity,
  Parser,
  FormDocument,
  FormSettings,
  Page,
  FormElement,
  ElementType,
  // ...various question types
} from "md2form"
 
// Deprecated (v1 compatible)
import { parseMarkdownToForm } from "md2form"

Main Functions

parseForm

Parses Markdown text and returns a ParseResult. Main API for v2.

function parseForm(markdown: string, options?: ParseOptions): ParseResult

This is a synchronous function. No await is required.

Parameters

ParameterTypeRequiredDescription
markdownstringMarkdown string to parse
optionsParseOptions-Parse options

Return Value

Type: ParseResult

An object with { document, diagnostics, ok }. See ParseResult for details.

Usage Examples

Basic usage:

import { parseForm, isParsedDocument } from "md2form"
 
const markdown = `
# Sample Form
## Section1
### Question 1
#type short_text
#required true
`
 
const result = parseForm(markdown)
console.log(result.document.title) // "Sample Form"
console.log(result.ok) // true (default is strict: false so always true)

Strict mode (recommended for CI):

const result = parseForm(markdown, { strict: true, validateSettings: true })
 
if (!isParsedDocument(result)) {
  result.diagnostics
    .filter((d) => d.severity === "error")
    .forEach((d) => console.error(`${d.code}: ${d.message}`))
  process.exit(1)
}
 
const form = result.document

With frontmatter:

const markdownWithFrontmatter = `
---
collectEmail: true
showProgressBar: true
---
# Survey Form
## Basic Info
### Your Name
#type short_text
#required true
`
 
const result = parseForm(markdownWithFrontmatter)
console.log(result.document.settings?.collectEmail) // true

createParser

Creates a reusable Parser instance for parsing multiple Markdown files with the same options.

function createParser(options?: ParseOptions): Parser

Parameters

ParameterTypeRequiredDescription
optionsParseOptions-Parse options

Return Value

Type: Parser

An object with a parse(markdown: string): ParseResult method.

Usage Example

import { createParser } from "md2form"
 
const parser = createParser({ strict: false })
 
const result1 = parser.parse(markdown1)
const result2 = parser.parse(markdown2)
const result3 = parser.parse(markdown3)

Batch processing usage:

import { createParser } from "md2form"
import type { FormDocument } from "md2form"
 
const parser = createParser({ strict: true })
 
function processAll(markdowns: string[]): FormDocument[] {
  return markdowns
    .map((md) => parser.parse(md))
    .filter((r) => r.ok)
    .map((r) => r.document)
}

isParsedDocument

Checks if a ParseResult has no error-level diagnostics. Always returns true when strict: false (default). Returns true when there are no errors if strict: true.

function isParsedDocument(result: { ok: boolean; diagnostics: Diagnostic[] }): boolean

Usage Example

import { parseForm, isParsedDocument } from "md2form"
 
const result = parseForm(markdown, { strict: true })
 
if (isParsedDocument(result)) {
  // result.ok === true
  console.log(result.document.title)
} else {
  // error-level diagnostics exist
  console.error(result.diagnostics)
}

validateDocument

Validates the structure of a FormDocument and returns Diagnostic[]. parseForm / createParser automatically calls this when validateSettings: true (default).

function validateDocument(document: FormDocument): Diagnostic[]

Validation Content

  • dropdown / radio / checkbox: #options is required
  • likert: #statements and #scaleLabels are required
  • matrix: #rows and #columns are required
  • scale: #min and #max are required
  • image / video: #src is required

Usage Example

import { validateDocument } from "md2form"
import type { FormDocument } from "md2form"
 
// Re-validate a FormDocument received from external source
const diagnostics = validateDocument(form)
if (diagnostics.some((d) => d.severity === "error")) {
  console.error("Validation errors found:", diagnostics)
}

Diagnostic Utilities

hasErrorSeverity

function hasErrorSeverity(diagnostics: Diagnostic[]): boolean

Returns true if the diagnostics array contains at least one error-level item.

computeOk

function computeOk(diagnostics: Diagnostic[], strict: boolean): boolean

Returns true if strict: false. Returns !hasErrorSeverity(diagnostics) if strict: true.

diagnostic

function diagnostic(
  code: DiagnosticCode,
  severity: Severity,
  message: string,
  extra?: Pick<Diagnostic, "line" | "column" | "path">,
): Diagnostic

Factory function to construct a Diagnostic object.


Deprecated API

parseMarkdownToForm (deprecated)

⚠️ Deprecated in v2. Use parseForm for new code.

Kept for v1 compatibility. Returns only document and diagnostics cannot be obtained.

/** @deprecated Use `parseForm` instead. */
function parseMarkdownToForm(markdown: string): Promise<FormDocument>

Migration Guide

// ❌ v1 (deprecated)
const form = await parseMarkdownToForm(markdown)
 
// ✅ v2 (recommended)
const result = parseForm(markdown)
const form = result.document
 
// or with strict mode
const result = parseForm(markdown, { strict: true })
if (!isParsedDocument(result)) throw new Error("Parse error")
const form = result.document

Type Definitions

ParseOptions

Options passed to parseForm / createParser.

type ParseOptions = {
  /** When there are error-level diagnostics, ok === false (default: false) */
  strict?: boolean
  /** Fallback when title is not detected (default: "Untitled Form") */
  defaultTitle?: string
  /** Validate settings as FormSettings (default: true) */
  validateSettings?: boolean
}
FieldTypeDefaultDescription
strictbooleanfalseIf true, ok === false when there are errors
defaultTitlestring"Untitled Form"Fallback when # Title is not found
validateSettingsbooleantrueWhether to validate frontmatter

ParseResult

Return value of parseForm.

type ParseResult = {
  document: FormDocument // Parsed form definition
  diagnostics: Diagnostic[] // Error, warning, and info messages
  ok: boolean // false if there are errors in strict mode
}

When strict: false (default), ok is always true. document is always returned even if there are issues (partially recovered result).


ParsedFormDocument

Brand type for use when ok === true (for future type guard extensions).

type ParsedFormDocument = FormDocument & {
  readonly __brand?: unique symbol
}

Diagnostic

Individual diagnostic message.

type Diagnostic = {
  code: DiagnosticCode // Diagnostic identifier code
  severity: Severity // "error" | "warning" | "info"
  message: string // Human-readable message
  line?: number // Line number of the issue (if any)
  column?: number // Column number of the issue (if any)
  path?: string // Path to the problematic element (if any)
}

DiagnosticCode

Enumeration of diagnostic codes.

type DiagnosticCode =
  | "MISSING_FORM_TITLE" // # title not found
  | "MISSING_ELEMENT_TYPE" // #type not specified for question
  | "UNSUPPORTED_ELEMENT_TYPE" // Unknown #type value
  | "UNSUPPORTED_PROPERTY" // Unknown property key
  | "INVALID_PROPERTY_VALUE" // Invalid property value format
  | "MISSING_REQUIRED_FIELD" // Required field not specified (during validation)
  | "PROPERTY_BEFORE_TYPE" // Property defined before #type
  | "ORPHAN_QUESTION" // Question not belonging to a section
  | "AMBIGUOUS_STRUCTURE" // Structure is ambiguous
  | "UNKNOWN_SETTING_KEY" // Unknown key in frontmatter
  | "INVALID_SETTING_VALUE" // Invalid value in frontmatter

Severity

type Severity = "error" | "warning" | "info"
ValueDescription
"error"Issues that need fixing. If strict: true, ok: false
"warning"Works but not recommended usage
"info"Reference information

Parser

Return type of createParser.

type Parser = {
  parse(markdown: string): ParseResult
}

Importing Type Definitions

You can import all type definitions directly from md2form:

// Core types
import type { FormDocument, FormSettings, Page, FormElement, ElementType } from "md2form"
 
// v2 API types
import type {
  ParseOptions,
  ResolvedParseOptions,
  ParseResult,
  ParsedFormDocument,
  Diagnostic,
  DiagnosticCode,
  Severity,
  Parser,
} from "md2form"
 
// Individual question types
import type {
  ShortText,
  LongText,
  NumberField,
  EmailField,
  PhoneField,
  DropdownField,
  RadioField,
  CheckboxField,
  DateField,
  TimeField,
  RatingField,
  LikertField,
  MatrixField,
  ScaleField,
  FileUploadField,
  SignatureField,
  MediaField,
  BooleanField,
  SectionHeader,
} from "md2form"
 
// Union types for text input
import type { TextInputElement } from "md2form"

Advanced Usage Examples

Implementing a Diagnostic Reporter

import { parseForm } from "md2form"
import type { Diagnostic, Severity } from "md2form"
 
const ICONS: Record<Severity, string> = {
  error: "❌",
  warning: "⚠️",
  info: "ℹ️",
}
 
function reportDiagnostics(diagnostics: Diagnostic[]): void {
  if (diagnostics.length === 0) {
    console.log("✅ No issues found")
    return
  }
 
  for (const d of diagnostics) {
    const loc = d.line != null ? ` (line ${d.line})` : ""
    const path = d.path ? ` [${d.path}]` : ""
    console.log(`${ICONS[d.severity]} ${d.code}${path}${loc}: ${d.message}`)
  }
}
 
const result = parseForm(markdown, { strict: true })
reportDiagnostics(result.diagnostics)

Batch Processing (Validating Multiple Files)

import { createParser } from "md2form"
import type { FormDocument } from "md2form"
 
const parser = createParser({ strict: true, validateSettings: true })
 
interface BatchResult {
  filename: string
  ok: boolean
  form?: FormDocument
  errors: string[]
}
 
function processBatch(files: Array<{ name: string; content: string }>): BatchResult[] {
  return files.map(({ name, content }) => {
    const result = parser.parse(content)
    return {
      filename: name,
      ok: result.ok,
      form: result.ok ? result.document : undefined,
      errors: result.diagnostics
        .filter((d) => d.severity === "error")
        .map((d) => `${d.code}: ${d.message}`),
    }
  })
}
 
const results = processBatch([
  { name: "contact.md", content: contactMarkdown },
  { name: "survey.md", content: surveyMarkdown },
])
 
const failed = results.filter((r) => !r.ok)
if (failed.length > 0) {
  console.error(`${failed.length} file(s) have errors:`)
  failed.forEach((r) => {
    console.error(`  ${r.filename}:`)
    r.errors.forEach((e) => console.error(`    - ${e}`))
  })
}

Custom Validation (Using validateDocument)

import { parseForm, validateDocument } from "md2form"
import type { FormDocument, Diagnostic } from "md2form"
 
function validateFormBusiness(document: FormDocument): Diagnostic[] {
  // Custom business logic validation
  const diagnostics: Diagnostic[] = []
 
  if (document.pages.length === 0) {
    diagnostics.push({
      code: "AMBIGUOUS_STRUCTURE",
      severity: "error",
      message: "Form must have at least 1 section",
    })
  }
 
  if (!document.settings?.collectEmail) {
    diagnostics.push({
      code: "MISSING_REQUIRED_FIELD",
      severity: "warning",
      message: "collectEmail setting is recommended",
    })
  }
 
  return diagnostics
}
 
const result = parseForm(markdown)
const builtinDiagnostics = validateDocument(result.document)
const customDiagnostics = validateFormBusiness(result.document)
 
const allDiagnostics = [...builtinDiagnostics, ...customDiagnostics]

Next Steps

Version Information

This API reference is based on md2form v2.0.0.