@chromamark/renderer 0.2.1 → 0.3.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.
- package/README.md +19 -0
- package/dist/chromamark.esm.js +73 -7
- package/dist/chromamark.min.js +12 -12
- package/package.json +1 -1
- package/src/ansi.js +302 -0
- package/src/browser-core.js +17 -6
- package/src/containers.js +69 -2
- package/src/index.js +3 -0
- package/src/lint.js +157 -0
package/README.md
CHANGED
|
@@ -24,6 +24,25 @@ import chromamark, { render, createRenderer } from '@chromamark/renderer';
|
|
|
24
24
|
| `default` (`chromamark`) | markdown-it plugin: `new MarkdownIt().use(chromamark, options?)`. |
|
|
25
25
|
| `render(src, options?)` | Convenience: ChromaMark string → HTML fragment. |
|
|
26
26
|
| `createRenderer(options?)`| A `markdown-it` instance preconfigured with ChromaMark. |
|
|
27
|
+
| `renderAnsi(src, opts?)` | ChromaMark string → ANSI-styled text for a terminal. |
|
|
28
|
+
| `lint(src, opts?)` | Check for common mistakes → array of `{ line, column, rule, … }`. |
|
|
29
|
+
|
|
30
|
+
### Terminal rendering
|
|
31
|
+
|
|
32
|
+
`renderAnsi` walks the same parse into a TTY: tones become ANSI colors, pills
|
|
33
|
+
become bracketed icon chips (`[✓ PASS]`), blocks get a colored left bar, and
|
|
34
|
+
meters draw a unicode bar. It degrades to plain, icon-annotated text when color
|
|
35
|
+
is off.
|
|
36
|
+
|
|
37
|
+
```js
|
|
38
|
+
import { renderAnsi } from '@chromamark/renderer';
|
|
39
|
+
|
|
40
|
+
process.stdout.write(renderAnsi('::: success\nAll good [!ok healthy]\n:::'));
|
|
41
|
+
// options: { color: 'auto' | 'always' | 'never', width?: number }
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Color defaults to `'auto'` — on when stdout is a TTY and [`NO_COLOR`](https://no-color.org)
|
|
45
|
+
is unset. The `colorEnabled(option, env?, isTTY?)` helper is exported too.
|
|
27
46
|
|
|
28
47
|
### Options
|
|
29
48
|
|
package/dist/chromamark.esm.js
CHANGED
|
@@ -5929,13 +5929,52 @@ function makeRule2(enabled) {
|
|
|
5929
5929
|
if (silent) return true;
|
|
5930
5930
|
let nextLine = startLine;
|
|
5931
5931
|
let autoClosed = false;
|
|
5932
|
+
let fenceCh = 0;
|
|
5933
|
+
let fenceLen = 0;
|
|
5932
5934
|
for (; ; ) {
|
|
5933
5935
|
nextLine++;
|
|
5934
5936
|
if (nextLine >= endLine) break;
|
|
5935
5937
|
const lstart = state.bMarks[nextLine] + state.tShift[nextLine];
|
|
5936
5938
|
const lmax = state.eMarks[nextLine];
|
|
5937
|
-
|
|
5938
|
-
if (
|
|
5939
|
+
const indent = state.sCount[nextLine] - state.blkIndent;
|
|
5940
|
+
if (fenceCh) {
|
|
5941
|
+
if (indent < 4 && state.src.charCodeAt(lstart) === fenceCh) {
|
|
5942
|
+
let q = lstart;
|
|
5943
|
+
while (q < lmax && state.src.charCodeAt(q) === fenceCh) q++;
|
|
5944
|
+
if (q - lstart >= fenceLen) {
|
|
5945
|
+
let r = q;
|
|
5946
|
+
while (r < lmax && (state.src.charCodeAt(r) === 32 || state.src.charCodeAt(r) === 9)) r++;
|
|
5947
|
+
if (r >= lmax) {
|
|
5948
|
+
fenceCh = 0;
|
|
5949
|
+
fenceLen = 0;
|
|
5950
|
+
}
|
|
5951
|
+
}
|
|
5952
|
+
}
|
|
5953
|
+
continue;
|
|
5954
|
+
}
|
|
5955
|
+
const openCh = state.src.charCodeAt(lstart);
|
|
5956
|
+
if (indent < 4 && (openCh === 96 || openCh === 126)) {
|
|
5957
|
+
let q = lstart;
|
|
5958
|
+
while (q < lmax && state.src.charCodeAt(q) === openCh) q++;
|
|
5959
|
+
if (q - lstart >= 3) {
|
|
5960
|
+
let ok = true;
|
|
5961
|
+
if (openCh === 96) {
|
|
5962
|
+
for (let r = q; r < lmax; r++) {
|
|
5963
|
+
if (state.src.charCodeAt(r) === 96) {
|
|
5964
|
+
ok = false;
|
|
5965
|
+
break;
|
|
5966
|
+
}
|
|
5967
|
+
}
|
|
5968
|
+
}
|
|
5969
|
+
if (ok) {
|
|
5970
|
+
fenceCh = openCh;
|
|
5971
|
+
fenceLen = q - lstart;
|
|
5972
|
+
continue;
|
|
5973
|
+
}
|
|
5974
|
+
}
|
|
5975
|
+
}
|
|
5976
|
+
if (openCh !== MARKER) continue;
|
|
5977
|
+
if (indent >= 4) continue;
|
|
5939
5978
|
const closeLen = fenceLength(state.src, lstart, lmax);
|
|
5940
5979
|
if (closeLen < openLen) continue;
|
|
5941
5980
|
let p = lstart + closeLen;
|
|
@@ -6015,6 +6054,24 @@ function containerPlugin(md, enabled) {
|
|
|
6015
6054
|
}
|
|
6016
6055
|
return html + "</dl>";
|
|
6017
6056
|
};
|
|
6057
|
+
md.core.ruler.push("cm_sanitize_bodies", (state) => {
|
|
6058
|
+
let depth = 0;
|
|
6059
|
+
for (const token of state.tokens) {
|
|
6060
|
+
if (token.type === "cm_container_open") {
|
|
6061
|
+
depth++;
|
|
6062
|
+
} else if (token.type === "cm_container_close") {
|
|
6063
|
+
depth--;
|
|
6064
|
+
} else if (depth > 0) {
|
|
6065
|
+
if (token.type === "html_block") {
|
|
6066
|
+
token.content = esc(token.content);
|
|
6067
|
+
} else if (token.type === "inline" && token.children) {
|
|
6068
|
+
for (const child of token.children) {
|
|
6069
|
+
if (child.type === "html_inline") child.content = esc(child.content);
|
|
6070
|
+
}
|
|
6071
|
+
}
|
|
6072
|
+
}
|
|
6073
|
+
}
|
|
6074
|
+
});
|
|
6018
6075
|
}
|
|
6019
6076
|
|
|
6020
6077
|
// src/index.js
|
|
@@ -6081,16 +6138,25 @@ function injectTheme(doc) {
|
|
|
6081
6138
|
(d.head || d.documentElement).appendChild(style);
|
|
6082
6139
|
}
|
|
6083
6140
|
function dedent(text2) {
|
|
6084
|
-
const lines = text2.replace(/\
|
|
6141
|
+
const lines = text2.replace(/\r/g, "").split("\n");
|
|
6085
6142
|
while (lines.length && lines[0].trim() === "") lines.shift();
|
|
6086
6143
|
while (lines.length && lines[lines.length - 1].trim() === "") lines.pop();
|
|
6087
|
-
let
|
|
6144
|
+
let prefix = null;
|
|
6088
6145
|
for (const line of lines) {
|
|
6089
6146
|
if (!line.trim()) continue;
|
|
6090
|
-
|
|
6147
|
+
const lead = line.match(/^[ \t]*/)[0];
|
|
6148
|
+
if (prefix === null) {
|
|
6149
|
+
prefix = lead;
|
|
6150
|
+
continue;
|
|
6151
|
+
}
|
|
6152
|
+
let i = 0;
|
|
6153
|
+
const lim = Math.min(prefix.length, lead.length);
|
|
6154
|
+
while (i < lim && prefix[i] === lead[i]) i++;
|
|
6155
|
+
prefix = prefix.slice(0, i);
|
|
6156
|
+
if (prefix === "") break;
|
|
6091
6157
|
}
|
|
6092
|
-
|
|
6093
|
-
return lines.map((line) => line.slice(
|
|
6158
|
+
const cut = prefix ? prefix.length : 0;
|
|
6159
|
+
return lines.map((line) => line.slice(cut)).join("\n");
|
|
6094
6160
|
}
|
|
6095
6161
|
function resolve(target) {
|
|
6096
6162
|
return typeof target === "string" ? document.querySelector(target) : target;
|