dexin-content 0.1.0 → 0.1.2

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/collection.ts CHANGED
@@ -104,7 +104,7 @@ export function createMemorySource (files: Record<string, string>): SourceAdapte
104
104
  list: async () => Object.keys(files).sort(),
105
105
  read: async (rel) => {
106
106
  if (!(rel in files)) throw new Error(`[MemorySource] Not found: ${rel}`)
107
- return files[rel]
107
+ return files[rel]!
108
108
  }
109
109
  }
110
110
  }
@@ -143,7 +143,7 @@ export async function discover (
143
143
  const all = await source.list()
144
144
  const files: ContentFile[] = []
145
145
  for (const rel of all) {
146
- const top = rel.split('/')[0]
146
+ const top = rel.split('/')[0]!
147
147
  const col = byDir.get(top)
148
148
  if (!col) {
149
149
  throw new Error(
@@ -39,7 +39,7 @@ export function splitFrontmatter (source: string): SplitResult {
39
39
  const lines = rest.split('\n')
40
40
  let closeIdx = -1
41
41
  for (let i = 0; i < lines.length; i++) {
42
- if (lines[i].trimEnd() === '---') {
42
+ if ((lines[i] ?? '').trimEnd() === '---') {
43
43
  closeIdx = i
44
44
  break
45
45
  }
package/core/markdown.ts CHANGED
@@ -79,7 +79,7 @@ export function parseToDocAST (source: string, file: string): DocumentContent {
79
79
  .use(remarkDirective)
80
80
  .parse(source) as MdNode
81
81
 
82
- const blocks = walkBlocks(mdast.children ?? [], file, 'root')
82
+ const blocks = walkBlocks(mdast.children ?? [], file, 'root', source)
83
83
  return { version: 1, blocks }
84
84
  }
85
85
 
@@ -89,20 +89,20 @@ export { parseToDocAST as parseDocument }
89
89
 
90
90
  type BlockScope = 'root' | 'blockquote' | 'container'
91
91
 
92
- function walkBlocks (nodes: MdNode[], file: string, scope: BlockScope): DocumentBlock[] {
92
+ function walkBlocks (nodes: MdNode[], file: string, scope: BlockScope, source: string): DocumentBlock[] {
93
93
  const out: DocumentBlock[] = []
94
94
  for (const n of nodes) {
95
95
  switch (n.type) {
96
96
  case 'heading': out.push(walkHeading(n, file)); break
97
- case 'paragraph': out.push(walkParagraph(n, file)); break
98
- case 'blockquote': out.push(walkBlockquote(n, file)); break
97
+ case 'paragraph': out.push(walkParagraph(n, file, source)); break
98
+ case 'blockquote': out.push(walkBlockquote(n, file, source)); break
99
99
  case 'thematicBreak': out.push({ type: 'divider' }); break
100
100
  case 'list': out.push(walkList(n, file)); break
101
101
  case 'table': out.push(walkTable(n, file)); break
102
102
  case 'image': out.push(walkImage(n)); break
103
103
  case 'code': out.push(walkCode(n)); break
104
104
  case NODE_FORMULA_BLOCK: out.push(walkFormula(n)); break
105
- case 'containerDirective': out.push(walkContainerDirective(n, file)); break
105
+ case 'containerDirective': out.push(walkContainerDirective(n, file, source)); break
106
106
  default: {
107
107
  const err = new Error(
108
108
  `[MDAST_UNSUPPORTED_NODE] Unsupported block node type '${n.type}' in ${file} (scope: ${scope}). ` +
@@ -145,8 +145,24 @@ function walkHeading (n: MdNode, file: string): HeadingBlock {
145
145
  return h
146
146
  }
147
147
 
148
- function walkParagraph (n: MdNode, file: string): ParagraphBlock {
149
- return { type: 'paragraph', children: walkInlines(n.children ?? [], file) }
148
+ function walkParagraph (n: MdNode, file: string, source: string): DocumentBlock {
149
+ // Block Math rescue (P-0 fix): remark-math 6.0.0 fails to recognize a
150
+ // single-line `$$...$$` (delimiter on the same line as the content) as a
151
+ // block-level math node, producing paragraph > inlineMath instead of a
152
+ // top-level `math` node. When a paragraph consists of exactly one inline
153
+ // math child whose original source delimiter is `$$` (verified via the
154
+ // node's position offset into `source`), promote it to
155
+ // FormulaBlock(display=true). A single `$` inline is never promoted.
156
+ const children = n.children ?? []
157
+ if (children.length === 1 && children[0]?.type === NODE_FORMULA_INLINE) {
158
+ const child = children[0]!
159
+ const pos = child.position as { start?: { offset?: number } } | undefined
160
+ const startOffset = pos?.start?.offset
161
+ if (startOffset !== undefined && source.slice(startOffset, startOffset + 2) === '$$') {
162
+ return { type: 'formula', latex: child.value ?? '', display: true }
163
+ }
164
+ }
165
+ return { type: 'paragraph', children: walkInlines(children, file) }
150
166
  }
151
167
 
152
168
  /**
@@ -155,8 +171,8 @@ function walkParagraph (n: MdNode, file: string): ParagraphBlock {
155
171
  * ParagraphBlock with a literal newline rather than two paragraphs.
156
172
  * Paragraphs separated by blank lines inside the quote remain separate.
157
173
  */
158
- function walkBlockquote (n: MdNode, file: string): QuoteBlock {
159
- const inner = walkBlocks(n.children ?? [], file, 'blockquote')
174
+ function walkBlockquote (n: MdNode, file: string, source: string): QuoteBlock {
175
+ const inner = walkBlocks(n.children ?? [], file, 'blockquote', source)
160
176
  return { type: 'quote', children: inner }
161
177
  }
162
178
 
@@ -192,7 +208,7 @@ function walkTable (n: MdNode, file: string): TableBlock {
192
208
  const headers: TableCell[] = []
193
209
  const rows: TableCell[][] = []
194
210
  for (let i = 0; i < kids.length; i++) {
195
- const row = kids[i]
211
+ const row = kids[i]!
196
212
  const rowCells: TableCell[] = []
197
213
  const cells = row.children ?? []
198
214
  for (const cell of cells) rowCells.push(walkInlines(cell.children ?? [], file))
@@ -220,7 +236,7 @@ function walkFormula (n: MdNode): FormulaBlock {
220
236
  * Interpretation of a container's name and semantics is deferred to the
221
237
  * active domain parser; here the structure is preserved verbatim.
222
238
  */
223
- function walkContainerDirective (n: MdNode, file: string): ContainerBlock {
239
+ function walkContainerDirective (n: MdNode, file: string, source: string): ContainerBlock {
224
240
  const name = n.name ?? 'unknown'
225
241
  const attrsIn = n.attributes ?? {}
226
242
  const attrs: Record<string, string> = {}
@@ -228,7 +244,7 @@ function walkContainerDirective (n: MdNode, file: string): ContainerBlock {
228
244
  const v = attrsIn[key]
229
245
  attrs[key] = v == null ? '' : String(v)
230
246
  }
231
- const children = walkBlocks(n.children ?? [], file, 'container')
247
+ const children = walkBlocks(n.children ?? [], file, 'container', source)
232
248
  return { type: 'container', name, attrs, children }
233
249
  }
234
250
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dexin-content",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Structured content compilation & runtime layer — neutral Markdown → Content AST → PositiveArtifact + store/query/collection pipeline.",
5
5
  "keywords": [
6
6
  "markdown",
@@ -41,6 +41,7 @@
41
41
  "./core/compiler": "./core/compiler.ts",
42
42
  "./core/frontmatter": "./core/frontmatter.ts",
43
43
  "./core/discovery": "./core/discovery.ts",
44
+ "./core/markdown": "./core/markdown.ts",
44
45
  "./store": "./store.ts",
45
46
  "./collection": "./collection.ts",
46
47
  "./query": "./query.ts",