md-annotator 0.7.0 → 0.8.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.
@@ -12,6 +12,12 @@ const HTML_VOID_TAGS = new Set([
12
12
  'link', 'meta', 'param', 'source', 'track', 'wbr'
13
13
  ])
14
14
 
15
+ // HTML tags that can contain markdown content (e.g. <div align="center">)
16
+ const HTML_MIXED_CONTENT_TAGS = new Set([
17
+ 'div', 'section', 'details', 'aside', 'article', 'figure', 'figcaption',
18
+ 'header', 'footer', 'main', 'nav', 'center'
19
+ ])
20
+
15
21
  /**
16
22
  * Simplified markdown parser that splits content into linear blocks.
17
23
  * Designed for predictable text-anchoring (not AST-based).
@@ -215,12 +221,56 @@ export function parseMarkdownToBlocks(markdown) {
215
221
  flush()
216
222
  const tagName = tagMatch[1].toLowerCase()
217
223
  const htmlStartLine = currentLineNum
218
- const htmlLines = [line]
219
224
 
220
225
  const isSelfClosing = trimmed.endsWith('/>')
221
226
  const isVoid = HTML_VOID_TAGS.has(tagName)
222
227
  const hasSameLineClose = new RegExp(`</${tagName}\\s*>`, 'i').test(trimmed)
223
228
 
229
+ if (!isSelfClosing && !isVoid && !hasSameLineClose && HTML_MIXED_CONTENT_TAGS.has(tagName)) {
230
+ // Mixed content wrapper: split into open tag + inner markdown + close tag
231
+ const closePattern = new RegExp(`</${tagName}\\s*>`, 'i')
232
+ const openPattern = new RegExp(`<${tagName}[\\s>/]`, 'i')
233
+ const innerLines = []
234
+ let closingLine = null
235
+ let depth = 1
236
+ i++
237
+ while (i < lines.length) {
238
+ if (openPattern.test(lines[i].trim())) { depth++ }
239
+ if (closePattern.test(lines[i].trim())) {
240
+ depth--
241
+ if (depth === 0) { closingLine = lines[i]; break }
242
+ }
243
+ innerLines.push(lines[i])
244
+ i++
245
+ }
246
+
247
+ // Emit opening tag
248
+ blocks.push({
249
+ id: `block-${currentId++}`,
250
+ type: 'html',
251
+ content: line,
252
+ order: currentId,
253
+ startLine: htmlStartLine
254
+ })
255
+ // Recursively parse inner content as markdown
256
+ for (const inner of parseMarkdownToBlocks(innerLines.join('\n'))) {
257
+ blocks.push({ ...inner, id: `block-${currentId++}`, order: currentId, startLine: htmlStartLine + inner.startLine })
258
+ }
259
+ // Emit closing tag
260
+ if (closingLine) {
261
+ blocks.push({
262
+ id: `block-${currentId++}`,
263
+ type: 'html',
264
+ content: closingLine,
265
+ order: currentId,
266
+ startLine: htmlStartLine + innerLines.length + 1
267
+ })
268
+ }
269
+ continue
270
+ }
271
+
272
+ // Non-mixed HTML: collect everything as one opaque block
273
+ const htmlLines = [line]
224
274
  if (!isSelfClosing && !isVoid && !hasSameLineClose) {
225
275
  const closePattern = new RegExp(`</${tagName}\\s*>`, 'i')
226
276
  const openPattern = new RegExp(`<${tagName}[\\s>/]`, 'i')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "md-annotator",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Browser-based Markdown annotator for AI-assisted review",
5
5
  "type": "module",
6
6
  "bin": {