sensemaking 0.15.2 → 0.15.4

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.
Files changed (73) hide show
  1. package/dist/cjs/cli/download.js +3 -8
  2. package/dist/cjs/cli/download.js.map +1 -1
  3. package/dist/cjs/cli/index.js +8 -19
  4. package/dist/cjs/cli/index.js.map +1 -1
  5. package/dist/cjs/cli/map.js +1 -3
  6. package/dist/cjs/cli/map.js.map +1 -1
  7. package/dist/cjs/cli/named.js +3 -8
  8. package/dist/cjs/cli/named.js.map +1 -1
  9. package/dist/cjs/cli/path.js +4 -7
  10. package/dist/cjs/cli/path.js.map +1 -1
  11. package/dist/cjs/cli/peek.js +2 -4
  12. package/dist/cjs/cli/peek.js.map +1 -1
  13. package/dist/cjs/cli/related.js +14 -20
  14. package/dist/cjs/cli/related.js.map +1 -1
  15. package/dist/cjs/cli/search.js +12 -17
  16. package/dist/cjs/cli/search.js.map +1 -1
  17. package/dist/cjs/cli/shared.js +17 -21
  18. package/dist/cjs/cli/shared.js.map +1 -1
  19. package/dist/cjs/cli/sql.js +7 -8
  20. package/dist/cjs/cli/sql.js.map +1 -1
  21. package/dist/cjs/cli/status.js +1 -3
  22. package/dist/cjs/cli/status.js.map +1 -1
  23. package/dist/cjs/cli/watch.js +3 -8
  24. package/dist/cjs/cli/watch.js.map +1 -1
  25. package/dist/cjs/cli.js +22 -34
  26. package/dist/cjs/cli.js.map +1 -1
  27. package/dist/cjs/column-hint.js +4 -2
  28. package/dist/cjs/column-hint.js.map +1 -1
  29. package/dist/cjs/commands/peek.js +5 -3
  30. package/dist/cjs/commands/peek.js.map +1 -1
  31. package/dist/cjs/commands/related.js +14 -15
  32. package/dist/cjs/commands/related.js.map +1 -1
  33. package/dist/cjs/commands/scope.js +4 -2
  34. package/dist/cjs/commands/scope.js.map +1 -1
  35. package/dist/cjs/commands/search.js +15 -16
  36. package/dist/cjs/commands/search.js.map +1 -1
  37. package/dist/cjs/config/access.js +4 -2
  38. package/dist/cjs/config/access.js.map +1 -1
  39. package/dist/cjs/config/load.js +4 -7
  40. package/dist/cjs/config/load.js.map +1 -1
  41. package/dist/cjs/config/validate.js +1 -1
  42. package/dist/cjs/db/open.js +4 -2
  43. package/dist/cjs/db/open.js.map +1 -1
  44. package/dist/cjs/db/reconcile.js +5 -3
  45. package/dist/cjs/db/reconcile.js.map +1 -1
  46. package/dist/cjs/errors.js +15 -24
  47. package/dist/cjs/errors.js.map +1 -1
  48. package/dist/cjs/features/embed.js +39 -45
  49. package/dist/cjs/features/embed.js.map +1 -1
  50. package/dist/cjs/features/links.js +4 -2
  51. package/dist/cjs/features/links.js.map +1 -1
  52. package/dist/cjs/features/rank.js +1 -1
  53. package/dist/cjs/features/tags.js +9 -127
  54. package/dist/cjs/features/tags.js.map +1 -1
  55. package/dist/cjs/fences.d.cts +1 -0
  56. package/dist/cjs/fences.d.ts +1 -0
  57. package/dist/cjs/fences.js +127 -2
  58. package/dist/cjs/fences.js.map +1 -1
  59. package/dist/cjs/graph.js +5 -3
  60. package/dist/cjs/graph.js.map +1 -1
  61. package/dist/cjs/output.js +6 -6
  62. package/dist/cjs/scan.js +5 -3
  63. package/dist/cjs/scan.js.map +1 -1
  64. package/dist/cjs/traverse.js +4 -2
  65. package/dist/cjs/traverse.js.map +1 -1
  66. package/dist/cjs/watch.js +2 -5
  67. package/dist/cjs/watch.js.map +1 -1
  68. package/dist/esm/features/tags.js +6 -126
  69. package/dist/esm/features/tags.js.map +1 -1
  70. package/dist/esm/fences.d.ts +1 -0
  71. package/dist/esm/fences.js +133 -5
  72. package/dist/esm/fences.js.map +1 -1
  73. package/package.json +1 -1
