specra 0.2.60 → 0.2.61

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.
@@ -6,9 +6,14 @@
6
6
  language: string;
7
7
  filename?: string;
8
8
  showLineNumbers?: boolean;
9
+ diff?: boolean;
9
10
  }
10
11
 
11
- let { code, language, filename, showLineNumbers = false }: Props = $props();
12
+ let { code, language, filename, showLineNumbers = false, diff = false }: Props = $props();
13
+
14
+ // Diff add/remove markers apply either to a `diff` language or to any block
15
+ // explicitly opted in via the `diff` fence-meta flag.
16
+ let diffEnabled = $derived(diff || language === 'diff');
12
17
 
13
18
  // Languages whose syntax the JS/TS-oriented tokenizer below does NOT model.
14
19
  // Highlighting these would mis-colour prose markup (e.g. a markdown list `-`
@@ -125,7 +130,7 @@
125
130
 
126
131
  <!-- Code content -->
127
132
  <div class="bg-muted/30 dark:bg-muted/20 rounded-b-xl overflow-x-auto border border-border/50">
128
- <pre class="p-2 text-[13px] font-mono leading-relaxed text-gray-800 dark:text-gray-200"><code class="table w-full">{#each lines as line, i}{@const isDeletion = language === 'diff' && line.startsWith('-') && !line.startsWith('--')}{@const isAddition = language === 'diff' && line.startsWith('+') && !line.startsWith('++')}{@const isDiff = isDeletion || isAddition}{@const diffBgClass = isDeletion ? 'bg-red-500/5 dark:bg-red-500/10' : isAddition ? 'bg-green-500/5 dark:bg-green-500/10' : ''}{@const diffMarkerClass = isDeletion ? 'text-red-600 dark:text-red-400' : isAddition ? 'text-green-600 dark:text-green-400' : ''}{@const tokens = isPlain ? [] : tokenizeLine(line)}<div class="table-row {diffBgClass}">{#if showLineNumbers}<span class="table-cell pr-4 text-right select-none text-muted-foreground/40 w-8 align-top">{i + 1}</span>{/if}<span class="table-cell align-top">{#if isPlain}{#if line}{line}{:else}&nbsp;{/if}{:else}{#if tokens.length === 0}&nbsp;{:else}{#each tokens as token, j}{#if j === 0 && isDiff && token.value.length > 0 && (token.value[0] === '+' || token.value[0] === '-')}<span class="{diffMarkerClass} font-bold">{token.value[0]}</span>{#if token.value.length > 1}<span class="token-{token.type}">{token.value.slice(1)}</span>{/if}{:else}<span class="token-{token.type}">{token.value}</span>{/if}{/each}{/if}{/if}</span></div>{/each}</code></pre>
133
+ <pre class="p-2 text-[13px] font-mono leading-relaxed text-gray-800 dark:text-gray-200"><code class="table w-full">{#each lines as line, i}{@const isDeletion = diffEnabled && line.startsWith('-') && !line.startsWith('--')}{@const isAddition = diffEnabled && line.startsWith('+') && !line.startsWith('++')}{@const isDiff = isDeletion || isAddition}{@const diffBgClass = isDeletion ? 'bg-red-500/5 dark:bg-red-500/10' : isAddition ? 'bg-green-500/5 dark:bg-green-500/10' : ''}{@const diffMarkerClass = isDeletion ? 'text-red-600 dark:text-red-400' : isAddition ? 'text-green-600 dark:text-green-400' : ''}{@const tokens = isPlain ? [] : tokenizeLine(line)}<div class="table-row {diffBgClass}">{#if showLineNumbers}<span class="table-cell pr-4 text-right select-none text-muted-foreground/40 w-8 align-top">{i + 1}</span>{/if}<span class="table-cell align-top">{#if isPlain}{#if isDiff}<span class="{diffMarkerClass} font-bold">{line[0]}</span>{line.slice(1)}{:else}{#if line}{line}{:else}&nbsp;{/if}{/if}{:else}{#if tokens.length === 0}&nbsp;{:else}{#each tokens as token, j}{#if j === 0 && isDiff && token.value.length > 0 && (token.value[0] === '+' || token.value[0] === '-')}<span class="{diffMarkerClass} font-bold">{token.value[0]}</span>{#if token.value.length > 1}<span class="token-{token.type}">{token.value.slice(1)}</span>{/if}{:else}<span class="token-{token.type}">{token.value}</span>{/if}{/each}{/if}{/if}</span></div>{/each}</code></pre>
129
134
  </div>
130
135
  </div>
131
136
 
@@ -3,6 +3,7 @@ interface Props {
3
3
  language: string;
4
4
  filename?: string;
5
5
  showLineNumbers?: boolean;
6
+ diff?: boolean;
6
7
  }
7
8
  declare const CodeBlock: import("svelte").Component<Props, {}, "">;
8
9
  type CodeBlock = ReturnType<typeof CodeBlock>;
package/dist/mdx.js CHANGED
@@ -585,11 +585,14 @@ function extractCodeBlockProps(node) {
585
585
  const filename = readDataAttr('dataFilename', 'data-filename');
586
586
  const lineNumbers = readDataAttr('dataLineNumbers', 'data-line-numbers');
587
587
  const showLineNumbers = lineNumbers === 'true' || lineNumbers === true || lineNumbers === '';
588
+ const diffAttr = readDataAttr('dataDiff', 'data-diff');
589
+ const diff = diffAttr === 'true' || diffAttr === true || diffAttr === '';
588
590
  return {
589
591
  code,
590
592
  language,
591
593
  ...(filename ? { filename } : {}),
592
594
  ...(showLineNumbers ? { showLineNumbers: true } : {}),
595
+ ...(diff ? { diff: true } : {}),
593
596
  };
594
597
  }
595
598
  /**
@@ -7,8 +7,10 @@
7
7
  * ```ts title='src/index.ts' -> data-filename="src/index.ts"
8
8
  * ```js showLineNumbers -> data-line-numbers="true"
9
9
  * ```js showLineNumbers=true -> data-line-numbers="true"
10
+ * ```html diff -> data-diff="true"
10
11
  *
11
- * Line numbers are opt-in: only an explicit `showLineNumbers` (or
12
- * `showLineNumbers=true`) turns them on; absence (or `=false`) leaves them off.
12
+ * Line numbers and diff markers are opt-in: only an explicit flag turns them on.
13
+ * `diff` lets a syntax-highlighted block (any language) render leading `-`/`+`
14
+ * lines as removed/added without auto-detecting them across every language.
13
15
  */
14
16
  export declare function remarkCodeMeta(): (tree: any) => void;
@@ -7,28 +7,40 @@
7
7
  * ```ts title='src/index.ts' -> data-filename="src/index.ts"
8
8
  * ```js showLineNumbers -> data-line-numbers="true"
9
9
  * ```js showLineNumbers=true -> data-line-numbers="true"
10
+ * ```html diff -> data-diff="true"
10
11
  *
11
- * Line numbers are opt-in: only an explicit `showLineNumbers` (or
12
- * `showLineNumbers=true`) turns them on; absence (or `=false`) leaves them off.
12
+ * Line numbers and diff markers are opt-in: only an explicit flag turns them on.
13
+ * `diff` lets a syntax-highlighted block (any language) render leading `-`/`+`
14
+ * lines as removed/added without auto-detecting them across every language.
13
15
  */
14
16
  export function remarkCodeMeta() {
15
17
  return (tree) => {
16
18
  const visit = (node) => {
17
19
  if (node.type === 'code' && node.meta) {
20
+ const meta = node.meta;
18
21
  const hProperties = {};
19
22
  // title="..." / title='...' -> filename shown in the code block header.
20
- const titleMatch = node.meta.match(/\btitle\s*=\s*"([^"]*)"/i) ||
21
- node.meta.match(/\btitle\s*=\s*'([^']*)'/i);
23
+ const titleMatch = meta.match(/\btitle\s*=\s*"([^"]*)"/i) ||
24
+ meta.match(/\btitle\s*=\s*'([^']*)'/i);
22
25
  if (titleMatch) {
23
26
  hProperties['data-filename'] = titleMatch[1];
24
27
  }
28
+ // Strip quoted `key="..."` / `key='...'` values before scanning for bare
29
+ // flags, so a value like title="my diff notes" can't false-match below.
30
+ const flags = meta
31
+ .replace(/\b\w+\s*=\s*"[^"]*"/g, ' ')
32
+ .replace(/\b\w+\s*=\s*'[^']*'/g, ' ');
25
33
  // showLineNumbers (opt-in). Bare flag or `=true` enables; `=false` keeps off.
26
- const lineNumbersMatch = node.meta.match(/\bshowLineNumbers(?:\s*=\s*(true|false))?\b/i);
34
+ const lineNumbersMatch = flags.match(/\bshowLineNumbers(?:\s*=\s*(true|false))?\b/i);
27
35
  if (lineNumbersMatch &&
28
36
  (lineNumbersMatch[1] === undefined ||
29
37
  lineNumbersMatch[1].toLowerCase() === 'true')) {
30
38
  hProperties['data-line-numbers'] = 'true';
31
39
  }
40
+ // diff (opt-in): treat leading -/+ lines as removed/added.
41
+ if (/\bdiff\b/i.test(flags)) {
42
+ hProperties['data-diff'] = 'true';
43
+ }
32
44
  if (Object.keys(hProperties).length > 0) {
33
45
  node.data = node.data || {};
34
46
  node.data.hProperties = { ...(node.data.hProperties || {}), ...hProperties };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specra",
3
- "version": "0.2.60",
3
+ "version": "0.2.61",
4
4
  "description": "A modern documentation library for SvelteKit with built-in versioning, API reference generation, full-text search, and MDX support",
5
5
  "svelte": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",