@mirrordown/mdit-attrs 0.1.2 → 0.1.3

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 CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
 
4
4
 
5
+
6
+ ## 0.1.3
7
+ <sub>2026-06-28</sub>
8
+
9
+ - *(patch)*
10
+ Improve JSR package scores: add package descriptions, document all exported symbols (JSDoc), add READMEs for the inline-svg packages, clear slow-type errors on the exported hast handlers, and trim internal regex constants from the public API.
11
+
5
12
  ## 0.1.2
6
13
  <sub>2026-06-28</sub>
7
14
 
package/dist/index.d.mts CHANGED
@@ -1,12 +1,18 @@
1
1
  import { PluginWithOptions } from "markdown-it";
2
2
 
3
3
  //#region src/types.d.ts
4
+ /** A markdown-it rule that attribute lists can be attached to. */
4
5
  type AttrRuleName = "fence" | "inline" | "table" | "list" | "heading" | "hr" | "softbreak" | "block";
6
+ /** Delimiters and allowed characters for the attribute-list syntax. */
5
7
  interface DelimiterConfig {
8
+ /** Opening delimiter (default `{`). */
6
9
  left: string;
10
+ /** Closing delimiter (default `}`). */
7
11
  right: string;
12
+ /** Characters/patterns permitted inside the delimiters. */
8
13
  allowed: Array<string | RegExp>;
9
14
  }
15
+ /** Options for the {@link attrs} plugin. */
10
16
  interface AttrsOptions extends Partial<DelimiterConfig> {
11
17
  /**
12
18
  * Which rules to enable. "all" enables everything (default). false or []
@@ -14,11 +20,13 @@ interface AttrsOptions extends Partial<DelimiterConfig> {
14
20
  */
15
21
  rule?: "all" | boolean | AttrRuleName[];
16
22
  }
23
+ /** A parsed `[key, value]` attribute pair. */
17
24
  type Attr = [key: string, value: string];
18
25
  /** [startIndex, endIndex] within the token content string, exclusive of delimiters */
19
26
  type DelimiterRange = [start: number, end: number];
20
27
  //#endregion
21
28
  //#region src/plugin.d.ts
29
+ /** markdown-it plugin for attribute lists (`{.class #id key=value}`) on elements. */
22
30
  declare const attrs: PluginWithOptions<AttrsOptions>;
23
31
  //#endregion
24
32
  export { type Attr, type AttrRuleName, type AttrsOptions, type DelimiterConfig, type DelimiterRange, attrs };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/plugin.ts"],"mappings":";;;KAAY,YAAA;AAAA,UAUK,eAAA;EACf,IAAA;EACA,KAAA;EACA,OAAA,EAAS,KAAA,UAAe,MAAA;AAAA;AAAA,UAGT,YAAA,SAAqB,OAAA,CAAQ,eAAA;EAhBtB;AAUxB;;;EAWE,IAAA,qBAAyB,YAAA;AAAA;AAAA,KAGf,IAAA,IAAQ,GAAA,UAAa,KAAA;;KAGrB,cAAA,IAAkB,KAAA,UAAe,GAAA;;;cCtBhC,KAAA,EAAO,iBAAA,CAAkB,YAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/plugin.ts"],"mappings":";;;;KACY,YAAA;;UAWK,eAAA;EAXO;EAatB,IAAA;EAbsB;EAetB,KAAA;EAJe;EAMf,OAAA,EAAS,KAAA,UAAe,MAAA;AAAA;;UAIT,YAAA,SAAqB,OAAA,CAAQ,eAAA;EAN5C;;;;EAWA,IAAA,qBAAyB,YAAA;AAAA;AAL3B;AAAA,KASY,IAAA,IAAQ,GAAA,UAAa,KAAA;;KAGrB,cAAA,IAAkB,KAAA,UAAe,GAAA;;;;cC5BhC,KAAA,EAAO,iBAAA,CAAkB,YAAA"}
package/dist/index.mjs CHANGED
@@ -845,6 +845,7 @@ const createRules = (options) => {
845
845
  };
846
846
  //#endregion
847
847
  //#region src/plugin.ts