@@ -72,24 +72,152 @@ export function commentTracker() {
72
72
  }
73
73
  return out;
74
74
  },
75
+ close () {
76
+ inComment = false;
77
+ },
75
78
  get inComment () {
76
79
  return inComment;
77
80
  }
78
81
  };
79
82
  }
80
- // Body with fenced-code regions (delimiter and content lines) and <!-- --> comment spans
81
- // replaced by spaces, newlines preserved so line numbers and offsets survive. Bodies without a
82
- // backtick/tilde/`<!--` fast-path out untouched.
83
+ // CommonMark's HTML-block type-6 list (fixed by the spec, not a drifting enumeration): a line
84
+ // starting with an open or close tag of one of these, at column 0 (leading whitespace/`>`
85
+ // blockquote markers tolerated), opens a block that swallows following lines -- tags, links,
86
+ // and comments alike -- until a blank line closes it.
87
+ const HTML_BLOCK_TAGS = new Set([
88
+ 'address',
89
+ 'article',
90
+ 'aside',
91
+ 'base',
92
+ 'basefont',
93
+ 'blockquote',
94
+ 'body',
95
+ 'caption',
96
+ 'center',
97
+ 'col',
98
+ 'colgroup',
99
+ 'dd',
100
+ 'details',
101
+ 'dialog',
102
+ 'dir',
103
+ 'div',
104
+ 'dl',
105
+ 'dt',
106
+ 'fieldset',
107
+ 'figcaption',
108
+ 'figure',
109
+ 'footer',
110
+ 'form',
111
+ 'frame',
112
+ 'frameset',
113
+ 'h1',
114
+ 'h2',
115
+ 'h3',
116
+ 'h4',
117
+ 'h5',
118
+ 'h6',
119
+ 'head',
120
+ 'header',
121
+ 'hr',
122
+ 'html',
123
+ 'iframe',
124
+ 'legend',
125
+ 'li',
126
+ 'link',
127
+ 'main',
128
+ 'menu',
129
+ 'menuitem',
130
+ 'nav',
131
+ 'noframes',
132
+ 'ol',
133
+ 'optgroup',
134
+ 'option',
135
+ 'p',
136
+ 'param',
137
+ 'search',
138
+ 'section',
139
+ 'summary',
140
+ 'table',
141
+ 'tbody',
142
+ 'td',
143
+ 'tfoot',
144
+ 'th',
145
+ 'thead',
146
+ 'title',
147
+ 'tr',
148
+ 'track',
149
+ 'ul'
150
+ ]);
151
+ // Type-1 blocks (script/pre/style/textarea): closes on the line holding the matching end tag,
152
+ // not on a blank line, and that line is the last one swallowed.
153
+ const HTML_PRE_TAGS = new Set([
154
+ 'script',
155
+ 'pre',
156
+ 'style',
157
+ 'textarea'
158
+ ]);
159
+ const HTML_PRE_CLOSE_RE = /<\/(?:script|pre|style|textarea)>/i; // any of the four closers ends the block, not only the tag that opened it
160
+ // An opening or closing tag at column 0, tag name captured for the lookups above.
161
+ const HTML_BLOCK_OPEN_RE = /^<\/?([a-zA-Z][a-zA-Z0-9]*)(?:[ \t]|\/?>|$)/;
162
+ const BLANK_LINE_RE = /^[ \t>]*$/; // whitespace/blockquote-markers only -- a paragraph break, and what ends a type-6 block
163
+ // Body with fenced-code, HTML-block, and <!-- --> comment regions replaced by spaces (newlines
164
+ // preserved, so line numbers and offsets survive) plus inline code spans masked. The single
165
+ // region masker for tags/links: fence and HTML-block delimiter+content lines are opaque, an
166
+ // unclosed comment dies at its containing block's end (or the next blank line at paragraph
167
+ // level -- never silently to end of file), and a closed comment masks exactly its span.
168
+ // Bodies without a backtick/tilde/`<` fast-path out untouched.
83
169
  export function maskRegions(body) {
84
- if (!/[`~]/.test(body) && !body.includes('<!--')) return body;
170
+ if (!/[`~<]/.test(body)) return body;
85
171
  const fence = fenceTracker();
86
172
  const comment = commentTracker();
173
+ let inHtmlBlock = false;
174
+ let htmlBlockClose = null; // set while inside a type-1 (script/pre/style/textarea) block
87
175
  return body.split('\n').map((line)=>{
176
+ if (inHtmlBlock) {
177
+ if (htmlBlockClose) {
178
+ if (htmlBlockClose.test(line)) {
179
+ inHtmlBlock = false;
180
+ htmlBlockClose = null;
181
+ }
182
+ return ' '.repeat(line.length);
183
+ }
184
+ if (BLANK_LINE_RE.test(line)) {
185
+ // Block content never feeds the comment tracker, so an inner <!-- was only ever
186
+ // masked text; nothing to close here.
187
+ inHtmlBlock = false;
188
+ return line;
189
+ }
190
+ return ' '.repeat(line.length);
191
+ }
88
192
  if (!comment.inComment) {
89
193
  const isDelim = fence.feed(line);
90
194
  if (isDelim || fence.inFence) return ' '.repeat(line.length);
91
195
  }
92
- const uncommented = comment.mask(line);
196
+ const uncommented = comment.inComment || line.includes('<!--') ? comment.mask(line) : line;
197
+ if (comment.inComment && BLANK_LINE_RE.test(line)) comment.close(); // paragraph-level: dies at the next blank line
198
+ // Indented or blockquoted HTML blocks still swallow their content in Obsidian, so the
199
+ // opener test runs after stripping leading whitespace and > markers.
200
+ const stripped = uncommented.replace(/^[ \t>]*/, '');
201
+ if (stripped[0] === '<') {
202
+ const openMatch = HTML_BLOCK_OPEN_RE.exec(stripped);
203
+ if (openMatch) {
204
+ const tagName = openMatch[1].toLowerCase();
205
+ const isClosingTag = stripped[1] === '/';
206
+ if (!isClosingTag && HTML_PRE_TAGS.has(tagName)) {
207
+ // The end condition can be met on the opening line itself: <script>x</script>
208
+ // is a one-line block and the next line parses (Obsidian-verified).
209
+ if (!HTML_PRE_CLOSE_RE.test(stripped.slice(openMatch[0].length))) {
210
+ inHtmlBlock = true;
211
+ htmlBlockClose = HTML_PRE_CLOSE_RE;
212
+ }
213
+ return ' '.repeat(line.length);
214
+ }
215
+ if (HTML_BLOCK_TAGS.has(tagName)) {
216
+ inHtmlBlock = true;
217
+ return ' '.repeat(line.length);
218
+ }
219
+ }
220
+ }
93
221
  // Inline code spans hide their content too: `[[x]]` in prose is not a link.
94
222
  return uncommented.includes('`') ? maskCodeSpans(uncommented) : uncommented;
95
223
  }).join('\n');
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/fences.ts"],"sourcesContent":["// Shared line-fence tracker for tags/sections/embed. Opener: >=3 backticks or tildes at column\n// 0 -- no indent allowance, a deliberate divergence from CommonMark's up-to-3-space rule (see\n// test/unit/fences.test.ts DIVERGENCES table). A backtick opener's info string must not itself\n// contain a backtick (spec rule). A closer is a run of the SAME character, length >= the\n// opener's, holding nothing but trailing spaces after the run.\n\nexport interface FenceTracker {\n feed(line: string): boolean; // true iff this line is a fence delimiter (open or close)\n readonly inFence: boolean;\n}\n\nconst BACKTICK_OPEN = /^(`{3,})(.*)$/;\nconst TILDE_OPEN = /^(~{3,})(.*)$/;\n\nexport function fenceTracker(): FenceTracker {\n let inFence = false;\n let fenceChar = '';\n let fenceLen = 0;\n return {\n feed(line: string): boolean {\n if (!inFence) {\n const bt = BACKTICK_OPEN.exec(line);\n if (bt && !bt[2].includes('`')) {\n inFence = true;\n fenceChar = '`';\n fenceLen = bt[1].length;\n return true;\n }\n const td = TILDE_OPEN.exec(line);\n if (td) {\n inFence = true;\n fenceChar = '~';\n fenceLen = td[1].length;\n return true;\n }\n return false;\n }\n const run = fenceChar === '`' ? /^(`+)(.*)$/ : /^(~+)(.*)$/;\n const m = run.exec(line);\n if (m && m[1].length >= fenceLen && m[2].trim() === '') {\n inFence = false;\n return true;\n }\n return false;\n },\n get inFence() {\n return inFence;\n },\n };\n}\n\n// Masks <!-- ... --> spans that may cross line boundaries, one line at a time so callers can\n// interleave it with their own per-line state. An unclosed <!-- masks to end of input, matching\n// CommonMark type-2 HTML comments' practical effect (everything after is swallowed).\nexport interface CommentTracker {\n mask(line: string): string;\n readonly inComment: boolean;\n}\n\nexport function commentTracker(): CommentTracker {\n let inComment = false;\n return {\n mask(line: string): string {\n let out = '';\n let i = 0;\n while (i < line.length) {\n if (inComment) {\n const end = line.indexOf('-->', i);\n if (end === -1) {\n out += ' '.repeat(line.length - i);\n i = line.length;\n } else {\n out += ' '.repeat(end + 3 - i);\n i = end + 3;\n inComment = false;\n }\n continue;\n }\n const start = line.indexOf('<!--', i);\n if (start === -1) {\n out += line.slice(i);\n i = line.length;\n } else {\n out += `${line.slice(i, start)} `;\n i = start + 4;\n inComment = true;\n }\n }\n return out;\n },\n get inComment() {\n return inComment;\n },\n };\n}\n\n// Body with fenced-code regions (delimiter and content lines) and <!-- --> comment spans\n// replaced by spaces, newlines preserved so line numbers and offsets survive. Bodies without a\n// backtick/tilde/`<!--` fast-path out untouched.\nexport function maskRegions(body: string): string {\n if (!/[`~]/.test(body) && !body.includes('<!--')) return body;\n const fence = fenceTracker();\n const comment = commentTracker();\n return body\n .split('\\n')\n .map((line) => {\n if (!comment.inComment) {\n const isDelim = fence.feed(line);\n if (isDelim || fence.inFence) return ' '.repeat(line.length);\n }\n const uncommented = comment.mask(line);\n // Inline code spans hide their content too: `[[x]]` in prose is not a link.\n return uncommented.includes('`') ? maskCodeSpans(uncommented) : uncommented;\n })\n .join('\\n');\n}\n\n// A code span opens on a run of N backticks and closes at the next run of exactly N -- a\n// shorter or longer run in between is literal text, not a delimiter (CommonMark code spans).\n// Masked with spaces so column positions and tag-boundary whitespace are unaffected.\nexport function maskCodeSpans(line: string): string {\n let out = '';\n let i = 0;\n while (i < line.length) {\n if (line[i] !== '`') {\n out += line[i];\n i++;\n continue;\n }\n let j = i;\n while (line[j] === '`') j++;\n const n = j - i;\n let k = j;\n let closeStart = -1;\n let closeEnd = -1;\n while (k < line.length) {\n if (line[k] !== '`') {\n k++;\n continue;\n }\n let m = k;\n while (line[m] === '`') m++;\n if (m - k === n) {\n closeStart = k;\n closeEnd = m;\n break;\n }\n k = m;\n }\n if (closeStart >= 0) {\n out += ' '.repeat(closeEnd - i);\n i = closeEnd;\n } else {\n out += line.slice(i, j);\n i = j;\n }\n }\n return out;\n}\n"],"names":["BACKTICK_OPEN","TILDE_OPEN","fenceTracker","inFence","fenceChar","fenceLen","feed","line","bt","exec","includes","length","td","run","m","trim","commentTracker","inComment","mask","out","i","end","indexOf","repeat","start","slice","maskRegions","body","test","fence","comment","split","map","isDelim","uncommented","maskCodeSpans","join","j","n","k","closeStart","closeEnd"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/fences.ts"],"sourcesContent":["// Shared line-fence tracker for tags/sections/embed. Opener: >=3 backticks or tildes at column\n// 0 -- no indent allowance, a deliberate divergence from CommonMark's up-to-3-space rule (see\n// test/unit/fences.test.ts DIVERGENCES table). A backtick opener's info string must not itself\n// contain a backtick (spec rule). A closer is a run of the SAME character, length >= the\n// opener's, holding nothing but trailing spaces after the run.\n\nexport interface FenceTracker {\n feed(line: string): boolean; // true iff this line is a fence delimiter (open or close)\n readonly inFence: boolean;\n}\n\nconst BACKTICK_OPEN = /^(`{3,})(.*)$/;\nconst TILDE_OPEN = /^(~{3,})(.*)$/;\n\nexport function fenceTracker(): FenceTracker {\n let inFence = false;\n let fenceChar = '';\n let fenceLen = 0;\n return {\n feed(line: string): boolean {\n if (!inFence) {\n const bt = BACKTICK_OPEN.exec(line);\n if (bt && !bt[2].includes('`')) {\n inFence = true;\n fenceChar = '`';\n fenceLen = bt[1].length;\n return true;\n }\n const td = TILDE_OPEN.exec(line);\n if (td) {\n inFence = true;\n fenceChar = '~';\n fenceLen = td[1].length;\n return true;\n }\n return false;\n }\n const run = fenceChar === '`' ? /^(`+)(.*)$/ : /^(~+)(.*)$/;\n const m = run.exec(line);\n if (m && m[1].length >= fenceLen && m[2].trim() === '') {\n inFence = false;\n return true;\n }\n return false;\n },\n get inFence() {\n return inFence;\n },\n };\n}\n\n// Masks <!-- ... --> spans that may cross line boundaries, one line at a time so callers can\n// interleave it with their own per-line state. In isolation an unclosed <!-- stays open forever\n// (mask() has no notion of a line boundary that should kill it); maskRegions() below is what\n// calls close() at the point an unclosed comment actually dies -- a blank line at paragraph\n// level, or its enclosing HTML block's end.\nexport interface CommentTracker {\n mask(line: string): string;\n close(): void; // force-ends an unclosed comment (paragraph blank line, or its HTML block ending)\n readonly inComment: boolean;\n}\n\nexport function commentTracker(): CommentTracker {\n let inComment = false;\n return {\n mask(line: string): string {\n let out = '';\n let i = 0;\n while (i < line.length) {\n if (inComment) {\n const end = line.indexOf('-->', i);\n if (end === -1) {\n out += ' '.repeat(line.length - i);\n i = line.length;\n } else {\n out += ' '.repeat(end + 3 - i);\n i = end + 3;\n inComment = false;\n }\n continue;\n }\n const start = line.indexOf('<!--', i);\n if (start === -1) {\n out += line.slice(i);\n i = line.length;\n } else {\n out += `${line.slice(i, start)} `;\n i = start + 4;\n inComment = true;\n }\n }\n return out;\n },\n close() {\n inComment = false;\n },\n get inComment() {\n return inComment;\n },\n };\n}\n\n// CommonMark's HTML-block type-6 list (fixed by the spec, not a drifting enumeration): a line\n// starting with an open or close tag of one of these, at column 0 (leading whitespace/`>`\n// blockquote markers tolerated), opens a block that swallows following lines -- tags, links,\n// and comments alike -- until a blank line closes it.\nconst HTML_BLOCK_TAGS = new Set([\n 'address',\n 'article',\n 'aside',\n 'base',\n 'basefont',\n 'blockquote',\n 'body',\n 'caption',\n 'center',\n 'col',\n 'colgroup',\n 'dd',\n 'details',\n 'dialog',\n 'dir',\n 'div',\n 'dl',\n 'dt',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'frame',\n 'frameset',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'head',\n 'header',\n 'hr',\n 'html',\n 'iframe',\n 'legend',\n 'li',\n 'link',\n 'main',\n 'menu',\n 'menuitem',\n 'nav',\n 'noframes',\n 'ol',\n 'optgroup',\n 'option',\n 'p',\n 'param',\n 'search',\n 'section',\n 'summary',\n 'table',\n 'tbody',\n 'td',\n 'tfoot',\n 'th',\n 'thead',\n 'title',\n 'tr',\n 'track',\n 'ul',\n]);\n// Type-1 blocks (script/pre/style/textarea): closes on the line holding the matching end tag,\n// not on a blank line, and that line is the last one swallowed.\nconst HTML_PRE_TAGS = new Set(['script', 'pre', 'style', 'textarea']);\nconst HTML_PRE_CLOSE_RE = /<\\/(?:script|pre|style|textarea)>/i; // any of the four closers ends the block, not only the tag that opened it\n// An opening or closing tag at column 0, tag name captured for the lookups above.\nconst HTML_BLOCK_OPEN_RE = /^<\\/?([a-zA-Z][a-zA-Z0-9]*)(?:[ \\t]|\\/?>|$)/;\nconst BLANK_LINE_RE = /^[ \\t>]*$/; // whitespace/blockquote-markers only -- a paragraph break, and what ends a type-6 block\n\n// Body with fenced-code, HTML-block, and <!-- --> comment regions replaced by spaces (newlines\n// preserved, so line numbers and offsets survive) plus inline code spans masked. The single\n// region masker for tags/links: fence and HTML-block delimiter+content lines are opaque, an\n// unclosed comment dies at its containing block's end (or the next blank line at paragraph\n// level -- never silently to end of file), and a closed comment masks exactly its span.\n// Bodies without a backtick/tilde/`<` fast-path out untouched.\nexport function maskRegions(body: string): string {\n if (!/[`~<]/.test(body)) return body;\n const fence = fenceTracker();\n const comment = commentTracker();\n let inHtmlBlock = false;\n let htmlBlockClose: RegExp | null = null; // set while inside a type-1 (script/pre/style/textarea) block\n return body\n .split('\\n')\n .map((line) => {\n if (inHtmlBlock) {\n if (htmlBlockClose) {\n if (htmlBlockClose.test(line)) {\n inHtmlBlock = false;\n htmlBlockClose = null;\n }\n return ' '.repeat(line.length);\n }\n if (BLANK_LINE_RE.test(line)) {\n // Block content never feeds the comment tracker, so an inner <!-- was only ever\n // masked text; nothing to close here.\n inHtmlBlock = false;\n return line;\n }\n return ' '.repeat(line.length);\n }\n if (!comment.inComment) {\n const isDelim = fence.feed(line);\n if (isDelim || fence.inFence) return ' '.repeat(line.length);\n }\n const uncommented = comment.inComment || line.includes('<!--') ? comment.mask(line) : line;\n if (comment.inComment && BLANK_LINE_RE.test(line)) comment.close(); // paragraph-level: dies at the next blank line\n // Indented or blockquoted HTML blocks still swallow their content in Obsidian, so the\n // opener test runs after stripping leading whitespace and > markers.\n const stripped = uncommented.replace(/^[ \\t>]*/, '');\n if (stripped[0] === '<') {\n const openMatch = HTML_BLOCK_OPEN_RE.exec(stripped);\n if (openMatch) {\n const tagName = openMatch[1].toLowerCase();\n const isClosingTag = stripped[1] === '/';\n if (!isClosingTag && HTML_PRE_TAGS.has(tagName)) {\n // The end condition can be met on the opening line itself: <script>x</script>\n // is a one-line block and the next line parses (Obsidian-verified).\n if (!HTML_PRE_CLOSE_RE.test(stripped.slice(openMatch[0].length))) {\n inHtmlBlock = true;\n htmlBlockClose = HTML_PRE_CLOSE_RE;\n }\n return ' '.repeat(line.length);\n }\n if (HTML_BLOCK_TAGS.has(tagName)) {\n inHtmlBlock = true;\n return ' '.repeat(line.length);\n }\n }\n }\n // Inline code spans hide their content too: `[[x]]` in prose is not a link.\n return uncommented.includes('`') ? maskCodeSpans(uncommented) : uncommented;\n })\n .join('\\n');\n}\n\n// A code span opens on a run of N backticks and closes at the next run of exactly N -- a\n// shorter or longer run in between is literal text, not a delimiter (CommonMark code spans).\n// Masked with spaces so column positions and tag-boundary whitespace are unaffected.\nexport function maskCodeSpans(line: string): string {\n let out = '';\n let i = 0;\n while (i < line.length) {\n if (line[i] !== '`') {\n out += line[i];\n i++;\n continue;\n }\n let j = i;\n while (line[j] === '`') j++;\n const n = j - i;\n let k = j;\n let closeStart = -1;\n let closeEnd = -1;\n while (k < line.length) {\n if (line[k] !== '`') {\n k++;\n continue;\n }\n let m = k;\n while (line[m] === '`') m++;\n if (m - k === n) {\n closeStart = k;\n closeEnd = m;\n break;\n }\n k = m;\n }\n if (closeStart >= 0) {\n out += ' '.repeat(closeEnd - i);\n i = closeEnd;\n } else {\n out += line.slice(i, j);\n i = j;\n }\n }\n return out;\n}\n"],"names":["BACKTICK_OPEN","TILDE_OPEN","fenceTracker","inFence","fenceChar","fenceLen","feed","line","bt","exec","includes","length","td","run","m","trim","commentTracker","inComment","mask","out","i","end","indexOf","repeat","start","slice","close","HTML_BLOCK_TAGS","Set","HTML_PRE_TAGS","HTML_PRE_CLOSE_RE","HTML_BLOCK_OPEN_RE","BLANK_LINE_RE","maskRegions","body","test","fence","comment","inHtmlBlock","htmlBlockClose","split","map","isDelim","uncommented","stripped","replace","openMatch","tagName","toLowerCase","isClosingTag","has","maskCodeSpans","join","j","n","k","closeStart","closeEnd"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sensemaking",
3
- "version": "0.15.2",
3
+ "version": "0.15.4",
4
4
  "description": "Query and search your markdown notes with context-aware progressive disclosure: SQL over frontmatter, links, and text, plus semantic search and link-graph ranking. No server, no build step",
5
5
  "keywords": [
6
6
  "markdown",