@stacksjs/ts-md 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +151 -0
- package/LICENSE.md +21 -0
- package/README.md +121 -0
- package/bin/cli.ts +86 -0
- package/dist/config.d.ts +5 -0
- package/dist/frontmatter.d.ts +17 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +1130 -0
- package/dist/index.js.map +13 -0
- package/dist/parser.d.ts +3 -0
- package/dist/types.d.ts +67 -0
- package/dist/yaml.d.ts +9 -0
- package/package.json +99 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/yaml.ts", "../src/frontmatter.ts", "../src/parser.ts", "../src/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { JsonObject, JsonValue, YamlOptions } from './types'\n\n/**\n * Fast, native YAML parser powered by Bun's first-class YAML support\n * Uses Bun.YAML.parse and Bun.YAML.stringify for optimal performance and conformance\n */\n\n/**\n * Convert YAML 1.1 boolean aliases to actual booleans\n * YAML 1.2 doesn't include yes/no/on/off as booleans, but YAML 1.1 does\n */\nfunction convertYaml11Booleans(obj: unknown): unknown {\n if (obj === null || obj === undefined) {\n return obj\n }\n\n if (typeof obj === 'string') {\n const lower = obj.toLowerCase()\n if (lower === 'yes' || lower === 'on') return true\n if (lower === 'no' || lower === 'off') return false\n return obj\n }\n\n if (Array.isArray(obj)) {\n return obj.map(convertYaml11Booleans)\n }\n\n if (typeof obj === 'object') {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(obj)) {\n result[key] = convertYaml11Booleans(value)\n }\n return result\n }\n\n return obj\n}\n\n/**\n * Parse YAML string to JavaScript object\n */\nexport function parse<T = JsonObject>(input: string, options: YamlOptions = {}): T {\n const strict = options.strict ?? false\n\n try {\n // Remove UTF-8 BOM if present\n const content = input.replace(/^\\uFEFF/, '')\n\n // Handle empty input\n if (!content.trim()) {\n return {} as T\n }\n\n // Use Bun's native YAML parser for optimal performance\n let result = Bun.YAML.parse(content)\n\n // Bun.YAML.parse returns an array for multi-document YAML\n // If it's a single document, return the first element\n if (Array.isArray(result) && result.length === 1) {\n result = result[0]\n }\n\n // Convert YAML 1.1 boolean aliases (yes/no/on/off) to actual booleans\n // for compatibility with libraries that expect YAML 1.1 behavior\n return convertYaml11Booleans(result) as T\n }\n catch (error) {\n if (strict) {\n throw new Error(`YAML parsing failed: ${error}`)\n }\n // Return empty object for malformed YAML in non-strict mode\n return {} as T\n }\n}\n\n/**\n * Fallback parser for edge cases (kept for compatibility)\n * @internal\n * Note: Uses permissive internal typing for dynamic object construction\n * The public API (parse function) provides proper typing through generics\n */\nfunction _parseFallback<T = JsonObject>(input: string, _options: YamlOptions = {}): T {\n const strict = _options.strict ?? false\n\n try {\n const content = input.replace(/^\\uFEFF/, '')\n\n if (!content.trim()) {\n return {} as T\n }\n\n // Split into lines for processing\n const lines = content.split('\\n')\n // Internal parser uses permissive types for dynamic object construction\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const result: Record<string, any> = {}\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const stack: Array<{ obj: any, indent: number, key?: string }> = [{ obj: result, indent: -1 }]\n\n const _currentIndent = 0\n let inMultiline = false\n let multilineKey = ''\n let multilineValue: string[] = []\n let multilineIndent = 0\n\n for (let i = 0; i < lines.length; i++) {\n let line = lines[i]\n\n // Skip comments and empty lines (unless in multiline)\n if (!inMultiline && (line.trim().startsWith('#') || !line.trim())) {\n continue\n }\n\n // Calculate indentation\n const match = line.match(/^(\\s*)/)\n const indent = match ? match[1].length : 0\n\n // Handle multiline strings\n if (inMultiline) {\n // Check if we're still in multiline mode\n if (line.trim() && indent > multilineIndent) {\n multilineValue.push(line.substring(multilineIndent))\n continue\n }\n else {\n // End of multiline\n const current = stack[stack.length - 1]\n if (multilineKey) {\n current.obj[multilineKey] = multilineValue.join('\\n')\n }\n inMultiline = false\n multilineKey = ''\n multilineValue = []\n\n // Process the current line if it's not empty\n if (!line.trim())\n continue\n }\n }\n\n // Remove leading whitespace\n line = line.substring(indent)\n\n // Handle list items\n if (line.match(/^-\\s+/)) {\n // Pop stack if we've decreased indentation\n while (stack.length > 1 && indent < stack[stack.length - 1].indent) {\n stack.pop()\n }\n\n const current = stack[stack.length - 1]\n\n // Check if we need to convert the current context to an array\n if (!Array.isArray(current.obj)) {\n // If current.obj has a 'key' marker, we're in the context of a key that should be an array\n if (current.key) {\n // Replace the empty object with an array\n const parent = stack[stack.length - 2]\n if (parent) {\n parent.obj[current.key] = []\n current.obj = parent.obj[current.key]\n }\n else {\n current.obj[current.key] = []\n current.obj = current.obj[current.key]\n }\n }\n }\n\n // Parse the value\n const value = line.substring(2).trim()\n const parsed = parseValue(value)\n\n if (typeof parsed === 'object' && !Array.isArray(parsed) && parsed !== null) {\n current.obj.push(parsed)\n stack.push({ obj: parsed, indent })\n }\n else {\n current.obj.push(parsed)\n }\n continue\n }\n\n // Handle key-value pairs\n const colonIndex = line.indexOf(':')\n if (colonIndex > 0) {\n const key = line.substring(0, colonIndex).trim()\n const value = line.substring(colonIndex + 1).trim()\n\n // Pop stack if we've decreased indentation\n while (stack.length > 1 && indent <= stack[stack.length - 1].indent) {\n stack.pop()\n }\n\n const current = stack[stack.length - 1]\n\n // Handle multiline indicators\n if (value === '|' || value === '>') {\n inMultiline = true\n multilineKey = key\n multilineIndent = indent + 2 // Standard YAML indentation\n multilineValue = []\n continue\n }\n\n // Handle empty value (could be null or nested object/array)\n if (!value) {\n // Create a placeholder object for now\n // It will be replaced with an array if list items follow, or kept as object for nested keys\n current.obj[key] = {}\n stack.push({ obj: current.obj[key], indent, key })\n }\n else {\n // Parse the value\n current.obj[key] = parseValue(value)\n }\n }\n }\n\n // Clean up empty objects that should be null\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function cleanupEmptyObjects(obj: Record<string, any>): void {\n for (const key in obj) {\n const value = obj[key]\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n const keys = Object.keys(value)\n if (keys.length === 0) {\n obj[key] = null\n }\n else {\n cleanupEmptyObjects(value)\n }\n }\n }\n }\n\n cleanupEmptyObjects(result)\n\n return result as T\n }\n catch (error) {\n if (strict) {\n throw new Error(`YAML parsing failed: ${error}`)\n }\n return {} as T\n }\n}\n\n/**\n * Parse a YAML value to its appropriate JavaScript type\n */\nfunction parseValue(value: string): JsonValue {\n // Handle null\n if (value === 'null' || value === '~' || value === '') {\n return null\n }\n\n // Handle booleans\n if (value === 'true' || value === 'yes' || value === 'on') {\n return true\n }\n if (value === 'false' || value === 'no' || value === 'off') {\n return false\n }\n\n // Handle numbers\n if (/^-?\\d+$/.test(value)) {\n return Number.parseInt(value, 10)\n }\n if (/^-?\\d+\\.\\d+$/.test(value)) {\n return Number.parseFloat(value)\n }\n\n // Handle quoted strings\n if ((value.startsWith('\"') && value.endsWith('\"')) || (value.startsWith('\\'') && value.endsWith('\\''))) {\n return value.substring(1, value.length - 1)\n }\n\n // Handle arrays in flow style\n if (value.startsWith('[') && value.endsWith(']')) {\n const items = value.substring(1, value.length - 1).split(',')\n return items.map(item => parseValue(item.trim()))\n }\n\n // Handle objects in flow style\n if (value.startsWith('{') && value.endsWith('}')) {\n const content = value.substring(1, value.length - 1)\n const obj: JsonObject = {}\n const pairs = content.split(',')\n for (const pair of pairs) {\n const colonIndex = pair.indexOf(':')\n if (colonIndex > 0) {\n const key = pair.substring(0, colonIndex).trim()\n const val = pair.substring(colonIndex + 1).trim()\n obj[key] = parseValue(val)\n }\n }\n return obj\n }\n\n // Default to string\n return value\n}\n\n/**\n * Stringify JavaScript object to YAML\n */\nexport function stringify(obj: JsonValue, _options: YamlOptions = {}): string {\n try {\n // Use Bun's native YAML stringify with block-style formatting (2 spaces)\n return Bun.YAML.stringify(obj, null, 2)\n }\n catch {\n // Fallback to custom implementation if needed\n return stringifyFallback(obj, 0)\n }\n}\n\n/**\n * Fallback stringify for edge cases\n * @internal\n */\nfunction stringifyFallback(obj: JsonValue, indent: number): string {\n return stringifyValue(obj, indent)\n}\n\n/**\n * Recursively stringify a value to YAML format\n */\nfunction stringifyValue(value: JsonValue, indent: number): string {\n const spaces = ' '.repeat(indent)\n\n if (value === null || value === undefined) {\n return 'null'\n }\n\n if (typeof value === 'boolean') {\n return value.toString()\n }\n\n if (typeof value === 'number') {\n return value.toString()\n }\n\n if (typeof value === 'string') {\n // Quote strings with special characters\n if (value.includes(':') || value.includes('#') || value.includes('\\n')) {\n return `\"${value.replace(/\"/g, '\\\\\"')}\"`\n }\n return value\n }\n\n if (Array.isArray(value)) {\n if (value.length === 0)\n return '[]'\n\n return value.map((item) => {\n if (typeof item === 'object' && item !== null && !Array.isArray(item)) {\n const itemStr = stringifyValue(item, indent + 2)\n return `\\n${spaces}- ${itemStr.trim()}`\n }\n return `\\n${spaces}- ${stringifyValue(item, indent + 2)}`\n }).join('')\n }\n\n if (typeof value === 'object') {\n const keys = Object.keys(value)\n if (keys.length === 0)\n return '{}'\n\n return keys.map((key) => {\n const val = value[key]\n if (typeof val === 'object' && val !== null) {\n return `\\n${spaces}${key}:${stringifyValue(val, indent + 2)}`\n }\n return `\\n${spaces}${key}: ${stringifyValue(val, indent + 2)}`\n }).join('')\n }\n\n return String(value)\n}\n",
|
|
6
|
+
"import type { JsonObject, JsonValue, ParsedMarkdown } from './types'\nimport * as yaml from './yaml'\n\n/**\n * Fast frontmatter parser optimized for Bun\n * Replaces gray-matter with a performance-focused implementation\n */\n\nconst FRONTMATTER_REGEX = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n/\nconst FRONTMATTER_REGEX_ALT = /^\\+\\+\\+\\r?\\n([\\s\\S]*?)\\r?\\n\\+\\+\\+\\r?\\n/\n\n/**\n * Parse markdown with frontmatter\n */\nexport function parse<T = JsonObject>(content: string): ParsedMarkdown<T> {\n const original = content\n\n // Try YAML frontmatter (---)\n let match = content.match(FRONTMATTER_REGEX)\n let data: T = {} as T\n let matter: string | undefined\n let markdown = content\n\n if (match) {\n matter = match[1]\n markdown = content.substring(match[0].length)\n data = yaml.parse<T>(matter)\n }\n else {\n // Try TOML frontmatter (+++)\n match = content.match(FRONTMATTER_REGEX_ALT)\n if (match) {\n matter = match[1]\n markdown = content.substring(match[0].length)\n // For TOML, we'll use a simple parser\n data = parseToml(matter) as T\n }\n }\n\n return {\n data: data as T,\n content: markdown,\n original,\n matter,\n }\n}\n\n/**\n * Simple TOML parser for frontmatter\n */\nfunction parseToml(content: string): JsonObject {\n const result: JsonObject = {}\n const lines = content.split('\\n')\n\n for (const line of lines) {\n const trimmed = line.trim()\n\n // Skip comments and empty lines\n if (!trimmed || trimmed.startsWith('#')) {\n continue\n }\n\n // Parse key-value pairs\n const equalIndex = trimmed.indexOf('=')\n if (equalIndex > 0) {\n const key = trimmed.substring(0, equalIndex).trim()\n const value = trimmed.substring(equalIndex + 1).trim()\n\n // Parse value\n result[key] = parseTomlValue(value)\n }\n }\n\n return result\n}\n\n/**\n * Parse TOML value\n */\nfunction parseTomlValue(value: string): JsonValue {\n // Remove quotes\n if ((value.startsWith('\"') && value.endsWith('\"')) || (value.startsWith('\\'') && value.endsWith('\\''))) {\n return value.substring(1, value.length - 1)\n }\n\n // Boolean\n if (value === 'true')\n return true\n if (value === 'false')\n return false\n\n // Number\n if (/^-?\\d+$/.test(value)) {\n return Number.parseInt(value, 10)\n }\n if (/^-?\\d+\\.\\d+$/.test(value)) {\n return Number.parseFloat(value)\n }\n\n // Array\n if (value.startsWith('[') && value.endsWith(']')) {\n const items = value.substring(1, value.length - 1).split(',')\n return items.map(item => parseTomlValue(item.trim()))\n }\n\n return value\n}\n\n/**\n * Stringify data to frontmatter markdown\n */\nexport function stringify<T extends JsonObject = JsonObject>(\n data: T,\n content: string,\n format: 'yaml' | 'toml' = 'yaml',\n): string {\n if (!data || Object.keys(data).length === 0) {\n return content\n }\n\n const delimiter = format === 'yaml' ? '---' : '+++'\n const matter = format === 'yaml' ? yaml.stringify(data).trim() : stringifyToml(data).trim()\n\n return `${delimiter}\\n${matter}\\n${delimiter}\\n${content}`\n}\n\n/**\n * Stringify object to TOML format\n */\nfunction stringifyToml(obj: JsonObject): string {\n const lines: string[] = []\n\n for (const [key, value] of Object.entries(obj)) {\n if (typeof value === 'string') {\n lines.push(`${key} = \"${value}\"`)\n }\n else if (typeof value === 'boolean' || typeof value === 'number') {\n lines.push(`${key} = ${value}`)\n }\n else if (Array.isArray(value)) {\n const items = value.map((item) => {\n if (typeof item === 'string')\n return `\"${item}\"`\n return String(item)\n })\n lines.push(`${key} = [${items.join(', ')}]`)\n }\n }\n\n return lines.join('\\n')\n}\n\n/**\n * Check if content has frontmatter\n */\nexport function hasFrontmatter(content: string): boolean {\n return FRONTMATTER_REGEX.test(content) || FRONTMATTER_REGEX_ALT.test(content)\n}\n\n/**\n * Extract only the frontmatter (without parsing)\n */\nexport function extractFrontmatter(content: string): string | null {\n let match = content.match(FRONTMATTER_REGEX)\n if (match)\n return match[1]\n\n match = content.match(FRONTMATTER_REGEX_ALT)\n if (match)\n return match[1]\n\n return null\n}\n",
|
|
7
|
+
"import type { MarkdownOptions } from './types'\n\n/**\n * markdown-it inspired flat token stream architecture\n * Key optimizations:\n * - Flat token array (no nesting)\n * - Position-based parsing (no substring allocations)\n * - Pending text buffer (batch consecutive text)\n * - Two-pass emphasis matching\n */\n\ninterface FlatToken {\n type: string\n tag?: string\n nesting?: number // 1 = open, 0 = self-closing, -1 = close\n content?: string\n markup?: string\n level?: number\n children?: FlatToken[]\n}\n\ninterface ParserState {\n src: string\n pos: number\n posMax: number\n tokens: FlatToken[]\n pending: string\n level: number\n options: MarkdownOptions\n // Cache for emphasis delimiter matching\n cache: Record<number, number>\n delimiters: Array<{\n marker: number\n length: number\n token: number\n end: number\n can_open: boolean\n can_close: boolean\n }>\n}\n\nconst defaultOptions: MarkdownOptions = {\n gfm: true,\n breaks: false,\n headerIds: true,\n headerPrefix: '',\n pedantic: false,\n smartLists: true,\n smartypants: false,\n sanitize: false,\n}\n\n// Character codes for fast comparison\nconst CODE_NEWLINE = 10 // \\n\nconst CODE_HASH = 35 // #\nconst CODE_STAR = 42 // *\nconst CODE_UNDERSCORE = 95 // _\nconst CODE_BACKTICK = 96 // `\nconst CODE_LBRACKET = 91 // [\nconst CODE_BANG = 33 // !\nconst CODE_TILDE = 126 // ~\nconst CODE_PIPE = 124 // |\nconst CODE_GT = 62 // >\nconst CODE_MINUS = 45 // -\nconst CODE_PLUS = 43 // +\nconst CODE_SPACE = 32 // space\n\n// Helper to check if a character code is alphanumeric\nfunction isAlphanumeric(code: number): boolean {\n return (code >= 48 && code <= 57) // 0-9\n || (code >= 65 && code <= 90) // A-Z\n || (code >= 97 && code <= 122) // a-z\n}\n\nexport function parse(markdown: string, options: MarkdownOptions = {}): string {\n const opts = { ...defaultOptions, ...options }\n const state: ParserState = {\n src: markdown.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n'),\n pos: 0,\n posMax: markdown.length,\n tokens: [],\n pending: '',\n level: 0,\n options: opts,\n cache: {},\n delimiters: [],\n }\n\n // Block parsing\n parseBlocks(state)\n\n // Render tokens to HTML\n return renderTokens(state.tokens, opts)\n}\n\nexport function parseSync(markdown: string, options: MarkdownOptions = {}): string {\n return parse(markdown, options)\n}\n\nfunction parseBlocks(state: ParserState): void {\n while (state.pos < state.posMax) {\n const char = state.src.charCodeAt(state.pos)\n\n // Skip empty lines\n if (char === CODE_NEWLINE) {\n state.pos++\n continue\n }\n\n // Headings\n if (char === CODE_HASH && isStartOfLine(state)) {\n if (parseHeading(state))\n continue\n }\n\n // Code blocks\n if (char === CODE_BACKTICK && lookAhead(state, '```')) {\n if (parseCodeBlock(state))\n continue\n }\n\n // Horizontal rule\n if ((char === CODE_STAR || char === CODE_MINUS || char === CODE_UNDERSCORE) && isStartOfLine(state)) {\n if (parseHR(state))\n continue\n }\n\n // Blockquote\n if (char === CODE_GT && isStartOfLine(state)) {\n if (parseBlockquote(state))\n continue\n }\n\n // Lists\n if (isListMarker(char) && isStartOfLine(state)) {\n if (parseList(state))\n continue\n }\n\n // Tables\n if (state.options.gfm && char === CODE_PIPE && isStartOfLine(state)) {\n if (parseTable(state))\n continue\n }\n\n // Paragraph\n if (parseParagraph(state))\n continue\n\n // Fallback: skip character\n state.pos++\n }\n\n // Flush any pending text\n if (state.pending) {\n pushPending(state)\n }\n}\n\nfunction isStartOfLine(state: ParserState): boolean {\n return state.pos === 0 || state.src.charCodeAt(state.pos - 1) === CODE_NEWLINE\n}\n\nfunction lookAhead(state: ParserState, str: string): boolean {\n return state.src.slice(state.pos, state.pos + str.length) === str\n}\n\nfunction isListMarker(char: number): boolean {\n return char === CODE_STAR || char === CODE_MINUS || char === CODE_PLUS || (char >= 48 && char <= 57)\n}\n\nfunction pushPending(state: ParserState): void {\n if (!state.pending)\n return\n\n state.tokens.push({\n type: 'text',\n content: state.pending,\n level: state.level,\n })\n state.pending = ''\n}\n\nfunction pushToken(state: ParserState, type: string, tag: string, nesting: number): FlatToken {\n pushPending(state)\n\n if (nesting < 0)\n state.level--\n\n const token: FlatToken = {\n type,\n tag,\n nesting,\n level: state.level,\n }\n\n if (nesting > 0)\n state.level++\n\n state.tokens.push(token)\n return token\n}\n\nfunction parseHeading(state: ParserState): boolean {\n const start = state.pos\n let level = 0\n\n while (state.pos < state.posMax && state.src.charCodeAt(state.pos) === CODE_HASH && level < 6) {\n level++\n state.pos++\n }\n\n if (level === 0 || state.pos >= state.posMax || state.src.charCodeAt(state.pos) !== CODE_SPACE) {\n state.pos = start\n return false\n }\n\n state.pos++ // skip space\n\n // Find end of line\n const textStart = state.pos\n let textEnd = state.pos\n while (textEnd < state.posMax && state.src.charCodeAt(textEnd) !== CODE_NEWLINE) {\n textEnd++\n }\n\n const content = state.src.slice(textStart, textEnd).trim()\n\n const token = pushToken(state, 'heading_open', `h${level}`, 1)\n\n // Add header ID if enabled\n if (state.options.headerIds) {\n token.markup = `${state.options.headerPrefix}${slugify(content)}`\n }\n\n // Parse inline content\n parseInline(state, content)\n\n pushToken(state, 'heading_close', `h${level}`, -1)\n\n state.pos = textEnd + 1\n return true\n}\n\nfunction slugify(text: string): string {\n return text\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-')\n .trim()\n}\n\nfunction parseCodeBlock(state: ParserState): boolean {\n const start = state.pos\n state.pos += 3 // skip ```\n\n // Get language\n const langStart = state.pos\n while (state.pos < state.posMax && state.src.charCodeAt(state.pos) !== CODE_NEWLINE) {\n state.pos++\n }\n const lang = state.src.slice(langStart, state.pos).trim()\n state.pos++ // skip newline\n\n // Find closing ```\n const codeStart = state.pos\n\n // Check if closing ``` is immediately at current position (empty code block)\n if (state.src.slice(state.pos, state.pos + 3) === '```') {\n const token = pushToken(state, 'fence', 'code', 0)\n token.content = ''\n token.markup = lang\n state.pos += 3\n return true\n }\n\n const closing = state.src.indexOf('\\n```', state.pos)\n if (closing === -1) {\n state.pos = start\n return false\n }\n\n const code = state.src.slice(codeStart, closing)\n\n const token = pushToken(state, 'fence', 'code', 0)\n token.content = code\n token.markup = lang\n\n state.pos = closing + 4\n return true\n}\n\nfunction parseHR(state: ParserState): boolean {\n const start = state.pos\n const marker = state.src.charCodeAt(state.pos)\n let count = 0\n\n while (state.pos < state.posMax) {\n const char = state.src.charCodeAt(state.pos)\n if (char === marker)\n count++\n else if (char !== CODE_SPACE && char !== CODE_NEWLINE)\n break\n state.pos++\n if (char === CODE_NEWLINE)\n break\n }\n\n if (count >= 3) {\n pushToken(state, 'hr', 'hr', 0)\n return true\n }\n\n state.pos = start\n return false\n}\n\nfunction parseBlockquote(state: ParserState): boolean {\n // Simple blockquote implementation\n pushToken(state, 'blockquote_open', 'blockquote', 1)\n\n while (state.pos < state.posMax && state.src.charCodeAt(state.pos) === CODE_GT) {\n state.pos++ // skip >\n if (state.src.charCodeAt(state.pos) === CODE_SPACE)\n state.pos++\n\n const lineStart = state.pos\n let lineEnd = state.pos\n while (lineEnd < state.posMax && state.src.charCodeAt(lineEnd) !== CODE_NEWLINE) {\n lineEnd++\n }\n\n const content = state.src.slice(lineStart, lineEnd).trim()\n if (content) {\n pushToken(state, 'paragraph_open', 'p', 1)\n parseInline(state, content)\n pushToken(state, 'paragraph_close', 'p', -1)\n }\n\n state.pos = lineEnd + 1\n }\n\n pushToken(state, 'blockquote_close', 'blockquote', -1)\n return true\n}\n\nfunction parseList(state: ParserState): boolean {\n const firstChar = state.src.charCodeAt(state.pos)\n const isOrdered = firstChar >= 48 && firstChar <= 57\n\n // For bullet lists, make sure there's only one marker character\n if (!isOrdered) {\n const nextChar = state.src.charCodeAt(state.pos + 1)\n // If followed by same character or not followed by space, it's not a list\n if (nextChar === firstChar || nextChar !== CODE_SPACE) {\n return false\n }\n }\n\n pushToken(state, isOrdered ? 'ordered_list_open' : 'bullet_list_open', isOrdered ? 'ol' : 'ul', 1)\n\n while (state.pos < state.posMax) {\n const char = state.src.charCodeAt(state.pos)\n\n // Check for list marker\n if (isOrdered) {\n let num = 0\n while (state.src.charCodeAt(state.pos) >= 48 && state.src.charCodeAt(state.pos) <= 57) {\n state.pos++\n num++\n }\n if (num === 0 || state.src.charCodeAt(state.pos) !== 46)\n break // not a number or missing dot\n state.pos++ // skip dot\n }\n else {\n if (char !== CODE_STAR && char !== CODE_MINUS && char !== CODE_PLUS)\n break\n // Make sure next char isn't the same (would be **, --, etc)\n if (state.src.charCodeAt(state.pos + 1) === char)\n break\n state.pos++\n }\n\n if (state.src.charCodeAt(state.pos) !== CODE_SPACE)\n break\n state.pos++ // skip space\n\n // Get item content\n const itemStart = state.pos\n let itemEnd = state.pos\n while (itemEnd < state.posMax && state.src.charCodeAt(itemEnd) !== CODE_NEWLINE) {\n itemEnd++\n }\n\n let content = state.src.slice(itemStart, itemEnd).trim()\n\n // Check for task list item\n const taskMatch = content.match(/^\\[([ x])\\]\\s+(.+)/i)\n if (taskMatch) {\n const checked = taskMatch[1].toLowerCase() === 'x'\n content = taskMatch[2]\n\n const token = pushToken(state, 'list_item_open', 'li', 1)\n token.markup = checked ? 'checked' : 'unchecked'\n\n parseInline(state, content)\n pushToken(state, 'list_item_close', 'li', -1)\n }\n else {\n pushToken(state, 'list_item_open', 'li', 1)\n parseInline(state, content)\n pushToken(state, 'list_item_close', 'li', -1)\n }\n\n state.pos = itemEnd + 1\n\n // Check if next line is also a list item\n const nextChar = state.src.charCodeAt(state.pos)\n if (!isListMarker(nextChar))\n break\n }\n\n pushToken(state, isOrdered ? 'ordered_list_close' : 'bullet_list_close', isOrdered ? 'ol' : 'ul', -1)\n return true\n}\n\n// Helper to split table row by pipes while respecting inline code\nfunction splitTableCells(line: string): string[] {\n const cells: string[] = []\n let current = ''\n let inCode = false\n let escaped = false\n\n for (let i = 0; i < line.length; i++) {\n const char = line[i]\n\n // Handle escape sequences\n if (escaped) {\n current += char\n escaped = false\n continue\n }\n\n if (char === '\\\\') {\n current += char\n escaped = true\n continue\n }\n\n // Toggle code mode on backtick\n if (char === '`') {\n inCode = !inCode\n current += char\n continue\n }\n\n // Split on pipe only if not in code\n if (char === '|' && !inCode) {\n cells.push(current.trim())\n current = ''\n continue\n }\n\n current += char\n }\n\n // Add final cell\n if (current || cells.length > 0) {\n cells.push(current.trim())\n }\n\n // Remove first and last empty cells (from leading/trailing pipes)\n return cells.slice(1, -1)\n}\n\nfunction parseTable(state: ParserState): boolean {\n const start = state.pos\n\n // Find first line (header)\n let lineEnd = state.pos\n while (lineEnd < state.posMax && state.src.charCodeAt(lineEnd) !== CODE_NEWLINE) {\n lineEnd++\n }\n const headerLine = state.src.slice(state.pos, lineEnd)\n\n // Check if it's a valid table (starts and ends with |)\n if (!headerLine.startsWith('|') || !headerLine.trim().endsWith('|')) {\n return false\n }\n\n // Move past header line\n state.pos = lineEnd + 1\n\n // Parse alignment line\n lineEnd = state.pos\n while (lineEnd < state.posMax && state.src.charCodeAt(lineEnd) !== CODE_NEWLINE) {\n lineEnd++\n }\n const alignLine = state.src.slice(state.pos, lineEnd)\n\n // Validate alignment line\n if (!/^\\|(?:\\s*:?-+:?\\s*\\|)+$/.test(alignLine.trim())) {\n state.pos = start\n return false\n }\n\n // Parse alignment\n const alignCells = alignLine.split('|').slice(1, -1)\n const align: Array<string | null> = alignCells.map((cell) => {\n const trimmed = cell.trim()\n if (trimmed.startsWith(':') && trimmed.endsWith(':'))\n return 'center'\n if (trimmed.endsWith(':'))\n return 'right'\n if (trimmed.startsWith(':'))\n return 'left'\n return null\n })\n\n // Move past alignment line\n state.pos = lineEnd + 1\n\n // Parse header cells\n const headerCells = splitTableCells(headerLine)\n\n // Start table\n pushToken(state, 'table_open', 'table', 1)\n pushToken(state, 'thead_open', 'thead', 1)\n pushToken(state, 'tr_open', 'tr', 1)\n\n // Render header cells\n for (let i = 0; i < headerCells.length; i++) {\n const token = pushToken(state, 'th_open', 'th', 1)\n if (align[i]) {\n token.markup = align[i] ?? undefined\n }\n parseInline(state, headerCells[i])\n pushToken(state, 'th_close', 'th', -1)\n }\n\n pushToken(state, 'tr_close', 'tr', -1)\n pushToken(state, 'thead_close', 'thead', -1)\n\n // Parse body rows\n pushToken(state, 'tbody_open', 'tbody', 1)\n\n while (state.pos < state.posMax) {\n lineEnd = state.pos\n while (lineEnd < state.posMax && state.src.charCodeAt(lineEnd) !== CODE_NEWLINE) {\n lineEnd++\n }\n\n const rowLine = state.src.slice(state.pos, lineEnd).trim()\n\n // Check if still a table row\n if (!rowLine.startsWith('|') || !rowLine.endsWith('|')) {\n break\n }\n\n const cells = splitTableCells(rowLine)\n\n pushToken(state, 'tr_open', 'tr', 1)\n\n for (let i = 0; i < cells.length; i++) {\n const token = pushToken(state, 'td_open', 'td', 1)\n if (align[i]) {\n token.markup = align[i] ?? undefined\n }\n parseInline(state, cells[i])\n pushToken(state, 'td_close', 'td', -1)\n }\n\n pushToken(state, 'tr_close', 'tr', -1)\n\n state.pos = lineEnd + 1\n }\n\n pushToken(state, 'tbody_close', 'tbody', -1)\n pushToken(state, 'table_close', 'table', -1)\n\n return true\n}\n\nfunction parseParagraph(state: ParserState): boolean {\n const start = state.pos\n let end = state.pos\n\n // Find end of paragraph (double newline or EOF)\n while (end < state.posMax) {\n if (state.src.charCodeAt(end) === CODE_NEWLINE) {\n if (end + 1 < state.posMax && state.src.charCodeAt(end + 1) === CODE_NEWLINE) {\n break\n }\n }\n end++\n }\n\n const content = state.src.slice(start, end).trim()\n if (!content) {\n state.pos = end + 1\n return false\n }\n\n pushToken(state, 'paragraph_open', 'p', 1)\n parseInline(state, content)\n pushToken(state, 'paragraph_close', 'p', -1)\n\n state.pos = end + 1\n return true\n}\n\n// Inline parsing with direct matching (simpler and more reliable)\nfunction parseInline(state: ParserState, content: string): void {\n const savedSrc = state.src\n const savedPos = state.pos\n const savedPosMax = state.posMax\n\n state.src = content\n state.pos = 0\n state.posMax = content.length\n\n while (state.pos < state.posMax) {\n const char = state.src.charCodeAt(state.pos)\n\n // Strong (bold) - check for ** or __\n if ((char === CODE_STAR || char === CODE_UNDERSCORE) && state.src.charCodeAt(state.pos + 1) === char) {\n if (scanStrong(state, char))\n continue\n }\n\n // Emphasis (italic) - check for * or _\n if (char === CODE_STAR || char === CODE_UNDERSCORE) {\n if (scanEmphasisDirect(state, char))\n continue\n }\n\n // Inline code\n if (char === CODE_BACKTICK) {\n if (scanCode(state))\n continue\n }\n\n // Links\n if (char === CODE_LBRACKET) {\n if (scanLink(state))\n continue\n }\n\n // Images\n if (char === CODE_BANG && state.src.charCodeAt(state.pos + 1) === CODE_LBRACKET) {\n if (scanImage(state))\n continue\n }\n\n // Strikethrough (GFM)\n if (state.options.gfm && char === CODE_TILDE && state.src.charCodeAt(state.pos + 1) === CODE_TILDE) {\n if (scanStrikethrough(state))\n continue\n }\n\n // Line breaks\n if (state.options.breaks && char === CODE_NEWLINE) {\n pushPending(state)\n pushToken(state, 'br', 'br', 0)\n state.pos++\n continue\n }\n\n // Regular text\n state.pending += state.src[state.pos]\n state.pos++\n }\n\n // Flush pending\n if (state.pending)\n pushPending(state)\n\n // Restore state\n state.src = savedSrc\n state.pos = savedPos\n state.posMax = savedPosMax\n}\n\nfunction scanStrong(state: ParserState, marker: number): boolean {\n const start = state.pos\n const markerStr = String.fromCharCode(marker)\n const searchStart = start + 2\n\n // For underscores, check word boundaries (GFM rule)\n if (marker === 95) { // underscore\n const prevChar = start > 0 ? state.src.charCodeAt(start - 1) : 0\n // If preceded by alphanumeric or underscore, not emphasis\n if (isAlphanumeric(prevChar) || prevChar === 95) {\n return false\n }\n }\n\n // Find closing marker\n const closePos = state.src.indexOf(markerStr + markerStr, searchStart)\n if (closePos === -1) {\n return false\n }\n\n // For underscores, check word boundaries after closing marker\n if (marker === 95) { // underscore\n const nextChar = closePos + 2 < state.posMax ? state.src.charCodeAt(closePos + 2) : 0\n // If followed by alphanumeric or underscore, not emphasis\n if (isAlphanumeric(nextChar) || nextChar === 95) {\n return false\n }\n }\n\n pushPending(state)\n\n // Get text between markers\n const text = state.src.substring(searchStart, closePos)\n\n pushToken(state, 'strong_open', 'strong', 1)\n // Recursively parse nested inline elements\n parseInline(state, text)\n pushToken(state, 'strong_close', 'strong', -1)\n\n state.pos = closePos + 2\n return true\n}\n\nfunction scanEmphasisDirect(state: ParserState, marker: number): boolean {\n const start = state.pos\n const markerStr = String.fromCharCode(marker)\n const searchStart = start + 1\n\n // For underscores, check word boundaries (GFM rule)\n if (marker === 95) { // underscore\n const prevChar = start > 0 ? state.src.charCodeAt(start - 1) : 0\n // If preceded by alphanumeric or underscore, not emphasis\n if (isAlphanumeric(prevChar) || prevChar === 95) {\n return false\n }\n }\n\n // Find closing marker (make sure it's not a double marker)\n let closePos = state.src.indexOf(markerStr, searchStart)\n while (closePos !== -1) {\n // Make sure it's not a double marker\n if (state.src.charCodeAt(closePos + 1) === marker) {\n closePos = state.src.indexOf(markerStr, closePos + 2)\n continue\n }\n\n // For underscores, check word boundaries after closing marker\n if (marker === 95) { // underscore\n const nextChar = closePos + 1 < state.posMax ? state.src.charCodeAt(closePos + 1) : 0\n // If followed by alphanumeric or underscore, keep searching\n if (isAlphanumeric(nextChar) || nextChar === 95) {\n closePos = state.src.indexOf(markerStr, closePos + 1)\n continue\n }\n }\n\n break\n }\n\n if (closePos === -1 || closePos === searchStart) {\n return false\n }\n\n pushPending(state)\n\n // Get text between markers\n const text = state.src.substring(searchStart, closePos)\n\n pushToken(state, 'em_open', 'em', 1)\n // Recursively parse nested inline elements\n parseInline(state, text)\n pushToken(state, 'em_close', 'em', -1)\n\n state.pos = closePos + 1\n return true\n}\n\nfunction scanCode(state: ParserState): boolean {\n const start = state.pos\n state.pos++ // skip opening `\n\n const codeStart = state.pos\n const closeIdx = state.src.indexOf('`', state.pos)\n if (closeIdx === -1) {\n state.pos = start\n return false\n }\n\n const code = state.src.slice(codeStart, closeIdx)\n pushToken(state, 'code_inline', 'code', 0).content = code\n\n state.pos = closeIdx + 1\n return true\n}\n\nfunction scanLink(state: ParserState): boolean {\n const start = state.pos\n state.pos++ // skip [\n\n const textStart = state.pos\n const textEnd = state.src.indexOf(']', state.pos)\n if (textEnd === -1) {\n state.pos = start\n return false\n }\n\n if (state.src.charCodeAt(textEnd + 1) !== 40) { // not followed by (\n state.pos = start\n return false\n }\n\n const urlStart = textEnd + 2\n const urlEnd = state.src.indexOf(')', urlStart)\n if (urlEnd === -1) {\n state.pos = start\n return false\n }\n\n pushPending(state)\n\n const text = state.src.slice(textStart, textEnd)\n const urlPart = state.src.slice(urlStart, urlEnd)\n\n // Parse out title if present: url \"title\" or url 'title'\n let url = urlPart\n let title = ''\n const titleMatch = urlPart.match(/^(.*?)\\s+[\"'](.*)[\"']$/)\n if (titleMatch) {\n url = titleMatch[1]\n title = titleMatch[2]\n }\n\n const token = pushToken(state, 'link_open', 'a', 1)\n token.markup = url\n if (title) {\n token.content = title\n }\n\n // Recursively parse link text\n parseInline(state, text)\n pushToken(state, 'link_close', 'a', -1)\n\n state.pos = urlEnd + 1\n return true\n}\n\nfunction scanImage(state: ParserState): boolean {\n const start = state.pos\n state.pos += 2 // skip ![\n\n const altStart = state.pos\n const altEnd = state.src.indexOf(']', state.pos)\n if (altEnd === -1) {\n state.pos = start\n return false\n }\n\n if (state.src.charCodeAt(altEnd + 1) !== 40) {\n state.pos = start\n return false\n }\n\n const urlStart = altEnd + 2\n const urlEnd = state.src.indexOf(')', urlStart)\n if (urlEnd === -1) {\n state.pos = start\n return false\n }\n\n const alt = state.src.slice(altStart, altEnd)\n const urlPart = state.src.slice(urlStart, urlEnd)\n\n // Parse out title if present: url \"title\" or url 'title'\n let url = urlPart\n let title = ''\n const titleMatch = urlPart.match(/^(.*?)\\s+[\"'](.*)[\"']$/)\n if (titleMatch) {\n url = titleMatch[1]\n title = titleMatch[2]\n }\n\n pushToken(state, 'image', 'img', 0).markup = `${alt}|${url}|${title}`\n\n state.pos = urlEnd + 1\n return true\n}\n\nfunction scanStrikethrough(state: ParserState): boolean {\n const start = state.pos\n state.pos += 2 // skip ~~\n\n const textStart = state.pos\n const closeIdx = state.src.indexOf('~~', state.pos)\n if (closeIdx === -1) {\n state.pos = start\n return false\n }\n\n pushPending(state)\n\n const text = state.src.slice(textStart, closeIdx)\n\n pushToken(state, 'del_open', 'del', 1)\n // Recursively parse nested inline elements\n parseInline(state, text)\n pushToken(state, 'del_close', 'del', -1)\n\n state.pos = closeIdx + 2\n return true\n}\n\nfunction renderTokens(tokens: FlatToken[], options: MarkdownOptions): string {\n let html = ''\n\n for (const token of tokens) {\n switch (token.type) {\n case 'heading_open':\n if (token.markup) {\n html += `<${token.tag} id=\"${token.markup}\">`\n }\n else {\n html += `<${token.tag}>`\n }\n break\n case 'heading_close':\n html += `</${token.tag}>\\n`\n break\n case 'paragraph_open':\n html += '<p>'\n break\n case 'paragraph_close':\n html += '</p>\\n'\n break\n case 'fence':\n case 'code_block': {\n let code = token.content || ''\n const lang = token.markup || ''\n\n // Apply syntax highlighting if provided\n if (options.highlight && lang) {\n code = options.highlight(code, lang)\n }\n else {\n code = escapeHtml(code)\n }\n\n if (lang) {\n html += `<pre><code class=\"language-${lang}\">${code}</code></pre>\\n`\n }\n else {\n html += `<pre><code>${code}</code></pre>\\n`\n }\n break\n }\n case 'code_inline':\n html += `<code>${escapeHtml(token.content || '')}</code>`\n break\n case 'hr':\n html += '<hr>\\n'\n break\n case 'blockquote_open':\n html += '<blockquote>\\n'\n break\n case 'blockquote_close':\n html += '</blockquote>\\n'\n break\n case 'bullet_list_open':\n html += '<ul>\\n'\n break\n case 'bullet_list_close':\n html += '</ul>\\n'\n break\n case 'ordered_list_open':\n html += '<ol>\\n'\n break\n case 'ordered_list_close':\n html += '</ol>\\n'\n break\n case 'list_item_open':\n html += '<li>'\n if (token.markup === 'checked') {\n html += '<input type=\"checkbox\" checked disabled> '\n }\n else if (token.markup === 'unchecked') {\n html += '<input type=\"checkbox\" disabled> '\n }\n break\n case 'list_item_close':\n html += '</li>\\n'\n break\n case 'table_open':\n html += '<table>\\n'\n break\n case 'table_close':\n html += '</table>\\n'\n break\n case 'thead_open':\n html += '<thead>\\n'\n break\n case 'thead_close':\n html += '</thead>\\n'\n break\n case 'tbody_open':\n html += '<tbody>\\n'\n break\n case 'tbody_close':\n html += '</tbody>\\n'\n break\n case 'tr_open':\n html += '<tr>\\n'\n break\n case 'tr_close':\n html += '</tr>\\n'\n break\n case 'th_open':\n if (token.markup) {\n html += `<th align=\"${token.markup}\">`\n }\n else {\n html += '<th>'\n }\n break\n case 'th_close':\n html += '</th>\\n'\n break\n case 'td_open':\n if (token.markup) {\n html += `<td align=\"${token.markup}\">`\n }\n else {\n html += '<td>'\n }\n break\n case 'td_close':\n html += '</td>\\n'\n break\n case 'strong_open':\n html += '<strong>'\n break\n case 'strong_close':\n html += '</strong>'\n break\n case 'em_open':\n html += '<em>'\n break\n case 'em_close':\n html += '</em>'\n break\n case 'del_open':\n html += '<del>'\n break\n case 'del_close':\n html += '</del>'\n break\n case 'br':\n html += '<br>'\n break\n case 'link_open':\n if (token.content) {\n html += `<a href=\"${escapeHtml(token.markup || '')}\" title=\"${escapeHtml(token.content)}\">`\n }\n else {\n html += `<a href=\"${escapeHtml(token.markup || '')}\">`\n }\n break\n case 'link_close':\n html += '</a>'\n break\n case 'image': {\n const [alt, url, imageTitle] = (token.markup || '||').split('|')\n if (imageTitle) {\n html += `<img src=\"${escapeHtml(url)}\" alt=\"${escapeHtml(alt)}\" title=\"${escapeHtml(imageTitle)}\">`\n }\n else {\n html += `<img src=\"${escapeHtml(url)}\" alt=\"${escapeHtml(alt)}\">`\n }\n break\n }\n case 'text':\n html += escapeHtml(token.content || '')\n break\n }\n }\n\n return html\n}\n\n// Character codes for HTML escaping\nconst CHAR_AMP = 38 // &\nconst CHAR_LT = 60 // <\nconst CHAR_GT = 62 // >\nconst CHAR_QUOT = 34 // \"\nconst CHAR_APOS = 39 // '\n\nfunction escapeHtml(text: string): string {\n const len = text.length\n let lastPos = 0\n let needsEscape = false\n\n // Quick scan to see if escaping is needed\n for (let i = 0; i < len; i++) {\n const code = text.charCodeAt(i)\n if (code === CHAR_AMP || code === CHAR_LT || code === CHAR_GT || code === CHAR_QUOT || code === CHAR_APOS) {\n needsEscape = true\n break\n }\n }\n\n if (!needsEscape)\n return text\n\n const parts: string[] = []\n for (let i = 0; i < len; i++) {\n const code = text.charCodeAt(i)\n let replacement: string | null = null\n\n switch (code) {\n case CHAR_AMP:\n replacement = '&'\n break\n case CHAR_LT:\n replacement = '<'\n break\n case CHAR_GT:\n replacement = '>'\n break\n case CHAR_QUOT:\n replacement = '"'\n break\n case CHAR_APOS:\n replacement = '''\n break\n }\n\n if (replacement) {\n if (i > lastPos) {\n parts.push(text.substring(lastPos, i))\n }\n parts.push(replacement)\n lastPos = i + 1\n }\n }\n\n if (lastPos < len) {\n parts.push(text.substring(lastPos))\n }\n\n return parts.join('')\n}\n",
|
|
8
|
+
"/**\n * ts-md\n *\n * A fast, native Bun-powered markdown parser with frontmatter support.\n * Replaces gray-matter, marked, and yaml with performance-optimized implementations.\n */\n\n// Default export for common use case\nimport { parse as parseFrontmatter } from './frontmatter'\nimport { parse as parseMarkdown } from './parser'\n\nexport * as frontmatter from './frontmatter'\n// Re-export for convenience\nexport { parse as parseFrontmatter, stringify as stringifyFrontmatter } from './frontmatter'\nexport * from './parser'\nexport { parse as parseMarkdown, parseSync as parseMarkdownSync } from './parser'\n\nexport * from './types'\nexport * as yaml from './yaml'\nexport { parse as parseYaml, stringify as stringifyYaml } from './yaml'\n\n/**\n * Parse markdown file with frontmatter in one go\n */\nexport function parseMarkdownWithFrontmatter<T = Record<string, any>>(\n content: string,\n options?: { gfm?: boolean, breaks?: boolean },\n): { data: T, content: string, html: string } {\n const { data, content: markdown } = parseFrontmatter<T>(content)\n const html = parseMarkdown(markdown, options)\n\n return {\n data,\n content: markdown,\n html,\n }\n}\n\n/**\n * Default export\n */\nconst markdownParser: {\n parseFrontmatter: typeof parseFrontmatter\n parseMarkdown: typeof parseMarkdown\n parseMarkdownWithFrontmatter: typeof parseMarkdownWithFrontmatter\n} = {\n parseFrontmatter,\n parseMarkdown,\n parseMarkdownWithFrontmatter,\n}\n\nexport default markdownParser\n"
|
|
9
|
+
],
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "4EC4EE35429AE4D764756E2164756E21",
|
|
12
|
+
"names": []
|
|
13
|
+
}
|
package/dist/parser.d.ts
ADDED
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown parsing options
|
|
3
|
+
*/
|
|
4
|
+
export declare interface MarkdownOptions {
|
|
5
|
+
gfm?: boolean
|
|
6
|
+
breaks?: boolean
|
|
7
|
+
headerIds?: boolean
|
|
8
|
+
headerPrefix?: string
|
|
9
|
+
highlight?: (code: string, lang: string) => string
|
|
10
|
+
pedantic?: boolean
|
|
11
|
+
smartLists?: boolean
|
|
12
|
+
smartypants?: boolean
|
|
13
|
+
sanitize?: boolean
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Parsed markdown with frontmatter
|
|
17
|
+
*/
|
|
18
|
+
export declare interface ParsedMarkdown<T = JsonObject> {
|
|
19
|
+
data: T
|
|
20
|
+
content: string
|
|
21
|
+
original: string
|
|
22
|
+
matter?: string
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* YAML parsing options
|
|
26
|
+
*/
|
|
27
|
+
export declare interface YamlOptions {
|
|
28
|
+
strict?: boolean
|
|
29
|
+
schema?: 'core' | 'json' | 'default'
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Binary CLI configuration
|
|
33
|
+
*/
|
|
34
|
+
export declare interface BinaryConfig {
|
|
35
|
+
from: string
|
|
36
|
+
verbose: boolean
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Token types for markdown parsing
|
|
40
|
+
*/
|
|
41
|
+
export declare interface Token {
|
|
42
|
+
type: string
|
|
43
|
+
raw: string
|
|
44
|
+
depth?: number
|
|
45
|
+
text?: string
|
|
46
|
+
tokens?: Token[]
|
|
47
|
+
lang?: string
|
|
48
|
+
href?: string
|
|
49
|
+
title?: string
|
|
50
|
+
ordered?: boolean
|
|
51
|
+
start?: number
|
|
52
|
+
loose?: boolean
|
|
53
|
+
items?: Token[]
|
|
54
|
+
header?: string[]
|
|
55
|
+
align?: Array<'left' | 'center' | 'right' | null>
|
|
56
|
+
rows?: string[][]
|
|
57
|
+
task?: boolean
|
|
58
|
+
checked?: boolean
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* JSON-compatible value types that YAML/TOML parsers can produce
|
|
62
|
+
*/
|
|
63
|
+
export type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue }
|
|
64
|
+
/**
|
|
65
|
+
* JSON-compatible object type
|
|
66
|
+
*/
|
|
67
|
+
export type JsonObject = { [key: string]: JsonValue }
|
package/dist/yaml.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { JsonObject, JsonValue, YamlOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Parse YAML string to JavaScript object
|
|
4
|
+
*/
|
|
5
|
+
export declare function parse<T = JsonObject>(input: string, options?: YamlOptions): T;
|
|
6
|
+
/**
|
|
7
|
+
* Stringify JavaScript object to YAML
|
|
8
|
+
*/
|
|
9
|
+
export declare function stringify(obj: JsonValue, _options?: YamlOptions): string;
|
package/package.json
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stacksjs/ts-md",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "A fast, native Bun-powered markdown parser with frontmatter support. Replaces gray-matter, marked, and yaml.",
|
|
6
|
+
"author": "Chris Breuer <chris@stacksjs.org>",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"homepage": "https://github.com/stacksjs/ts-md#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/stacksjs/ts-md.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/stacksjs/ts-md/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"markdown",
|
|
18
|
+
"frontmatter",
|
|
19
|
+
"parser",
|
|
20
|
+
"bun",
|
|
21
|
+
"yaml",
|
|
22
|
+
"gray-matter",
|
|
23
|
+
"marked",
|
|
24
|
+
"performance"
|
|
25
|
+
],
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"import": "./dist/index.js"
|
|
30
|
+
},
|
|
31
|
+
"./*": {
|
|
32
|
+
"import": "./dist/*"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"module": "./dist/index.js",
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"bin": {
|
|
38
|
+
"md": "./bin/cli.ts"
|
|
39
|
+
},
|
|
40
|
+
"files": ["LICENSE.md", "README.md", "dist", "bin/cli.ts"],
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "bun --bun build.ts",
|
|
43
|
+
"compile": "bun build ./bin/cli.ts --compile --minify --outfile bin/md",
|
|
44
|
+
"compile:all": "bun run compile:linux-x64 && bun run compile:linux-arm64 && bun run compile:windows-x64 && bun run compile:darwin-x64 && bun run compile:darwin-arm64",
|
|
45
|
+
"compile:linux-x64": "bun build ./bin/cli.ts --compile --minify --target=bun-linux-x64 --outfile bin/md-linux-x64",
|
|
46
|
+
"compile:linux-arm64": "bun build ./bin/cli.ts --compile --minify --target=bun-linux-arm64 --outfile bin/md-linux-arm64",
|
|
47
|
+
"compile:windows-x64": "bun build ./bin/cli.ts --compile --minify --target=bun-windows-x64 --outfile bin/md-windows-x64.exe",
|
|
48
|
+
"compile:darwin-x64": "bun build ./bin/cli.ts --compile --minify --target=bun-darwin-x64 --outfile bin/md-darwin-x64",
|
|
49
|
+
"compile:darwin-arm64": "bun build ./bin/cli.ts --compile --minify --target=bun-darwin-arm64 --outfile bin/md-darwin-arm64",
|
|
50
|
+
"zip": "bun run zip:all",
|
|
51
|
+
"zip:all": "bun run zip:linux-x64 && bun run zip:linux-arm64 && bun run zip:windows-x64 && bun run zip:darwin-x64 && bun run zip:darwin-arm64",
|
|
52
|
+
"zip:linux-x64": "zip -j bin/md-linux-x64.zip bin/md-linux-x64",
|
|
53
|
+
"zip:linux-arm64": "zip -j bin/md-linux-arm64.zip bin/md-linux-arm64",
|
|
54
|
+
"zip:windows-x64": "zip -j bin/md-windows-x64.zip bin/md-windows-x64.exe",
|
|
55
|
+
"zip:darwin-x64": "zip -j bin/md-darwin-x64.zip bin/md-darwin-x64",
|
|
56
|
+
"zip:darwin-arm64": "zip -j bin/md-darwin-arm64.zip bin/md-darwin-arm64",
|
|
57
|
+
"fresh": "bunx rimraf node_modules/ bun.lock && bun i",
|
|
58
|
+
"prepublishOnly": "bun --bun run build && bun run compile:all && bun run zip",
|
|
59
|
+
"test": "bun test",
|
|
60
|
+
"test:watch": "bun test --watch",
|
|
61
|
+
"test:coverage": "bun test --coverage",
|
|
62
|
+
"bench": "bun benchmarks/markdown-bench.ts",
|
|
63
|
+
"bench:yaml": "bun benchmarks/yaml-bench.ts",
|
|
64
|
+
"bench:frontmatter": "bun benchmarks/frontmatter-bench.ts",
|
|
65
|
+
"bench:all": "bun run bench && bun run bench:yaml && bun run bench:frontmatter",
|
|
66
|
+
"lint": "bunx --bun pickier lint . --config pickier.config.ts --max-warnings 9999",
|
|
67
|
+
"lint:fix": "bunx --bun pickier lint . --fix --config pickier.config.ts --max-warnings 9999",
|
|
68
|
+
"format": "bunx --bun pickier format . --config pickier.config.ts",
|
|
69
|
+
"format:fix": "bunx --bun pickier format . --write --config pickier.config.ts",
|
|
70
|
+
"changelog": "bunx logsmith --verbose",
|
|
71
|
+
"changelog:generate": "bunx logsmith --output CHANGELOG.md",
|
|
72
|
+
"release": "bun run changelog:generate && bunx bumpx prompt --recursive",
|
|
73
|
+
"postinstall": "bunx git-hooks",
|
|
74
|
+
"dev:docs": "bun --bun vitepress dev docs",
|
|
75
|
+
"build:docs": "bun --bun vitepress build docs",
|
|
76
|
+
"preview:docs": "bun --bun vitepress preview docs",
|
|
77
|
+
"typecheck": "bun --bun tsc --noEmit"
|
|
78
|
+
},
|
|
79
|
+
"devDependencies": {
|
|
80
|
+
"@types/bun": "latest",
|
|
81
|
+
"better-dx": "^0.2.5",
|
|
82
|
+
"gray-matter": "^4.0.3",
|
|
83
|
+
"js-yaml": "^4.1.1",
|
|
84
|
+
"markdown-it": "^14.1.0",
|
|
85
|
+
"marked": "^17.0.1",
|
|
86
|
+
"mitata": "^1.0.34",
|
|
87
|
+
"remark": "^15.0.1",
|
|
88
|
+
"remark-html": "^16.0.1",
|
|
89
|
+
"showdown": "^2.1.0"
|
|
90
|
+
},
|
|
91
|
+
"git-hooks": {
|
|
92
|
+
"pre-commit": {
|
|
93
|
+
"staged-lint": {
|
|
94
|
+
"*.{js,ts,json,yaml,yml,md}": "bunx --bun pickier lint --fix"
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"commit-msg": "bunx gitlint --edit .git/COMMIT_EDITMSG"
|
|
98
|
+
}
|
|
99
|
+
}
|