848
+ /** markdown-it plugin for attribute lists (`{.class #id key=value}`) on elements. */
848
849
  const attrs = (md, { left = "{", right = "}", allowed = [], rule = "all" } = {}) => {
849
850
  const rules = createRules({
850
851
  left,
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/helper/getAttrs.ts","../src/helper/addAttrs.ts","../src/helper/getDelimiterChecker.ts","../src/helper/testRule.ts","../src/helper/getMatchingOpeningToken.ts","../src/rules/block.ts","../src/rules/inline.ts","../src/rules/fence.ts","../src/rules/heading.ts","../src/rules/hr.ts","../src/rules/list.ts","../src/rules/softbreak.ts","../src/rules/table.ts","../src/rules/rules.ts","../src/plugin.ts"],"sourcesContent":["import type { Attr, DelimiterRange } from \"../types.js\";\n\nconst CLASS_MARKER = 46; // '.'\nconst ID_MARKER = 35; // '#'\nconst PAIR_SEPARATOR = 32; // ' '\nconst KEY_SEPARATOR = 61; // '='\nconst QUOTE_MARKER = 34; // '\"'\n\nconst DISALLOWED_KEY_CHARS = new Set([9, 10, 12, 32, 47, 62, 34, 39, 61]);\n\nexport const getAttrs = (\n str: string,\n range: DelimiterRange,\n allowed: Array<string | RegExp>\n): Attr[] => {\n let key = \"\";\n let value = \"\";\n let parsingKey = true;\n let valueInsideQuotes = false;\n const attrs: Attr[] = [];\n\n for (let i = range[0]; i < range[1]; i++) {\n const code = str.charCodeAt(i);\n\n if (code === KEY_SEPARATOR && parsingKey) {\n parsingKey = false;\n continue;\n }\n\n if (code === CLASS_MARKER && key === \"\") {\n key =\n str.charCodeAt(i + 1) === CLASS_MARKER ? (i++, \"css-module\") : \"class\";\n parsingKey = false;\n continue;\n }\n\n if (code === ID_MARKER && key === \"\") {\n key = \"id\";\n parsingKey = false;\n continue;\n }\n\n if (code === QUOTE_MARKER) {\n if (value === \"\" && !valueInsideQuotes) {\n valueInsideQuotes = true;\n } else if (valueInsideQuotes) {\n valueInsideQuotes = false;\n }\n continue;\n }\n\n if (code === PAIR_SEPARATOR && !valueInsideQuotes) {\n if (key !== \"\") {\n attrs.push([key, value]);\n key = \"\";\n value = \"\";\n parsingKey = true;\n }\n continue;\n }\n\n if (parsingKey) {\n if (!DISALLOWED_KEY_CHARS.has(code)) key += str[i];\n } else {\n value += str[i];\n }\n }\n\n if (key !== \"\") attrs.push([key, value]);\n\n if (allowed.length === 0) return attrs;\n return attrs.filter(([attr]) =>\n allowed.some((item) =>\n item instanceof RegExp ? item.test(attr) : item === attr\n )\n );\n};\n","import type Token from \"markdown-it/lib/token.mjs\";\nimport type { DelimiterRange } from \"../types.js\";\nimport { getAttrs } from \"./getAttrs.js\";\n\nexport const addAttrs = (\n token: Token,\n content: string,\n range: DelimiterRange,\n allowed: Array<string | RegExp>\n): void => {\n for (const [key, value] of getAttrs(content, range, allowed)) {\n if (key === \"class\" || key === \"css-module\") {\n token.attrJoin(key, value);\n } else {\n token.attrPush([key, value]);\n }\n }\n};\n","import type { DelimiterRange } from \"../types.js\";\n\ntype DelimiterPosition = \"start\" | \"end\" | \"only\";\n\nexport type DelimiterChecker = (\n str: string,\n pos: DelimiterPosition\n) => DelimiterRange | null;\n\n/**\n * Returns a function that checks whether `str` contains a valid attribute\n * block at the given position (\"start\", \"end\", or \"only\") and returns the\n * [start, end] range of the content inside the delimiters, or null if no\n * match. The returned range is exclusive of the delimiter characters.\n *\n * A valid block must contain at least one character (i.e. `{}` is invalid),\n * and the outer delimiters must not be repeated (i.e. `{{}}` is invalid).\n */\nexport const getDelimiterChecker = (\n left: string,\n right: string\n): DelimiterChecker => {\n const ll = left.length;\n const rl = right.length;\n const minLen = ll + 1 + rl;\n const doubleLeft = left + left;\n const doubleRight = right + right;\n\n return (str, pos): DelimiterRange | null => {\n if (str.length < minLen) return null;\n\n if (pos === \"start\" || pos === \"only\") {\n if (!str.startsWith(left)) return null;\n if (str.startsWith(doubleLeft)) return null;\n }\n\n if (pos === \"end\" || pos === \"only\") {\n if (!str.endsWith(right)) return null;\n if (str.endsWith(doubleRight)) return null;\n }\n\n if (pos === \"only\") {\n const contentEnd = str.length - rl;\n if (contentEnd <= ll) return null;\n return [ll, contentEnd];\n }\n\n if (pos === \"start\") {\n const end = str.indexOf(right, ll + 1);\n if (end === -1) return null;\n return [ll, end];\n }\n\n // pos === \"end\"\n const start = str.lastIndexOf(left, str.length - rl - 1);\n if (start === -1) return null;\n if (str.startsWith(left, start - ll)) return null;\n return [start + ll, str.length - rl];\n };\n};\n","// Token.meta is typed `any` by markdown-it; casts bridge to our richer rule-test predicates.\n/* oxlint-disable typescript/no-unsafe-type-assertion */\nimport type Token from \"markdown-it/lib/token.mjs\";\nimport type { DelimiterRange } from \"../types.js\";\nimport type { DelimiterChecker } from \"./getDelimiterChecker.js\";\n\nexport interface RuleTest {\n /** Offset from the current token index. Mutually exclusive with `position`. */\n shift?: number;\n /** Absolute token index. Mutually exclusive with `shift`. */\n position?: number;\n /** Token type must equal this string. */\n type?: string | ((t: string) => boolean);\n /** Token tag must equal this string. */\n tag?: string;\n /** Token nesting must equal this value. */\n nesting?: number | ((n: number) => boolean);\n /** Inspect token content; called with (content, token, tokens, index). */\n content?: string | ((c: string) => boolean);\n /** Inspect token.meta; predicate receives the meta object (may be null). */\n meta?: (meta: Record<string, unknown> | null) => boolean;\n /** Inspect a child token at the given index (negative = from end). */\n children?: Array<Omit<RuleTest, \"shift\" | \"position\"> & { index?: number }>;\n /** If set, use this delimiter checker to extract a range from token content. */\n attrChecker?: DelimiterChecker;\n /** Which position argument to pass to attrChecker (\"start\"|\"end\"|\"only\"). */\n attrPos?: \"start\" | \"end\" | \"only\";\n}\n\nexport interface TestResult {\n match: boolean;\n position: number | null;\n range: DelimiterRange | null;\n}\n\nconst matches = (test: unknown, actual: unknown): boolean => {\n if (typeof test === \"function\")\n return (test as (v: unknown) => boolean)(actual);\n return test === actual;\n};\n\nconst testChild = (\n child: Token,\n childTest: Omit<RuleTest, \"shift\" | \"position\">\n): { match: boolean; range: DelimiterRange | null } => {\n let range: DelimiterRange | null = null;\n\n if (childTest.type !== undefined && !matches(childTest.type, child.type)) {\n return { match: false, range: null };\n }\n if (\n childTest.nesting !== undefined &&\n !matches(childTest.nesting, child.nesting)\n ) {\n return { match: false, range: null };\n }\n if (childTest.tag !== undefined && child.tag !== childTest.tag) {\n return { match: false, range: null };\n }\n if (childTest.content !== undefined) {\n if (!matches(childTest.content, child.content))\n return { match: false, range: null };\n }\n if (childTest.attrChecker) {\n range = childTest.attrChecker(child.content, childTest.attrPos ?? \"only\");\n if (!range) return { match: false, range: null };\n }\n\n return { match: true, range };\n};\n\nexport const testRule = (\n tokens: Token[],\n index: number,\n test: RuleTest\n): TestResult => {\n let tokenIndex: number;\n if (test.position !== undefined) {\n tokenIndex =\n test.position < 0 ? tokens.length + test.position : test.position;\n } else {\n tokenIndex = index + (test.shift ?? 0);\n }\n\n const token = tokens[tokenIndex];\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (!token) return { match: false, position: null, range: null };\n\n let range: DelimiterRange | null = null;\n\n if (test.type !== undefined && !matches(test.type, token.type)) {\n return { match: false, position: null, range: null };\n }\n if (test.nesting !== undefined && !matches(test.nesting, token.nesting)) {\n return { match: false, position: null, range: null };\n }\n if (test.tag !== undefined && token.tag !== test.tag) {\n return { match: false, position: null, range: null };\n }\n if (test.content !== undefined && !matches(test.content, token.content)) {\n return { match: false, position: null, range: null };\n }\n if (\n test.meta !== undefined &&\n !test.meta((token.meta as Record<string, unknown> | null) ?? null)\n ) {\n return { match: false, position: null, range: null };\n }\n if (test.attrChecker) {\n range = test.attrChecker(token.content, test.attrPos ?? \"only\");\n if (!range) return { match: false, position: null, range: null };\n }\n\n if (test.children) {\n const children = token.children ?? [];\n for (const childTest of test.children) {\n const idx =\n childTest.index !== undefined\n ? childTest.index < 0\n ? children.length + childTest.index\n : childTest.index\n : -1;\n\n if (idx >= 0) {\n const child = children[idx];\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (!child) return { match: false, position: null, range: null };\n const result = testChild(child, childTest);\n if (!result.match) return { match: false, position: null, range: null };\n if (result.range) range = result.range;\n } else {\n // No index: find any matching child\n const found = children.some((child) => {\n const result = testChild(child, childTest);\n if (result.range) range = result.range;\n return result.match;\n });\n if (!found) return { match: false, position: null, range: null };\n }\n }\n }\n\n return { match: true, position: tokenIndex, range };\n};\n","import type Token from \"markdown-it/lib/token.mjs\";\n\n/**\n * Given a closing or self-closing token at `index`, returns its matching\n * opening token by walking backwards to find the token of the same type at\n * the same nesting level. Returns the token itself for nesting === 0.\n */\nexport const getMatchingOpeningToken = (\n tokens: Token[],\n index: number\n): Token | null => {\n const token = tokens[index];\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (!token) return null;\n if (token.type === \"softbreak\") return null;\n if (token.nesting === 0) return token;\n\n const target = token.type.replace(/_close$/, \"_open\");\n let depth = 0;\n\n for (let i = index; i >= 0; i--) {\n const t = tokens[i];\n if (t.type === token.type) depth++;\n else if (t.type === target) {\n depth--;\n if (depth === 0) return t;\n }\n }\n\n return null;\n};\n","import type { DelimiterConfig } from \"../types.js\";\nimport {\n addAttrs,\n getDelimiterChecker,\n getMatchingOpeningToken\n} from \"../helper/index.js\";\nimport type { AttrRule } from \"./types.js\";\n\n// Token types that should not be treated as attr targets\nconst SKIP_TYPES = new Set([\n \"code_inline\",\n \"math_inline\",\n \"fence\",\n \"code_block\"\n]);\n\nexport const createBlockRule = (options: DelimiterConfig): AttrRule => {\n const check = getDelimiterChecker(options.left, options.right);\n\n return {\n name: \"block attributes\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n index: -1,\n type: (t: string) => !SKIP_TYPES.has(t),\n content: (content: string) => check(content.trim(), \"end\") !== null\n }\n ]\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const children = inline.children!;\n const lastChild = children[children.length - 1];\n\n const content = lastChild.content.trimEnd();\n const range = check(content, \"end\")!;\n\n // Find the block-level opening token that contains this inline\n // Walk backwards: skip the paragraph_open immediately before, then\n // look for the outermost open that wraps this inline token.\n let openToken = null;\n\n // First: find the _close token that closes the block containing this inline\n // by walking forward from the inline's position\n let closeIdx = index + 1;\n while (closeIdx < tokens.length && tokens[closeIdx].nesting !== -1) {\n closeIdx++;\n }\n\n if (closeIdx < tokens.length) {\n openToken = getMatchingOpeningToken(tokens, closeIdx);\n }\n\n if (!openToken) return;\n if (SKIP_TYPES.has(openToken.type)) return;\n\n addAttrs(openToken, content, range, options.allowed);\n\n // Strip the attr block from the last child's content\n const attrStart = content.lastIndexOf(options.left, range[0] - 1);\n lastChild.content = content.slice(0, attrStart).trimEnd();\n\n // Drop the child if now empty\n if (lastChild.content === \"\" && children.length > 1) {\n children.pop();\n }\n }\n };\n};\n","import type { DelimiterConfig } from \"../types.js\";\nimport { addAttrs, getDelimiterChecker } from \"../helper/index.js\";\nimport type { AttrRule } from \"./types.js\";\n\nexport const createInlineRules = (options: DelimiterConfig): AttrRule[] => {\n const check = getDelimiterChecker(options.left, options.right);\n\n // Handles self-closing inline elements: `code`, images (nesting === 0)\n const selfClose: AttrRule = {\n name: \"inline nesting self-close\",\n tests: [{ shift: 0, type: \"inline\" }],\n transform(tokens, index) {\n const token = tokens[index];\n const children = token.children!;\n let modified = false;\n\n for (let i = children.length - 1; i >= 0; i--) {\n const child = children[i];\n if (child.type !== \"text\") continue;\n\n const range = check(child.content, \"only\");\n if (!range) continue;\n\n // The preceding sibling must be nesting === 0 but not a softbreak\n const prev = children[i - 1];\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (prev?.nesting !== 0 || prev.type === \"softbreak\") continue;\n\n addAttrs(prev, child.content, range, options.allowed);\n children.splice(i, 1);\n modified = true;\n }\n\n return modified;\n }\n };\n\n // Handles closing inline elements: em, strong, s, etc. (nesting === -1)\n const closing: AttrRule = {\n name: \"inline attributes\",\n tests: [\n {\n shift: 0,\n type: \"inline\"\n }\n ],\n transform(tokens, index) {\n const token = tokens[index];\n const children = token.children!;\n let modified = false;\n\n for (let i = children.length - 1; i >= 0; i--) {\n const child = children[i];\n if (child.type !== \"text\") continue;\n\n const range = check(child.content, \"only\");\n if (!range) continue;\n\n // The preceding sibling must be a closing tag (nesting === -1)\n const prev = children[i - 1];\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (!prev || prev.nesting !== -1) continue;\n\n // Find the matching opening token among children\n const openType = prev.type.replace(/_close$/, \"_open\");\n let openIdx = -1;\n for (let j = i - 2; j >= 0; j--) {\n if (\n children[j].type === openType &&\n children[j].level === prev.level\n ) {\n openIdx = j;\n break;\n }\n }\n if (openIdx === -1) continue;\n\n addAttrs(children[openIdx], child.content, range, options.allowed);\n children.splice(i, 1);\n modified = true;\n }\n\n return modified;\n }\n };\n\n return [selfClose, closing];\n};\n","import type { DelimiterConfig } from \"../types.js\";\nimport { addAttrs, getDelimiterChecker } from \"../helper/index.js\";\nimport type { AttrRule } from \"./types.js\";\n\nexport const createFenceRule = (options: DelimiterConfig): AttrRule => {\n const check = getDelimiterChecker(options.left, options.right);\n\n return {\n name: \"fence attributes\",\n tests: [\n {\n shift: 0,\n type: \"fence\"\n }\n ],\n transform(tokens, index) {\n const token = tokens[index];\n const info = token.info.trim();\n const range = check(info, \"end\") ?? check(info, \"only\");\n if (!range) return;\n addAttrs(token, info, range, options.allowed);\n // Strip the attr block from the info string, preserving the language tag\n token.info = info\n .slice(0, info.lastIndexOf(options.left, range[0] - 1))\n .trimEnd();\n }\n };\n};\n","import type { DelimiterConfig } from \"../types.js\";\nimport { addAttrs, getDelimiterChecker } from \"../helper/index.js\";\nimport type { AttrRule } from \"./types.js\";\n\nexport const createHeadingRule = (options: DelimiterConfig): AttrRule => {\n const check = getDelimiterChecker(options.left, options.right);\n\n return {\n name: \"heading attributes\",\n tests: [\n {\n shift: 0,\n type: \"heading_open\"\n },\n {\n shift: 1,\n type: \"inline\",\n children: [\n {\n index: -1,\n type: (t: string) => t !== \"code_inline\" && t !== \"math_inline\",\n content: (content: string) => check(content.trim(), \"end\") !== null\n }\n ]\n }\n ],\n transform(tokens, index) {\n const openToken = tokens[index];\n const inline = tokens[index + 1];\n const children = inline.children!;\n const lastChild = children[children.length - 1];\n\n const content = lastChild.content;\n const trimmed = content.trimEnd();\n const range = check(trimmed, \"end\")!;\n\n addAttrs(openToken, trimmed, range, options.allowed);\n\n // Strip the attr block from the last child content\n const before = trimmed.slice(\n 0,\n trimmed.lastIndexOf(options.left, range[0] - 1)\n );\n lastChild.content = before.trimEnd();\n\n // Drop the child entirely if it's now empty\n if (lastChild.content === \"\" && children.length > 1) {\n children.pop();\n }\n }\n };\n};\n","import type { DelimiterConfig } from \"../types.js\";\nimport { addAttrs, getDelimiterChecker } from \"../helper/index.js\";\nimport type { AttrRule } from \"./types.js\";\n\nexport const createHrRule = (options: DelimiterConfig): AttrRule => {\n const check = getDelimiterChecker(options.left, options.right);\n\n return {\n name: \"hr attributes\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n index: 0,\n type: \"text\",\n content: (content: string) => check(content.trim(), \"only\") !== null\n }\n ]\n },\n {\n shift: -2,\n type: \"hr\"\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const textChild = inline.children![0];\n const content = textChild.content.trim();\n const range = check(content, \"only\")!;\n\n const hr = tokens[index - 2];\n addAttrs(hr, content, range, options.allowed);\n\n // Remove paragraph_open + inline + paragraph_close\n tokens.splice(index - 1, 3);\n }\n };\n};\n","import type { DelimiterConfig } from \"../types.js\";\nimport { addAttrs, getDelimiterChecker } from \"../helper/index.js\";\nimport type { AttrRule } from \"./types.js\";\n\nexport const createListRules = (options: DelimiterConfig): AttrRule[] => {\n const check = getDelimiterChecker(options.left, options.right);\n\n // Rule 1: attrs at end of a list item inline \"- item{.red}\"\n // Structure: list_item_open(-2) paragraph_open(-1) inline(0)\n const listItemEnd: AttrRule = {\n name: \"list item end\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n index: -1,\n type: (t: string) => t !== \"code_inline\",\n content: (content: string) => check(content.trim(), \"end\") !== null\n }\n ]\n },\n {\n shift: -1,\n type: \"paragraph_open\"\n },\n {\n shift: -2,\n type: \"list_item_open\"\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const children = inline.children!;\n const lastChild = children[children.length - 1];\n const content = lastChild.content.trimEnd();\n const range = check(content, \"end\")!;\n\n const listItemOpen = tokens[index - 2];\n addAttrs(listItemOpen, content, range, options.allowed);\n\n const attrStart = content.lastIndexOf(options.left, range[0] - 1);\n lastChild.content = content.slice(0, attrStart).trimEnd();\n if (lastChild.content === \"\" && children.length > 1) children.pop();\n }\n };\n\n // Rule 1b (generic): attrs at end of a custom item title inline\n // Matches when the open token two before the inline has meta.attrsRole === \"containerItem\"\n // and the token one before has meta.attrsItemTitle === true.\n // Third-party plugins opt in by setting these meta fields on their tokens.\n const customItemEnd: AttrRule = {\n name: \"custom item end\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n index: -1,\n type: (t: string) => t !== \"code_inline\",\n content: (content: string) => check(content.trim(), \"end\") !== null\n }\n ]\n },\n {\n shift: -1,\n meta: (m) => m?.attrsItemTitle === true\n },\n {\n shift: -2,\n meta: (m) => m?.attrsRole === \"containerItem\"\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const children = inline.children!;\n const lastChild = children[children.length - 1];\n const content = lastChild.content.trimEnd();\n const range = check(content, \"end\")!;\n\n const itemOpen = tokens[index - 2];\n addAttrs(itemOpen, content, range, options.allowed);\n\n const attrStart = content.lastIndexOf(options.left, range[0] - 1);\n lastChild.content = content.slice(0, attrStart).trimEnd();\n if (lastChild.content === \"\" && children.length > 1) children.pop();\n }\n };\n\n // Rule 1c (direct): attrs at end of a custom item inline where the open token\n // itself carries both attrsRole === \"containerItem\" AND attrsItemTitle === true.\n // Matches dt_open → inline (no intermediate title token).\n const customItemEndDirect: AttrRule = {\n name: \"custom item end direct\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n index: -1,\n type: (t: string) => t !== \"code_inline\",\n content: (content: string) => check(content.trim(), \"end\") !== null\n }\n ]\n },\n {\n shift: -1,\n meta: (m: Record<string, unknown> | null) =>\n m?.attrsItemTitle === true && m.attrsRole === \"containerItem\"\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const children = inline.children!;\n const lastChild = children[children.length - 1];\n const content = lastChild.content.trimEnd();\n const range = check(content, \"end\")!;\n\n const itemOpen = tokens[index - 1];\n addAttrs(itemOpen, content, range, options.allowed);\n\n const attrStart = content.lastIndexOf(options.left, range[0] - 1);\n lastChild.content = content.slice(0, attrStart).trimEnd();\n if (lastChild.content === \"\" && children.length > 1) children.pop();\n }\n };\n\n // Rule 2: attrs on own paragraph after bullet/ordered list close → apply to list\n // Structure: bullet_list_close(-2) paragraph_open(-1) inline(0) paragraph_close(+1)\n const listAttr: AttrRule = {\n name: \"list attributes\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n index: 0,\n type: \"text\",\n content: (content: string) => check(content.trim(), \"only\") !== null\n }\n ]\n },\n {\n shift: -1,\n type: \"paragraph_open\"\n },\n {\n shift: -2,\n type: (t: string) =>\n t === \"bullet_list_close\" || t === \"ordered_list_close\"\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const children = inline.children!;\n const textChild = children[0];\n const content = textChild.content.trim();\n const range = check(content, \"only\")!;\n\n // Find the matching list_open for the close token at index-2\n const closeToken = tokens[index - 2];\n const openType = closeToken.type.replace(\"_close\", \"_open\");\n\n let depth = 1;\n let listOpenIdx = -1;\n for (let i = index - 3; i >= 0; i--) {\n const t = tokens[i];\n if (t.type === closeToken.type) depth++;\n else if (t.type === openType) {\n depth--;\n if (depth === 0) {\n listOpenIdx = i;\n break;\n }\n }\n }\n\n if (listOpenIdx === -1) return;\n addAttrs(tokens[listOpenIdx], content, range, options.allowed);\n\n // Remove paragraph_open + inline + paragraph_close\n tokens.splice(index - 1, 3);\n }\n };\n\n // Rule 2b (generic): attrs on own paragraph after a custom container close → apply to container open\n // Matches when the close token two before the paragraph has meta.attrsRole === \"container\".\n // Third-party plugins opt in by setting meta.attrsRole = \"container\" on their open/close tokens.\n const customListAttr: AttrRule = {\n name: \"custom list attributes\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n index: 0,\n type: \"text\",\n content: (content: string) => check(content.trim(), \"only\") !== null\n }\n ]\n },\n {\n shift: -1,\n type: \"paragraph_open\"\n },\n {\n shift: -2,\n type: (t: string) => t.endsWith(\"_close\"),\n meta: (m) => m?.attrsRole === \"container\"\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const children = inline.children!;\n const textChild = children[0];\n const content = textChild.content.trim();\n const range = check(content, \"only\")!;\n\n // Walk back to find the matching open token (same type with _open suffix)\n const closeToken = tokens[index - 2];\n const openType = closeToken.type.replace(\"_close\", \"_open\");\n\n let depth = 1;\n let listOpenIdx = -1;\n for (let i = index - 3; i >= 0; i--) {\n const t = tokens[i];\n if (t.type === closeToken.type) depth++;\n else if (t.type === openType) {\n depth--;\n if (depth === 0) {\n listOpenIdx = i;\n break;\n }\n }\n }\n\n if (listOpenIdx === -1) return;\n addAttrs(tokens[listOpenIdx], content, range, options.allowed);\n\n // Remove paragraph_open + inline + paragraph_close\n tokens.splice(index - 1, 3);\n }\n };\n\n return [\n listItemEnd,\n customItemEnd,\n customItemEndDirect,\n listAttr,\n customListAttr\n ];\n};\n","import type { DelimiterConfig } from \"../types.js\";\nimport { addAttrs, getDelimiterChecker } from \"../helper/index.js\";\nimport type { AttrRule } from \"./types.js\";\n\nexport const createSoftbreakRule = (options: DelimiterConfig): AttrRule => {\n const check = getDelimiterChecker(options.left, options.right);\n\n return {\n name: \"softbreak attributes\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n // second-to-last child must be a softbreak\n index: -2,\n type: \"softbreak\"\n },\n {\n // last child must be a text node containing only an attr block\n index: -1,\n type: \"text\",\n content: (content: string) => check(content.trim(), \"only\") !== null\n }\n ]\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const children = inline.children!;\n const attrChild = children[children.length - 1];\n\n const content = attrChild.content.trim();\n const range = check(content, \"only\")!;\n\n // Walk backward to find the nearest nesting===1 opener that contains this inline\n let target = tokens[index];\n for (let i = index - 1; i >= 0; i--) {\n const t = tokens[i];\n if (t.nesting === 1) {\n target = t;\n break;\n }\n }\n\n addAttrs(target, content, range, options.allowed);\n\n // Remove the attr text child and the preceding softbreak\n children.splice(children.length - 2, 2);\n }\n };\n};\n","// TableMeta lives on Token.meta which markdown-it types as any — casts narrow to the rule-specific shape.\n/* oxlint-disable typescript/no-unsafe-type-assertion */\nimport type { DelimiterConfig } from \"../types.js\";\nimport { addAttrs, getDelimiterChecker } from \"../helper/index.js\";\nimport type { AttrRule } from \"./types.js\";\n\nexport const createTableRules = (options: DelimiterConfig): AttrRule[] => {\n const check = getDelimiterChecker(options.left, options.right);\n\n // Rule 1: table-level attrs — standalone paragraph after the table \"\\n{.class}\"\n const tableAttrs: AttrRule = {\n name: \"table attributes\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n index: 0,\n type: \"text\",\n content: (content: string) => check(content.trim(), \"only\") !== null\n }\n ]\n },\n {\n shift: -1,\n type: \"paragraph_open\"\n },\n {\n shift: -2,\n type: \"table_close\"\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const content = inline.children![0].content.trim();\n const range = check(content, \"only\")!;\n\n // Find the matching table_open (start from table_close at index-2)\n let tableOpenIdx = -1;\n let depth = 1;\n for (let i = index - 3; i >= 0; i--) {\n const t = tokens[i];\n if (t.type === \"table_close\") depth++;\n else if (t.type === \"table_open\") {\n depth--;\n if (depth === 0) {\n tableOpenIdx = i;\n break;\n }\n }\n }\n if (tableOpenIdx === -1) return;\n\n addAttrs(tokens[tableOpenIdx], content, range, options.allowed);\n\n // Remove paragraph_open + inline + paragraph_close\n tokens.splice(index - 1, 3);\n }\n };\n\n // Rule 2: table cell attrs — \"cell content {.class}\" inside td/th\n const tableCellAttrs: AttrRule = {\n name: \"table cell attributes\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n index: -1,\n type: \"text\",\n content: (content: string) => check(content.trim(), \"end\") !== null\n }\n ]\n },\n {\n shift: -1,\n type: (t: string) => t === \"td_open\" || t === \"th_open\"\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const children = inline.children!;\n const lastChild = children[children.length - 1];\n const content = lastChild.content.trimEnd();\n const range = check(content, \"end\")!;\n\n const cellOpen = tokens[index - 1];\n addAttrs(cellOpen, content, range, options.allowed);\n\n const attrStart = content.lastIndexOf(options.left, range[0] - 1);\n lastChild.content = content.slice(0, attrStart).trimEnd();\n if (lastChild.content === \"\" && children.length > 1) children.pop();\n }\n };\n\n // Rule 3: track column count in thead (stored as metadata for rowspan/colspan calc)\n interface TableMeta {\n cols: number;\n rowspan: number[];\n }\n\n const colTracker: AttrRule = {\n name: \"table column tracker\",\n tests: [{ shift: 0, type: \"tr_open\" }],\n transform(tokens, index) {\n // Count th tokens in this row to know column count; stored on thead_open meta\n let cols = 0;\n for (let i = index + 1; i < tokens.length; i++) {\n const t = tokens[i];\n if (t.type === \"tr_close\") break;\n if (t.type === \"th_open\") cols++;\n }\n if (cols === 0) return;\n\n // Find thead_open and store column count\n for (let i = index - 1; i >= 0; i--) {\n const t = tokens[i];\n if (t.type === \"thead_open\") {\n t.meta = t.meta ?? {};\n (t.meta as TableMeta).cols = cols;\n break;\n }\n if (t.type === \"table_open\") break;\n }\n }\n };\n\n // Rule 4: colspan/rowspan calculation — remove phantom cells, adjust span values\n const spanCalc: AttrRule = {\n name: \"table span calculator\",\n tests: [{ shift: 0, type: \"tbody_open\" }],\n transform(tokens, index) {\n // Find matching thead_open to get column count\n let cols = 0;\n for (let i = index - 1; i >= 0; i--) {\n const t = tokens[i];\n if (t.type === \"thead_open\") {\n cols = (t.meta as TableMeta | undefined)?.cols ?? 0;\n break;\n }\n if (t.type === \"table_open\") break;\n }\n if (cols === 0) return;\n\n // Find the tbody_close\n let tbodyClose = index + 1;\n let depth = 1;\n while (tbodyClose < tokens.length && depth > 0) {\n const t = tokens[tbodyClose];\n if (t.type === \"tbody_open\") depth++;\n else if (t.type === \"tbody_close\") depth--;\n tbodyClose++;\n }\n tbodyClose--;\n\n // Process each row within tbody\n const occupied: number[] = Array.from({ length: cols }, () => 0);\n\n let i = index + 1;\n while (i < tbodyClose) {\n const t = tokens[i];\n if (t.type === \"tr_open\") {\n // Decrement all occupied counts\n for (let c = 0; c < cols; c++) {\n if (occupied[c] > 0) occupied[c]--;\n }\n\n // Collect td tokens in this row\n const tdIndices: number[] = [];\n for (let j = i + 1; j < tbodyClose; j++) {\n if (tokens[j].type === \"tr_close\") break;\n if (tokens[j].type === \"td_open\") tdIndices.push(j);\n }\n\n // Assign cells to columns, skipping occupied ones\n let col = 0;\n let tdIdx = 0;\n\n while (col < cols && tdIdx < tdIndices.length) {\n // Skip occupied columns (from rowspan)\n while (col < cols && occupied[col] > 0) col++;\n if (col >= cols) break;\n\n const tdOpen = tokens[tdIndices[tdIdx]];\n const rowspanAttr = tdOpen.attrGet(\"rowspan\");\n const colspanAttr = tdOpen.attrGet(\"colspan\");\n const rowspan = rowspanAttr ? parseInt(rowspanAttr, 10) : 1;\n let colspan = colspanAttr ? parseInt(colspanAttr, 10) : 1;\n\n // Count how many consecutive free columns are available\n let freeCols = 0;\n for (let c = col; c < cols && occupied[c] === 0; c++) freeCols++;\n\n // Clamp colspan to available free columns\n if (colspan > freeCols) {\n colspan = freeCols;\n if (colspan === 1) {\n // Remove colspan attr if it resolved to 1 (keep as-is if explicitly set)\n // We keep it to match reference behavior: colspan=\"1\" is left on token\n }\n tdOpen.attrSet(\"colspan\", String(colspan));\n }\n\n // Mark columns occupied by this cell's rowspan\n for (let c = col; c < col + colspan && c < cols; c++) {\n if (rowspan > 1) occupied[c] = rowspan - 1;\n }\n\n col += colspan;\n tdIdx++;\n }\n\n // Remove phantom cells beyond assigned ones\n // (cells that were merged away by rowspan from a previous row)\n while (tdIdx < tdIndices.length) {\n const phantomStart = tdIndices[tdIdx];\n // Find the matching td_close\n let phantomEnd = phantomStart + 1;\n while (\n phantomEnd < tokens.length &&\n tokens[phantomEnd].type !== \"td_close\"\n ) {\n phantomEnd++;\n }\n tokens.splice(phantomStart, phantomEnd - phantomStart + 1);\n tbodyClose -= phantomEnd - phantomStart + 1;\n // Don't increment tdIdx since we just spliced\n }\n }\n i++;\n }\n }\n };\n\n return [tableAttrs, tableCellAttrs, colTracker, spanCalc];\n};\n","import type { AttrsOptions, AttrRuleName, DelimiterConfig } from \"../types.js\";\nimport type { AttrRule } from \"./types.js\";\nimport { createBlockRule } from \"./block.js\";\nimport { createInlineRules } from \"./inline.js\";\nimport { createFenceRule } from \"./fence.js\";\nimport { createHeadingRule } from \"./heading.js\";\nimport { createHrRule } from \"./hr.js\";\nimport { createListRules } from \"./list.js\";\nimport { createSoftbreakRule } from \"./softbreak.js\";\nimport { createTableRules } from \"./table.js\";\n\nconst ALL_RULE_NAMES: AttrRuleName[] = [\n \"fence\",\n \"inline\",\n \"table\",\n \"list\",\n \"heading\",\n \"hr\",\n \"softbreak\",\n \"block\"\n];\n\nconst ALL_RULE_SET = new Set<string>(ALL_RULE_NAMES);\n\nexport const createRules = (\n options: DelimiterConfig & Pick<AttrsOptions, \"rule\">\n): AttrRule[] => {\n const { rule = \"all\" } = options;\n\n let enabled: Set<string>;\n if (rule === \"all\" || rule === true) {\n enabled = ALL_RULE_SET;\n } else if (!rule || (Array.isArray(rule) && rule.length === 0)) {\n return [];\n } else {\n enabled = new Set(rule.filter((r) => ALL_RULE_SET.has(r)));\n }\n\n const rules: AttrRule[] = [];\n\n if (enabled.has(\"fence\")) rules.push(createFenceRule(options));\n if (enabled.has(\"inline\")) rules.push(...createInlineRules(options));\n if (enabled.has(\"table\")) rules.push(...createTableRules(options));\n if (enabled.has(\"list\")) rules.push(...createListRules(options));\n if (enabled.has(\"heading\")) rules.push(createHeadingRule(options));\n if (enabled.has(\"hr\")) rules.push(createHrRule(options));\n if (enabled.has(\"softbreak\")) rules.push(createSoftbreakRule(options));\n if (enabled.has(\"block\")) rules.push(createBlockRule(options));\n\n return rules;\n};\n","import type { PluginWithOptions } from \"markdown-it\";\nimport type { AttrsOptions, DelimiterRange } from \"./types.js\";\nimport { createRules } from \"./rules/index.js\";\nimport { testRule } from \"./helper/index.js\";\n\nexport const attrs: PluginWithOptions<AttrsOptions> = (\n md,\n { left = \"{\", right = \"}\", allowed = [], rule = \"all\" } = {}\n) => {\n const rules = createRules({ left, right, allowed, rule });\n\n md.core.ruler.before(\"linkify\", \"attrs\", (state) => {\n const { tokens } = state;\n\n for (let index = 0; index < tokens.length; index++) {\n for (let ruleIndex = 0; ruleIndex < rules.length; ruleIndex++) {\n const pattern = rules[ruleIndex];\n let position: number | null = null;\n let range: DelimiterRange | null = null;\n\n const match = pattern.tests.every((test) => {\n const result = testRule(tokens, index, test);\n if (result.position != null) position = result.position;\n if (result.range) range = result.range;\n return result.match;\n });\n\n if (match) {\n const modified = pattern.transform(tokens, index, position!, range!);\n\n if (\n modified !== false &&\n (pattern.name === \"inline attributes\" ||\n pattern.name === \"inline nesting self-close\")\n ) {\n ruleIndex--;\n }\n }\n }\n }\n });\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/helper/getAttrs.ts","../src/helper/addAttrs.ts","../src/helper/getDelimiterChecker.ts","../src/helper/testRule.ts","../src/helper/getMatchingOpeningToken.ts","../src/rules/block.ts","../src/rules/inline.ts","../src/rules/fence.ts","../src/rules/heading.ts","../src/rules/hr.ts","../src/rules/list.ts","../src/rules/softbreak.ts","../src/rules/table.ts","../src/rules/rules.ts","../src/plugin.ts"],"sourcesContent":["import type { Attr, DelimiterRange } from \"../types.js\";\n\nconst CLASS_MARKER = 46; // '.'\nconst ID_MARKER = 35; // '#'\nconst PAIR_SEPARATOR = 32; // ' '\nconst KEY_SEPARATOR = 61; // '='\nconst QUOTE_MARKER = 34; // '\"'\n\nconst DISALLOWED_KEY_CHARS = new Set([9, 10, 12, 32, 47, 62, 34, 39, 61]);\n\nexport const getAttrs = (\n str: string,\n range: DelimiterRange,\n allowed: Array<string | RegExp>\n): Attr[] => {\n let key = \"\";\n let value = \"\";\n let parsingKey = true;\n let valueInsideQuotes = false;\n const attrs: Attr[] = [];\n\n for (let i = range[0]; i < range[1]; i++) {\n const code = str.charCodeAt(i);\n\n if (code === KEY_SEPARATOR && parsingKey) {\n parsingKey = false;\n continue;\n }\n\n if (code === CLASS_MARKER && key === \"\") {\n key =\n str.charCodeAt(i + 1) === CLASS_MARKER ? (i++, \"css-module\") : \"class\";\n parsingKey = false;\n continue;\n }\n\n if (code === ID_MARKER && key === \"\") {\n key = \"id\";\n parsingKey = false;\n continue;\n }\n\n if (code === QUOTE_MARKER) {\n if (value === \"\" && !valueInsideQuotes) {\n valueInsideQuotes = true;\n } else if (valueInsideQuotes) {\n valueInsideQuotes = false;\n }\n continue;\n }\n\n if (code === PAIR_SEPARATOR && !valueInsideQuotes) {\n if (key !== \"\") {\n attrs.push([key, value]);\n key = \"\";\n value = \"\";\n parsingKey = true;\n }\n continue;\n }\n\n if (parsingKey) {\n if (!DISALLOWED_KEY_CHARS.has(code)) key += str[i];\n } else {\n value += str[i];\n }\n }\n\n if (key !== \"\") attrs.push([key, value]);\n\n if (allowed.length === 0) return attrs;\n return attrs.filter(([attr]) =>\n allowed.some((item) =>\n item instanceof RegExp ? item.test(attr) : item === attr\n )\n );\n};\n","import type Token from \"markdown-it/lib/token.mjs\";\nimport type { DelimiterRange } from \"../types.js\";\nimport { getAttrs } from \"./getAttrs.js\";\n\nexport const addAttrs = (\n token: Token,\n content: string,\n range: DelimiterRange,\n allowed: Array<string | RegExp>\n): void => {\n for (const [key, value] of getAttrs(content, range, allowed)) {\n if (key === \"class\" || key === \"css-module\") {\n token.attrJoin(key, value);\n } else {\n token.attrPush([key, value]);\n }\n }\n};\n","import type { DelimiterRange } from \"../types.js\";\n\ntype DelimiterPosition = \"start\" | \"end\" | \"only\";\n\nexport type DelimiterChecker = (\n str: string,\n pos: DelimiterPosition\n) => DelimiterRange | null;\n\n/**\n * Returns a function that checks whether `str` contains a valid attribute\n * block at the given position (\"start\", \"end\", or \"only\") and returns the\n * [start, end] range of the content inside the delimiters, or null if no\n * match. The returned range is exclusive of the delimiter characters.\n *\n * A valid block must contain at least one character (i.e. `{}` is invalid),\n * and the outer delimiters must not be repeated (i.e. `{{}}` is invalid).\n */\nexport const getDelimiterChecker = (\n left: string,\n right: string\n): DelimiterChecker => {\n const ll = left.length;\n const rl = right.length;\n const minLen = ll + 1 + rl;\n const doubleLeft = left + left;\n const doubleRight = right + right;\n\n return (str, pos): DelimiterRange | null => {\n if (str.length < minLen) return null;\n\n if (pos === \"start\" || pos === \"only\") {\n if (!str.startsWith(left)) return null;\n if (str.startsWith(doubleLeft)) return null;\n }\n\n if (pos === \"end\" || pos === \"only\") {\n if (!str.endsWith(right)) return null;\n if (str.endsWith(doubleRight)) return null;\n }\n\n if (pos === \"only\") {\n const contentEnd = str.length - rl;\n if (contentEnd <= ll) return null;\n return [ll, contentEnd];\n }\n\n if (pos === \"start\") {\n const end = str.indexOf(right, ll + 1);\n if (end === -1) return null;\n return [ll, end];\n }\n\n // pos === \"end\"\n const start = str.lastIndexOf(left, str.length - rl - 1);\n if (start === -1) return null;\n if (str.startsWith(left, start - ll)) return null;\n return [start + ll, str.length - rl];\n };\n};\n","// Token.meta is typed `any` by markdown-it; casts bridge to our richer rule-test predicates.\n/* oxlint-disable typescript/no-unsafe-type-assertion */\nimport type Token from \"markdown-it/lib/token.mjs\";\nimport type { DelimiterRange } from \"../types.js\";\nimport type { DelimiterChecker } from \"./getDelimiterChecker.js\";\n\nexport interface RuleTest {\n /** Offset from the current token index. Mutually exclusive with `position`. */\n shift?: number;\n /** Absolute token index. Mutually exclusive with `shift`. */\n position?: number;\n /** Token type must equal this string. */\n type?: string | ((t: string) => boolean);\n /** Token tag must equal this string. */\n tag?: string;\n /** Token nesting must equal this value. */\n nesting?: number | ((n: number) => boolean);\n /** Inspect token content; called with (content, token, tokens, index). */\n content?: string | ((c: string) => boolean);\n /** Inspect token.meta; predicate receives the meta object (may be null). */\n meta?: (meta: Record<string, unknown> | null) => boolean;\n /** Inspect a child token at the given index (negative = from end). */\n children?: Array<Omit<RuleTest, \"shift\" | \"position\"> & { index?: number }>;\n /** If set, use this delimiter checker to extract a range from token content. */\n attrChecker?: DelimiterChecker;\n /** Which position argument to pass to attrChecker (\"start\"|\"end\"|\"only\"). */\n attrPos?: \"start\" | \"end\" | \"only\";\n}\n\nexport interface TestResult {\n match: boolean;\n position: number | null;\n range: DelimiterRange | null;\n}\n\nconst matches = (test: unknown, actual: unknown): boolean => {\n if (typeof test === \"function\")\n return (test as (v: unknown) => boolean)(actual);\n return test === actual;\n};\n\nconst testChild = (\n child: Token,\n childTest: Omit<RuleTest, \"shift\" | \"position\">\n): { match: boolean; range: DelimiterRange | null } => {\n let range: DelimiterRange | null = null;\n\n if (childTest.type !== undefined && !matches(childTest.type, child.type)) {\n return { match: false, range: null };\n }\n if (\n childTest.nesting !== undefined &&\n !matches(childTest.nesting, child.nesting)\n ) {\n return { match: false, range: null };\n }\n if (childTest.tag !== undefined && child.tag !== childTest.tag) {\n return { match: false, range: null };\n }\n if (childTest.content !== undefined) {\n if (!matches(childTest.content, child.content))\n return { match: false, range: null };\n }\n if (childTest.attrChecker) {\n range = childTest.attrChecker(child.content, childTest.attrPos ?? \"only\");\n if (!range) return { match: false, range: null };\n }\n\n return { match: true, range };\n};\n\nexport const testRule = (\n tokens: Token[],\n index: number,\n test: RuleTest\n): TestResult => {\n let tokenIndex: number;\n if (test.position !== undefined) {\n tokenIndex =\n test.position < 0 ? tokens.length + test.position : test.position;\n } else {\n tokenIndex = index + (test.shift ?? 0);\n }\n\n const token = tokens[tokenIndex];\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (!token) return { match: false, position: null, range: null };\n\n let range: DelimiterRange | null = null;\n\n if (test.type !== undefined && !matches(test.type, token.type)) {\n return { match: false, position: null, range: null };\n }\n if (test.nesting !== undefined && !matches(test.nesting, token.nesting)) {\n return { match: false, position: null, range: null };\n }\n if (test.tag !== undefined && token.tag !== test.tag) {\n return { match: false, position: null, range: null };\n }\n if (test.content !== undefined && !matches(test.content, token.content)) {\n return { match: false, position: null, range: null };\n }\n if (\n test.meta !== undefined &&\n !test.meta((token.meta as Record<string, unknown> | null) ?? null)\n ) {\n return { match: false, position: null, range: null };\n }\n if (test.attrChecker) {\n range = test.attrChecker(token.content, test.attrPos ?? \"only\");\n if (!range) return { match: false, position: null, range: null };\n }\n\n if (test.children) {\n const children = token.children ?? [];\n for (const childTest of test.children) {\n const idx =\n childTest.index !== undefined\n ? childTest.index < 0\n ? children.length + childTest.index\n : childTest.index\n : -1;\n\n if (idx >= 0) {\n const child = children[idx];\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (!child) return { match: false, position: null, range: null };\n const result = testChild(child, childTest);\n if (!result.match) return { match: false, position: null, range: null };\n if (result.range) range = result.range;\n } else {\n // No index: find any matching child\n const found = children.some((child) => {\n const result = testChild(child, childTest);\n if (result.range) range = result.range;\n return result.match;\n });\n if (!found) return { match: false, position: null, range: null };\n }\n }\n }\n\n return { match: true, position: tokenIndex, range };\n};\n","import type Token from \"markdown-it/lib/token.mjs\";\n\n/**\n * Given a closing or self-closing token at `index`, returns its matching\n * opening token by walking backwards to find the token of the same type at\n * the same nesting level. Returns the token itself for nesting === 0.\n */\nexport const getMatchingOpeningToken = (\n tokens: Token[],\n index: number\n): Token | null => {\n const token = tokens[index];\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (!token) return null;\n if (token.type === \"softbreak\") return null;\n if (token.nesting === 0) return token;\n\n const target = token.type.replace(/_close$/, \"_open\");\n let depth = 0;\n\n for (let i = index; i >= 0; i--) {\n const t = tokens[i];\n if (t.type === token.type) depth++;\n else if (t.type === target) {\n depth--;\n if (depth === 0) return t;\n }\n }\n\n return null;\n};\n","import type { DelimiterConfig } from \"../types.js\";\nimport {\n addAttrs,\n getDelimiterChecker,\n getMatchingOpeningToken\n} from \"../helper/index.js\";\nimport type { AttrRule } from \"./types.js\";\n\n// Token types that should not be treated as attr targets\nconst SKIP_TYPES = new Set([\n \"code_inline\",\n \"math_inline\",\n \"fence\",\n \"code_block\"\n]);\n\nexport const createBlockRule = (options: DelimiterConfig): AttrRule => {\n const check = getDelimiterChecker(options.left, options.right);\n\n return {\n name: \"block attributes\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n index: -1,\n type: (t: string) => !SKIP_TYPES.has(t),\n content: (content: string) => check(content.trim(), \"end\") !== null\n }\n ]\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const children = inline.children!;\n const lastChild = children[children.length - 1];\n\n const content = lastChild.content.trimEnd();\n const range = check(content, \"end\")!;\n\n // Find the block-level opening token that contains this inline\n // Walk backwards: skip the paragraph_open immediately before, then\n // look for the outermost open that wraps this inline token.\n let openToken = null;\n\n // First: find the _close token that closes the block containing this inline\n // by walking forward from the inline's position\n let closeIdx = index + 1;\n while (closeIdx < tokens.length && tokens[closeIdx].nesting !== -1) {\n closeIdx++;\n }\n\n if (closeIdx < tokens.length) {\n openToken = getMatchingOpeningToken(tokens, closeIdx);\n }\n\n if (!openToken) return;\n if (SKIP_TYPES.has(openToken.type)) return;\n\n addAttrs(openToken, content, range, options.allowed);\n\n // Strip the attr block from the last child's content\n const attrStart = content.lastIndexOf(options.left, range[0] - 1);\n lastChild.content = content.slice(0, attrStart).trimEnd();\n\n // Drop the child if now empty\n if (lastChild.content === \"\" && children.length > 1) {\n children.pop();\n }\n }\n };\n};\n","import type { DelimiterConfig } from \"../types.js\";\nimport { addAttrs, getDelimiterChecker } from \"../helper/index.js\";\nimport type { AttrRule } from \"./types.js\";\n\nexport const createInlineRules = (options: DelimiterConfig): AttrRule[] => {\n const check = getDelimiterChecker(options.left, options.right);\n\n // Handles self-closing inline elements: `code`, images (nesting === 0)\n const selfClose: AttrRule = {\n name: \"inline nesting self-close\",\n tests: [{ shift: 0, type: \"inline\" }],\n transform(tokens, index) {\n const token = tokens[index];\n const children = token.children!;\n let modified = false;\n\n for (let i = children.length - 1; i >= 0; i--) {\n const child = children[i];\n if (child.type !== \"text\") continue;\n\n const range = check(child.content, \"only\");\n if (!range) continue;\n\n // The preceding sibling must be nesting === 0 but not a softbreak\n const prev = children[i - 1];\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (prev?.nesting !== 0 || prev.type === \"softbreak\") continue;\n\n addAttrs(prev, child.content, range, options.allowed);\n children.splice(i, 1);\n modified = true;\n }\n\n return modified;\n }\n };\n\n // Handles closing inline elements: em, strong, s, etc. (nesting === -1)\n const closing: AttrRule = {\n name: \"inline attributes\",\n tests: [\n {\n shift: 0,\n type: \"inline\"\n }\n ],\n transform(tokens, index) {\n const token = tokens[index];\n const children = token.children!;\n let modified = false;\n\n for (let i = children.length - 1; i >= 0; i--) {\n const child = children[i];\n if (child.type !== \"text\") continue;\n\n const range = check(child.content, \"only\");\n if (!range) continue;\n\n // The preceding sibling must be a closing tag (nesting === -1)\n const prev = children[i - 1];\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (!prev || prev.nesting !== -1) continue;\n\n // Find the matching opening token among children\n const openType = prev.type.replace(/_close$/, \"_open\");\n let openIdx = -1;\n for (let j = i - 2; j >= 0; j--) {\n if (\n children[j].type === openType &&\n children[j].level === prev.level\n ) {\n openIdx = j;\n break;\n }\n }\n if (openIdx === -1) continue;\n\n addAttrs(children[openIdx], child.content, range, options.allowed);\n children.splice(i, 1);\n modified = true;\n }\n\n return modified;\n }\n };\n\n return [selfClose, closing];\n};\n","import type { DelimiterConfig } from \"../types.js\";\nimport { addAttrs, getDelimiterChecker } from \"../helper/index.js\";\nimport type { AttrRule } from \"./types.js\";\n\nexport const createFenceRule = (options: DelimiterConfig): AttrRule => {\n const check = getDelimiterChecker(options.left, options.right);\n\n return {\n name: \"fence attributes\",\n tests: [\n {\n shift: 0,\n type: \"fence\"\n }\n ],\n transform(tokens, index) {\n const token = tokens[index];\n const info = token.info.trim();\n const range = check(info, \"end\") ?? check(info, \"only\");\n if (!range) return;\n addAttrs(token, info, range, options.allowed);\n // Strip the attr block from the info string, preserving the language tag\n token.info = info\n .slice(0, info.lastIndexOf(options.left, range[0] - 1))\n .trimEnd();\n }\n };\n};\n","import type { DelimiterConfig } from \"../types.js\";\nimport { addAttrs, getDelimiterChecker } from \"../helper/index.js\";\nimport type { AttrRule } from \"./types.js\";\n\nexport const createHeadingRule = (options: DelimiterConfig): AttrRule => {\n const check = getDelimiterChecker(options.left, options.right);\n\n return {\n name: \"heading attributes\",\n tests: [\n {\n shift: 0,\n type: \"heading_open\"\n },\n {\n shift: 1,\n type: \"inline\",\n children: [\n {\n index: -1,\n type: (t: string) => t !== \"code_inline\" && t !== \"math_inline\",\n content: (content: string) => check(content.trim(), \"end\") !== null\n }\n ]\n }\n ],\n transform(tokens, index) {\n const openToken = tokens[index];\n const inline = tokens[index + 1];\n const children = inline.children!;\n const lastChild = children[children.length - 1];\n\n const content = lastChild.content;\n const trimmed = content.trimEnd();\n const range = check(trimmed, \"end\")!;\n\n addAttrs(openToken, trimmed, range, options.allowed);\n\n // Strip the attr block from the last child content\n const before = trimmed.slice(\n 0,\n trimmed.lastIndexOf(options.left, range[0] - 1)\n );\n lastChild.content = before.trimEnd();\n\n // Drop the child entirely if it's now empty\n if (lastChild.content === \"\" && children.length > 1) {\n children.pop();\n }\n }\n };\n};\n","import type { DelimiterConfig } from \"../types.js\";\nimport { addAttrs, getDelimiterChecker } from \"../helper/index.js\";\nimport type { AttrRule } from \"./types.js\";\n\nexport const createHrRule = (options: DelimiterConfig): AttrRule => {\n const check = getDelimiterChecker(options.left, options.right);\n\n return {\n name: \"hr attributes\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n index: 0,\n type: \"text\",\n content: (content: string) => check(content.trim(), \"only\") !== null\n }\n ]\n },\n {\n shift: -2,\n type: \"hr\"\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const textChild = inline.children![0];\n const content = textChild.content.trim();\n const range = check(content, \"only\")!;\n\n const hr = tokens[index - 2];\n addAttrs(hr, content, range, options.allowed);\n\n // Remove paragraph_open + inline + paragraph_close\n tokens.splice(index - 1, 3);\n }\n };\n};\n","import type { DelimiterConfig } from \"../types.js\";\nimport { addAttrs, getDelimiterChecker } from \"../helper/index.js\";\nimport type { AttrRule } from \"./types.js\";\n\nexport const createListRules = (options: DelimiterConfig): AttrRule[] => {\n const check = getDelimiterChecker(options.left, options.right);\n\n // Rule 1: attrs at end of a list item inline \"- item{.red}\"\n // Structure: list_item_open(-2) paragraph_open(-1) inline(0)\n const listItemEnd: AttrRule = {\n name: \"list item end\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n index: -1,\n type: (t: string) => t !== \"code_inline\",\n content: (content: string) => check(content.trim(), \"end\") !== null\n }\n ]\n },\n {\n shift: -1,\n type: \"paragraph_open\"\n },\n {\n shift: -2,\n type: \"list_item_open\"\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const children = inline.children!;\n const lastChild = children[children.length - 1];\n const content = lastChild.content.trimEnd();\n const range = check(content, \"end\")!;\n\n const listItemOpen = tokens[index - 2];\n addAttrs(listItemOpen, content, range, options.allowed);\n\n const attrStart = content.lastIndexOf(options.left, range[0] - 1);\n lastChild.content = content.slice(0, attrStart).trimEnd();\n if (lastChild.content === \"\" && children.length > 1) children.pop();\n }\n };\n\n // Rule 1b (generic): attrs at end of a custom item title inline\n // Matches when the open token two before the inline has meta.attrsRole === \"containerItem\"\n // and the token one before has meta.attrsItemTitle === true.\n // Third-party plugins opt in by setting these meta fields on their tokens.\n const customItemEnd: AttrRule = {\n name: \"custom item end\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n index: -1,\n type: (t: string) => t !== \"code_inline\",\n content: (content: string) => check(content.trim(), \"end\") !== null\n }\n ]\n },\n {\n shift: -1,\n meta: (m) => m?.attrsItemTitle === true\n },\n {\n shift: -2,\n meta: (m) => m?.attrsRole === \"containerItem\"\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const children = inline.children!;\n const lastChild = children[children.length - 1];\n const content = lastChild.content.trimEnd();\n const range = check(content, \"end\")!;\n\n const itemOpen = tokens[index - 2];\n addAttrs(itemOpen, content, range, options.allowed);\n\n const attrStart = content.lastIndexOf(options.left, range[0] - 1);\n lastChild.content = content.slice(0, attrStart).trimEnd();\n if (lastChild.content === \"\" && children.length > 1) children.pop();\n }\n };\n\n // Rule 1c (direct): attrs at end of a custom item inline where the open token\n // itself carries both attrsRole === \"containerItem\" AND attrsItemTitle === true.\n // Matches dt_open → inline (no intermediate title token).\n const customItemEndDirect: AttrRule = {\n name: \"custom item end direct\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n index: -1,\n type: (t: string) => t !== \"code_inline\",\n content: (content: string) => check(content.trim(), \"end\") !== null\n }\n ]\n },\n {\n shift: -1,\n meta: (m: Record<string, unknown> | null) =>\n m?.attrsItemTitle === true && m.attrsRole === \"containerItem\"\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const children = inline.children!;\n const lastChild = children[children.length - 1];\n const content = lastChild.content.trimEnd();\n const range = check(content, \"end\")!;\n\n const itemOpen = tokens[index - 1];\n addAttrs(itemOpen, content, range, options.allowed);\n\n const attrStart = content.lastIndexOf(options.left, range[0] - 1);\n lastChild.content = content.slice(0, attrStart).trimEnd();\n if (lastChild.content === \"\" && children.length > 1) children.pop();\n }\n };\n\n // Rule 2: attrs on own paragraph after bullet/ordered list close → apply to list\n // Structure: bullet_list_close(-2) paragraph_open(-1) inline(0) paragraph_close(+1)\n const listAttr: AttrRule = {\n name: \"list attributes\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n index: 0,\n type: \"text\",\n content: (content: string) => check(content.trim(), \"only\") !== null\n }\n ]\n },\n {\n shift: -1,\n type: \"paragraph_open\"\n },\n {\n shift: -2,\n type: (t: string) =>\n t === \"bullet_list_close\" || t === \"ordered_list_close\"\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const children = inline.children!;\n const textChild = children[0];\n const content = textChild.content.trim();\n const range = check(content, \"only\")!;\n\n // Find the matching list_open for the close token at index-2\n const closeToken = tokens[index - 2];\n const openType = closeToken.type.replace(\"_close\", \"_open\");\n\n let depth = 1;\n let listOpenIdx = -1;\n for (let i = index - 3; i >= 0; i--) {\n const t = tokens[i];\n if (t.type === closeToken.type) depth++;\n else if (t.type === openType) {\n depth--;\n if (depth === 0) {\n listOpenIdx = i;\n break;\n }\n }\n }\n\n if (listOpenIdx === -1) return;\n addAttrs(tokens[listOpenIdx], content, range, options.allowed);\n\n // Remove paragraph_open + inline + paragraph_close\n tokens.splice(index - 1, 3);\n }\n };\n\n // Rule 2b (generic): attrs on own paragraph after a custom container close → apply to container open\n // Matches when the close token two before the paragraph has meta.attrsRole === \"container\".\n // Third-party plugins opt in by setting meta.attrsRole = \"container\" on their open/close tokens.\n const customListAttr: AttrRule = {\n name: \"custom list attributes\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n index: 0,\n type: \"text\",\n content: (content: string) => check(content.trim(), \"only\") !== null\n }\n ]\n },\n {\n shift: -1,\n type: \"paragraph_open\"\n },\n {\n shift: -2,\n type: (t: string) => t.endsWith(\"_close\"),\n meta: (m) => m?.attrsRole === \"container\"\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const children = inline.children!;\n const textChild = children[0];\n const content = textChild.content.trim();\n const range = check(content, \"only\")!;\n\n // Walk back to find the matching open token (same type with _open suffix)\n const closeToken = tokens[index - 2];\n const openType = closeToken.type.replace(\"_close\", \"_open\");\n\n let depth = 1;\n let listOpenIdx = -1;\n for (let i = index - 3; i >= 0; i--) {\n const t = tokens[i];\n if (t.type === closeToken.type) depth++;\n else if (t.type === openType) {\n depth--;\n if (depth === 0) {\n listOpenIdx = i;\n break;\n }\n }\n }\n\n if (listOpenIdx === -1) return;\n addAttrs(tokens[listOpenIdx], content, range, options.allowed);\n\n // Remove paragraph_open + inline + paragraph_close\n tokens.splice(index - 1, 3);\n }\n };\n\n return [\n listItemEnd,\n customItemEnd,\n customItemEndDirect,\n listAttr,\n customListAttr\n ];\n};\n","import type { DelimiterConfig } from \"../types.js\";\nimport { addAttrs, getDelimiterChecker } from \"../helper/index.js\";\nimport type { AttrRule } from \"./types.js\";\n\nexport const createSoftbreakRule = (options: DelimiterConfig): AttrRule => {\n const check = getDelimiterChecker(options.left, options.right);\n\n return {\n name: \"softbreak attributes\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n // second-to-last child must be a softbreak\n index: -2,\n type: \"softbreak\"\n },\n {\n // last child must be a text node containing only an attr block\n index: -1,\n type: \"text\",\n content: (content: string) => check(content.trim(), \"only\") !== null\n }\n ]\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const children = inline.children!;\n const attrChild = children[children.length - 1];\n\n const content = attrChild.content.trim();\n const range = check(content, \"only\")!;\n\n // Walk backward to find the nearest nesting===1 opener that contains this inline\n let target = tokens[index];\n for (let i = index - 1; i >= 0; i--) {\n const t = tokens[i];\n if (t.nesting === 1) {\n target = t;\n break;\n }\n }\n\n addAttrs(target, content, range, options.allowed);\n\n // Remove the attr text child and the preceding softbreak\n children.splice(children.length - 2, 2);\n }\n };\n};\n","// TableMeta lives on Token.meta which markdown-it types as any — casts narrow to the rule-specific shape.\n/* oxlint-disable typescript/no-unsafe-type-assertion */\nimport type { DelimiterConfig } from \"../types.js\";\nimport { addAttrs, getDelimiterChecker } from \"../helper/index.js\";\nimport type { AttrRule } from \"./types.js\";\n\nexport const createTableRules = (options: DelimiterConfig): AttrRule[] => {\n const check = getDelimiterChecker(options.left, options.right);\n\n // Rule 1: table-level attrs — standalone paragraph after the table \"\\n{.class}\"\n const tableAttrs: AttrRule = {\n name: \"table attributes\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n index: 0,\n type: \"text\",\n content: (content: string) => check(content.trim(), \"only\") !== null\n }\n ]\n },\n {\n shift: -1,\n type: \"paragraph_open\"\n },\n {\n shift: -2,\n type: \"table_close\"\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const content = inline.children![0].content.trim();\n const range = check(content, \"only\")!;\n\n // Find the matching table_open (start from table_close at index-2)\n let tableOpenIdx = -1;\n let depth = 1;\n for (let i = index - 3; i >= 0; i--) {\n const t = tokens[i];\n if (t.type === \"table_close\") depth++;\n else if (t.type === \"table_open\") {\n depth--;\n if (depth === 0) {\n tableOpenIdx = i;\n break;\n }\n }\n }\n if (tableOpenIdx === -1) return;\n\n addAttrs(tokens[tableOpenIdx], content, range, options.allowed);\n\n // Remove paragraph_open + inline + paragraph_close\n tokens.splice(index - 1, 3);\n }\n };\n\n // Rule 2: table cell attrs — \"cell content {.class}\" inside td/th\n const tableCellAttrs: AttrRule = {\n name: \"table cell attributes\",\n tests: [\n {\n shift: 0,\n type: \"inline\",\n children: [\n {\n index: -1,\n type: \"text\",\n content: (content: string) => check(content.trim(), \"end\") !== null\n }\n ]\n },\n {\n shift: -1,\n type: (t: string) => t === \"td_open\" || t === \"th_open\"\n }\n ],\n transform(tokens, index) {\n const inline = tokens[index];\n const children = inline.children!;\n const lastChild = children[children.length - 1];\n const content = lastChild.content.trimEnd();\n const range = check(content, \"end\")!;\n\n const cellOpen = tokens[index - 1];\n addAttrs(cellOpen, content, range, options.allowed);\n\n const attrStart = content.lastIndexOf(options.left, range[0] - 1);\n lastChild.content = content.slice(0, attrStart).trimEnd();\n if (lastChild.content === \"\" && children.length > 1) children.pop();\n }\n };\n\n // Rule 3: track column count in thead (stored as metadata for rowspan/colspan calc)\n interface TableMeta {\n cols: number;\n rowspan: number[];\n }\n\n const colTracker: AttrRule = {\n name: \"table column tracker\",\n tests: [{ shift: 0, type: \"tr_open\" }],\n transform(tokens, index) {\n // Count th tokens in this row to know column count; stored on thead_open meta\n let cols = 0;\n for (let i = index + 1; i < tokens.length; i++) {\n const t = tokens[i];\n if (t.type === \"tr_close\") break;\n if (t.type === \"th_open\") cols++;\n }\n if (cols === 0) return;\n\n // Find thead_open and store column count\n for (let i = index - 1; i >= 0; i--) {\n const t = tokens[i];\n if (t.type === \"thead_open\") {\n t.meta = t.meta ?? {};\n (t.meta as TableMeta).cols = cols;\n break;\n }\n if (t.type === \"table_open\") break;\n }\n }\n };\n\n // Rule 4: colspan/rowspan calculation — remove phantom cells, adjust span values\n const spanCalc: AttrRule = {\n name: \"table span calculator\",\n tests: [{ shift: 0, type: \"tbody_open\" }],\n transform(tokens, index) {\n // Find matching thead_open to get column count\n let cols = 0;\n for (let i = index - 1; i >= 0; i--) {\n const t = tokens[i];\n if (t.type === \"thead_open\") {\n cols = (t.meta as TableMeta | undefined)?.cols ?? 0;\n break;\n }\n if (t.type === \"table_open\") break;\n }\n if (cols === 0) return;\n\n // Find the tbody_close\n let tbodyClose = index + 1;\n let depth = 1;\n while (tbodyClose < tokens.length && depth > 0) {\n const t = tokens[tbodyClose];\n if (t.type === \"tbody_open\") depth++;\n else if (t.type === \"tbody_close\") depth--;\n tbodyClose++;\n }\n tbodyClose--;\n\n // Process each row within tbody\n const occupied: number[] = Array.from({ length: cols }, () => 0);\n\n let i = index + 1;\n while (i < tbodyClose) {\n const t = tokens[i];\n if (t.type === \"tr_open\") {\n // Decrement all occupied counts\n for (let c = 0; c < cols; c++) {\n if (occupied[c] > 0) occupied[c]--;\n }\n\n // Collect td tokens in this row\n const tdIndices: number[] = [];\n for (let j = i + 1; j < tbodyClose; j++) {\n if (tokens[j].type === \"tr_close\") break;\n if (tokens[j].type === \"td_open\") tdIndices.push(j);\n }\n\n // Assign cells to columns, skipping occupied ones\n let col = 0;\n let tdIdx = 0;\n\n while (col < cols && tdIdx < tdIndices.length) {\n // Skip occupied columns (from rowspan)\n while (col < cols && occupied[col] > 0) col++;\n if (col >= cols) break;\n\n const tdOpen = tokens[tdIndices[tdIdx]];\n const rowspanAttr = tdOpen.attrGet(\"rowspan\");\n const colspanAttr = tdOpen.attrGet(\"colspan\");\n const rowspan = rowspanAttr ? parseInt(rowspanAttr, 10) : 1;\n let colspan = colspanAttr ? parseInt(colspanAttr, 10) : 1;\n\n // Count how many consecutive free columns are available\n let freeCols = 0;\n for (let c = col; c < cols && occupied[c] === 0; c++) freeCols++;\n\n // Clamp colspan to available free columns\n if (colspan > freeCols) {\n colspan = freeCols;\n if (colspan === 1) {\n // Remove colspan attr if it resolved to 1 (keep as-is if explicitly set)\n // We keep it to match reference behavior: colspan=\"1\" is left on token\n }\n tdOpen.attrSet(\"colspan\", String(colspan));\n }\n\n // Mark columns occupied by this cell's rowspan\n for (let c = col; c < col + colspan && c < cols; c++) {\n if (rowspan > 1) occupied[c] = rowspan - 1;\n }\n\n col += colspan;\n tdIdx++;\n }\n\n // Remove phantom cells beyond assigned ones\n // (cells that were merged away by rowspan from a previous row)\n while (tdIdx < tdIndices.length) {\n const phantomStart = tdIndices[tdIdx];\n // Find the matching td_close\n let phantomEnd = phantomStart + 1;\n while (\n phantomEnd < tokens.length &&\n tokens[phantomEnd].type !== \"td_close\"\n ) {\n phantomEnd++;\n }\n tokens.splice(phantomStart, phantomEnd - phantomStart + 1);\n tbodyClose -= phantomEnd - phantomStart + 1;\n // Don't increment tdIdx since we just spliced\n }\n }\n i++;\n }\n }\n };\n\n return [tableAttrs, tableCellAttrs, colTracker, spanCalc];\n};\n","import type { AttrsOptions, AttrRuleName, DelimiterConfig } from \"../types.js\";\nimport type { AttrRule } from \"./types.js\";\nimport { createBlockRule } from \"./block.js\";\nimport { createInlineRules } from \"./inline.js\";\nimport { createFenceRule } from \"./fence.js\";\nimport { createHeadingRule } from \"./heading.js\";\nimport { createHrRule } from \"./hr.js\";\nimport { createListRules } from \"./list.js\";\nimport { createSoftbreakRule } from \"./softbreak.js\";\nimport { createTableRules } from \"./table.js\";\n\nconst ALL_RULE_NAMES: AttrRuleName[] = [\n \"fence\",\n \"inline\",\n \"table\",\n \"list\",\n \"heading\",\n \"hr\",\n \"softbreak\",\n \"block\"\n];\n\nconst ALL_RULE_SET = new Set<string>(ALL_RULE_NAMES);\n\nexport const createRules = (\n options: DelimiterConfig & Pick<AttrsOptions, \"rule\">\n): AttrRule[] => {\n const { rule = \"all\" } = options;\n\n let enabled: Set<string>;\n if (rule === \"all\" || rule === true) {\n enabled = ALL_RULE_SET;\n } else if (!rule || (Array.isArray(rule) && rule.length === 0)) {\n return [];\n } else {\n enabled = new Set(rule.filter((r) => ALL_RULE_SET.has(r)));\n }\n\n const rules: AttrRule[] = [];\n\n if (enabled.has(\"fence\")) rules.push(createFenceRule(options));\n if (enabled.has(\"inline\")) rules.push(...createInlineRules(options));\n if (enabled.has(\"table\")) rules.push(...createTableRules(options));\n if (enabled.has(\"list\")) rules.push(...createListRules(options));\n if (enabled.has(\"heading\")) rules.push(createHeadingRule(options));\n if (enabled.has(\"hr\")) rules.push(createHrRule(options));\n if (enabled.has(\"softbreak\")) rules.push(createSoftbreakRule(options));\n if (enabled.has(\"block\")) rules.push(createBlockRule(options));\n\n return rules;\n};\n","import type { PluginWithOptions } from \"markdown-it\";\nimport type { AttrsOptions, DelimiterRange } from \"./types.js\";\nimport { createRules } from \"./rules/index.js\";\nimport { testRule } from \"./helper/index.js\";\n\n/** markdown-it plugin for attribute lists (`{.class #id key=value}`) on elements. */\nexport const attrs: PluginWithOptions<AttrsOptions> = (\n md,\n { left = \"{\", right = \"}\", allowed = [], rule = \"all\" } = {}\n) => {\n const rules = createRules({ left, right, allowed, rule });\n\n md.core.ruler.before(\"linkify\", \"attrs\", (state) => {\n const { tokens } = state;\n\n for (let index = 0; index < tokens.length; index++) {\n for (let ruleIndex = 0; ruleIndex < rules.length; ruleIndex++) {\n const pattern = rules[ruleIndex];\n let position: number | null = null;\n let range: DelimiterRange | null = null;\n\n const match = pattern.tests.every((test) => {\n const result = testRule(tokens, index, test);\n if (result.position != null) position = result.position;\n if (result.range) range = result.range;\n return result.match;\n });\n\n if (match) {\n const modified = pattern.transform(tokens, index, position!, range!);\n\n if (\n modified !== false &&\n (pattern.name === \"inline attributes\" ||\n pattern.name === \"inline nesting self-close\")\n ) {\n ruleIndex--;\n }\n }\n }\n }\n });\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@mirrordown/mdit-attrs",
3
- "version": "0.1.2",
3
+ "description": "A markdown-it plugin for attribute lists ({.class #id key=value}) that set classes, IDs, and attributes on elements.",
4
+ "version": "0.1.3",
4
5
  "license": "MIT",
5
6
  "author": "Drake Costa <drake@saeris.io> (https://saeris.gg)",
6
7
  "repository": {
@@ -29,12 +30,11 @@
29
30
  "node": ">=24.0.0"
30
31
  },
31
32
  "bumpy": {
32
- "buildCommand": "vp pack",
33
33
  "publishCommand": [
34
34
  "node ../../scripts/sync-jsr-version.mjs",
35
- "yarn pack -o package.tgz",
36
- "npm publish package.tgz --access public",
37
- "npx jsr publish --allow-dirty --allow-slow-types"
35
+ "node ../../scripts/npm-publish.mjs",
36
+ "node ../../scripts/jsr-resolve-deps.mjs",
37
+ "node ../../scripts/jsr-publish.mjs"
38
38
  ]
39
39
  }
40
40
  }