ansimax 1.3.7 → 1.4.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/dist/index.mjs CHANGED
@@ -3192,7 +3192,7 @@ var spin = (text = "Loading", opts = {}) => {
3192
3192
  const animInterval = Math.max(FRAME_MS, safeInterval);
3193
3193
  acquireCursor();
3194
3194
  const startTime = Date.now();
3195
- const render = () => {
3195
+ const render2 = () => {
3196
3196
  if (stopped) return;
3197
3197
  const elapsed = Date.now() - startTime;
3198
3198
  frame2 = Math.floor(elapsed / animInterval) % frames2.length;
@@ -3202,8 +3202,8 @@ var spin = (text = "Loading", opts = {}) => {
3202
3202
  const buf = createOutputBuffer().push("\r").push(screen.clearLine()).push(line).toString();
3203
3203
  write(buf);
3204
3204
  };
3205
- render();
3206
- timer = setInterval(render, animInterval);
3205
+ render2();
3206
+ timer = setInterval(render2, animInterval);
3207
3207
  let abortedBySignal = false;
3208
3208
  const onAbort = () => {
3209
3209
  abortedBySignal = true;
@@ -3374,15 +3374,15 @@ var dots = (text = "Processing", opts = {}) => {
3374
3374
  let count = 0;
3375
3375
  let stopped = false;
3376
3376
  let timer = null;
3377
- const render = () => {
3377
+ const render2 = () => {
3378
3378
  if (stopped) return;
3379
3379
  const dotStr = ".".repeat(count);
3380
3380
  const colored = applyColor(dotStr, hex);
3381
3381
  write("\r" + screen.clearLine() + text + colored);
3382
3382
  count = (count + 1) % (max + 1);
3383
3383
  };
3384
- render();
3385
- timer = setInterval(render, Math.max(FRAME_MS, interval));
3384
+ render2();
3385
+ timer = setInterval(render2, Math.max(FRAME_MS, interval));
3386
3386
  const onAbort = () => stopFn();
3387
3387
  if (signal) signal.addEventListener("abort", onAbort, { once: true });
3388
3388
  const stopFn = () => {
@@ -3414,15 +3414,15 @@ var custom = (frames2, text = "", opts = {}) => {
3414
3414
  let timer = null;
3415
3415
  const safeInterval = Math.max(FRAME_MS, interval);
3416
3416
  const startTime = Date.now();
3417
- const render = () => {
3417
+ const render2 = () => {
3418
3418
  if (stopped) return;
3419
3419
  const elapsed = Date.now() - startTime;
3420
3420
  frame2 = Math.floor(elapsed / safeInterval) % frames2.length;
3421
3421
  const f = frames2[frame2] ?? "";
3422
3422
  write("\r" + screen.clearLine() + applyColor(f, hex) + " " + text);
3423
3423
  };
3424
- render();
3425
- timer = setInterval(render, safeInterval);
3424
+ render2();
3425
+ timer = setInterval(render2, safeInterval);
3426
3426
  const onAbort = () => stopFn();
3427
3427
  if (signal) signal.addEventListener("abort", onAbort, { once: true });
3428
3428
  const stopFn = () => {
@@ -3529,7 +3529,7 @@ var multi = (opts = {}) => {
3529
3529
  let frame2 = 0;
3530
3530
  let timer = null;
3531
3531
  let lastLineCount = 0;
3532
- const render = () => {
3532
+ const render2 = () => {
3533
3533
  if (lastLineCount > 0) {
3534
3534
  write("\r" + cursor.up(lastLineCount) + screen.clearDown());
3535
3535
  }
@@ -3551,8 +3551,8 @@ var multi = (opts = {}) => {
3551
3551
  const start = () => {
3552
3552
  if (timer) return;
3553
3553
  acquireCursor();
3554
- render();
3555
- timer = setInterval(render, interval);
3554
+ render2();
3555
+ timer = setInterval(render2, interval);
3556
3556
  };
3557
3557
  const tick = () => {
3558
3558
  if (!timer) start();
@@ -3576,35 +3576,35 @@ var multi = (opts = {}) => {
3576
3576
  },
3577
3577
  set text(v) {
3578
3578
  item.text = v;
3579
- render();
3579
+ render2();
3580
3580
  },
3581
3581
  update(newText) {
3582
3582
  item.text = newText;
3583
- render();
3583
+ render2();
3584
3584
  },
3585
3585
  succeed(t) {
3586
3586
  item.state = "success";
3587
3587
  if (t !== void 0) item.finalText = t;
3588
- render();
3588
+ render2();
3589
3589
  setTimeout(() => {
3590
3590
  items.delete(id);
3591
- render();
3591
+ render2();
3592
3592
  checkEmpty();
3593
3593
  }, interval);
3594
3594
  },
3595
3595
  fail(t) {
3596
3596
  item.state = "fail";
3597
3597
  if (t !== void 0) item.finalText = t;
3598
- render();
3598
+ render2();
3599
3599
  setTimeout(() => {
3600
3600
  items.delete(id);
3601
- render();
3601
+ render2();
3602
3602
  checkEmpty();
3603
3603
  }, interval);
3604
3604
  },
3605
3605
  stop() {
3606
3606
  items.delete(id);
3607
- render();
3607
+ render2();
3608
3608
  checkEmpty();
3609
3609
  }
3610
3610
  };
@@ -3914,7 +3914,7 @@ var live = (opts = {}) => {
3914
3914
  let running = false;
3915
3915
  let timer = null;
3916
3916
  let abortHandler = null;
3917
- const render = () => {
3917
+ const render2 = () => {
3918
3918
  if (lastLines > 0) clearLines(lastLines);
3919
3919
  const frame2 = isColorless2() ? stripAnsi(currentFrame) : currentFrame;
3920
3920
  try {
@@ -3929,7 +3929,7 @@ var live = (opts = {}) => {
3929
3929
  running = true;
3930
3930
  registerCrashHandlers3();
3931
3931
  hideCursorSafe2();
3932
- timer = setInterval(render, interval);
3932
+ timer = setInterval(render2, interval);
3933
3933
  if (signal && !abortHandler) {
3934
3934
  abortHandler = () => stop({ clear: false });
3935
3935
  if (signal.aborted) abortHandler();
@@ -3958,7 +3958,7 @@ var live = (opts = {}) => {
3958
3958
  };
3959
3959
  const update = (newFrame) => {
3960
3960
  currentFrame = ensureString4(newFrame);
3961
- if (running) render();
3961
+ if (running) render2();
3962
3962
  };
3963
3963
  if (autoStart) start();
3964
3964
  return { start, stop, update, isRunning: () => running };
@@ -4307,7 +4307,7 @@ var menu = (items, opts = {}) => {
4307
4307
  } catch {
4308
4308
  }
4309
4309
  };
4310
- const render = () => {
4310
+ const render2 = () => {
4311
4311
  let totalLines = 0;
4312
4312
  const { cols: termCols } = termSize();
4313
4313
  const safeTermCols = Math.max(1, termCols);
@@ -4381,7 +4381,7 @@ var menu = (items, opts = {}) => {
4381
4381
  try {
4382
4382
  emit(cursor.hide());
4383
4383
  cursorHidden = true;
4384
- lastRenderedLines = render();
4384
+ lastRenderedLines = render2();
4385
4385
  } catch {
4386
4386
  cleanup(null);
4387
4387
  return Promise.resolve(MENU_CANCELLED);
@@ -4422,7 +4422,7 @@ var menu = (items, opts = {}) => {
4422
4422
  return;
4423
4423
  }
4424
4424
  clearLinesLocal();
4425
- lastRenderedLines = render();
4425
+ lastRenderedLines = render2();
4426
4426
  } catch {
4427
4427
  cleanup(onKey);
4428
4428
  safeResolve(MENU_CANCELLED);
@@ -6134,8 +6134,8 @@ var _renderValue = (value, depth, config) => {
6134
6134
  inlineItems.push(_c(`... (${remaining} more)`, COLORS.comment, useColor));
6135
6135
  }
6136
6136
  const candidate = _c("[", COLORS.bracket, useColor) + inlineItems.join(", ") + _c("]", COLORS.bracket, useColor);
6137
- const visibleLen2 = candidate.replace(/\x1b\[[0-9;]*m/g, "").length;
6138
- if (visibleLen2 <= inlineArrayMaxLength) {
6137
+ const visibleLen3 = candidate.replace(/\x1b\[[0-9;]*m/g, "").length;
6138
+ if (visibleLen3 <= inlineArrayMaxLength) {
6139
6139
  return candidate;
6140
6140
  }
6141
6141
  }
@@ -6214,6 +6214,269 @@ var json = {
6214
6214
  pretty
6215
6215
  };
6216
6216
 
6217
+ // src/markdown/index.ts
6218
+ var THEMES = {
6219
+ dark: {
6220
+ h1: ["#ff79c6", "#bd93f9", "#8be9fd"],
6221
+ h2: "#bd93f9",
6222
+ h3: "#8be9fd",
6223
+ h4: "#50fa7b",
6224
+ h5: "#f1fa8c",
6225
+ h6: "#ffb86c",
6226
+ code: "#ff79c6",
6227
+ codeBlockBorder: "#6272a4",
6228
+ link: "#8be9fd",
6229
+ blockquote: "#6272a4",
6230
+ hr: "#6272a4",
6231
+ tableHeader: "#bd93f9"
6232
+ },
6233
+ light: {
6234
+ h1: ["#d63384", "#6f42c1", "#0d6efd"],
6235
+ h2: "#6f42c1",
6236
+ h3: "#0d6efd",
6237
+ h4: "#198754",
6238
+ h5: "#664d03",
6239
+ h6: "#fd7e14",
6240
+ code: "#d63384",
6241
+ codeBlockBorder: "#adb5bd",
6242
+ link: "#0d6efd",
6243
+ blockquote: "#6c757d",
6244
+ hr: "#adb5bd",
6245
+ tableHeader: "#6f42c1"
6246
+ }
6247
+ };
6248
+ var _normalize = (text) => typeof text === "string" ? text.replace(/\r\n/g, "\n").replace(/\r/g, "\n") : "";
6249
+ var HEADING_RE = /^(#{1,6})\s+(.+?)\s*#*\s*$/;
6250
+ var ORDERED_LIST_RE = /^(\s*)(\d+)[.)]\s+(.+)$/;
6251
+ var UNORDERED_LIST_RE = /^(\s*)[-*+]\s+(.+)$/;
6252
+ var HR_RE = /^[ \t]*(?:-{3,}|\*{3,}|_{3,})[ \t]*$/;
6253
+ var CODEBLOCK_OPEN_RE = /^```[ \t]*(\S*)[ \t]*$/;
6254
+ var CODEBLOCK_CLOSE_RE = /^```\s*$/;
6255
+ var BLOCKQUOTE_RE = /^>\s?(.*)$/;
6256
+ var TABLE_SEPARATOR_RE = /^\|?[ \t]*:?-{2,}:?[ \t]*(\|[ \t]*:?-{2,}:?[ \t]*)+\|?[ \t]*$/;
6257
+ var TABLE_ROW_RE = /^\|.*\|[ \t]*$/;
6258
+ var parseBlocks = (source) => {
6259
+ if (typeof source !== "string" || source.length === 0) return [];
6260
+ const lines = _normalize(source).split("\n");
6261
+ const out = [];
6262
+ let i = 0;
6263
+ while (i < lines.length) {
6264
+ const line = lines[i];
6265
+ if (line.trim() === "") {
6266
+ out.push({ type: "blank" });
6267
+ i++;
6268
+ continue;
6269
+ }
6270
+ if (HR_RE.test(line)) {
6271
+ out.push({ type: "hr" });
6272
+ i++;
6273
+ continue;
6274
+ }
6275
+ const headingMatch = HEADING_RE.exec(line);
6276
+ if (headingMatch) {
6277
+ const level = headingMatch[1].length;
6278
+ const text = headingMatch[2].trim();
6279
+ out.push({ type: "heading", level, text });
6280
+ i++;
6281
+ continue;
6282
+ }
6283
+ const codeOpen = CODEBLOCK_OPEN_RE.exec(line);
6284
+ if (codeOpen) {
6285
+ const lang = codeOpen[1].trim();
6286
+ const codeLines = [];
6287
+ i++;
6288
+ while (i < lines.length && !CODEBLOCK_CLOSE_RE.test(lines[i])) {
6289
+ codeLines.push(lines[i]);
6290
+ i++;
6291
+ }
6292
+ if (i < lines.length) i++;
6293
+ out.push({ type: "codeblock", lang, code: codeLines.join("\n") });
6294
+ continue;
6295
+ }
6296
+ if (BLOCKQUOTE_RE.test(line)) {
6297
+ const qLines = [];
6298
+ while (i < lines.length && BLOCKQUOTE_RE.test(lines[i])) {
6299
+ const m = BLOCKQUOTE_RE.exec(lines[i]);
6300
+ qLines.push((m?.[1] ?? "").trim());
6301
+ i++;
6302
+ }
6303
+ out.push({ type: "blockquote", text: qLines.join("\n") });
6304
+ continue;
6305
+ }
6306
+ if (TABLE_ROW_RE.test(line) && i + 1 < lines.length && TABLE_SEPARATOR_RE.test(lines[i + 1])) {
6307
+ const headers = _splitTableRow(line);
6308
+ i += 2;
6309
+ const rows = [];
6310
+ while (i < lines.length && TABLE_ROW_RE.test(lines[i])) {
6311
+ rows.push(_splitTableRow(lines[i]));
6312
+ i++;
6313
+ }
6314
+ out.push({ type: "table", headers, rows });
6315
+ continue;
6316
+ }
6317
+ const ulMatch = UNORDERED_LIST_RE.exec(line);
6318
+ const olMatch = ORDERED_LIST_RE.exec(line);
6319
+ if (ulMatch || olMatch) {
6320
+ const ordered = olMatch != null;
6321
+ const items = [];
6322
+ while (i < lines.length) {
6323
+ const ln = lines[i];
6324
+ const u = UNORDERED_LIST_RE.exec(ln);
6325
+ const o = ORDERED_LIST_RE.exec(ln);
6326
+ if (ordered && o) {
6327
+ items.push(o[3].trim());
6328
+ i++;
6329
+ } else if (!ordered && u) {
6330
+ items.push(u[2].trim());
6331
+ i++;
6332
+ } else {
6333
+ break;
6334
+ }
6335
+ }
6336
+ out.push({ type: "list", ordered, items });
6337
+ continue;
6338
+ }
6339
+ const paraLines = [line];
6340
+ i++;
6341
+ while (i < lines.length) {
6342
+ const next = lines[i];
6343
+ if (next.trim() === "" || HEADING_RE.test(next) || HR_RE.test(next) || CODEBLOCK_OPEN_RE.test(next) || BLOCKQUOTE_RE.test(next) || UNORDERED_LIST_RE.test(next) || ORDERED_LIST_RE.test(next) || TABLE_ROW_RE.test(next)) {
6344
+ break;
6345
+ }
6346
+ paraLines.push(next);
6347
+ i++;
6348
+ }
6349
+ out.push({ type: "paragraph", text: paraLines.join(" ").trim() });
6350
+ }
6351
+ return out;
6352
+ };
6353
+ var _splitTableRow = (row) => {
6354
+ const stripped = row.trim().replace(/^\|/, "").replace(/\|[ \t]*$/, "");
6355
+ return stripped.split("|").map((c) => c.trim());
6356
+ };
6357
+ var parseInline = (text, opts = {
6358
+ theme: "dark",
6359
+ inlineCodeBackground: true
6360
+ }) => {
6361
+ if (typeof text !== "string" || text.length === 0) return "";
6362
+ const t = THEMES[opts.theme];
6363
+ const codeSlots = [];
6364
+ let s = text.replace(/`([^`\n]+)`/g, (_m, code) => {
6365
+ const styled = opts.inlineCodeBackground ? color.dim(color.hex(t.code)("\xA0" + code + "\xA0")) : color.dim(color.hex(t.code)(code));
6366
+ codeSlots.push(styled);
6367
+ return `\0CODE${codeSlots.length - 1}\0`;
6368
+ });
6369
+ s = s.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g, (_m, label, url) => {
6370
+ return hyperlink(url, color.hex(t.link)(color.underline(label)));
6371
+ });
6372
+ s = s.replace(/~~([^~\n]+)~~/g, (_m, inner) => color.strikethrough(inner));
6373
+ s = s.replace(/\*\*([^*\n]+)\*\*/g, (_m, inner) => color.bold(inner));
6374
+ s = s.replace(/__([^_\n]+)__/g, (_m, inner) => color.bold(inner));
6375
+ s = s.replace(/(^|[^*])\*([^*\n]+)\*(?!\*)/g, (_m, pre, inner) => pre + color.italic(inner));
6376
+ s = s.replace(/(^|[^_])_([^_\n]+)_(?!_)/g, (_m, pre, inner) => pre + color.italic(inner));
6377
+ s = s.replace(/\x00CODE(\d+)\x00/g, (_m, idx) => codeSlots[Number(idx)] ?? "");
6378
+ return s;
6379
+ };
6380
+ var _detectWidth = () => {
6381
+ const w = process.stdout?.columns;
6382
+ return isFiniteNumber2(w) && w > 10 ? w : 80;
6383
+ };
6384
+ var render = (source, opts = {}) => {
6385
+ if (typeof source !== "string" || source.length === 0) return "";
6386
+ const {
6387
+ width = _detectWidth(),
6388
+ theme = "dark",
6389
+ headingGradient,
6390
+ boxCodeBlocks = true,
6391
+ inlineCodeBackground = true
6392
+ } = opts;
6393
+ const safeWidth = isFiniteNumber2(width) && width > 4 ? Math.floor(width) : 80;
6394
+ const t = THEMES[theme] ?? THEMES.dark;
6395
+ const h1Colors = headingGradient && headingGradient.length >= 2 ? headingGradient : t.h1;
6396
+ const blocks = parseBlocks(source);
6397
+ const inlineOpts = { theme, inlineCodeBackground };
6398
+ const out = [];
6399
+ for (const block of blocks) {
6400
+ switch (block.type) {
6401
+ case "blank":
6402
+ out.push("");
6403
+ break;
6404
+ case "hr":
6405
+ out.push(color.hex(t.hr)(ascii.divider({ width: safeWidth, char: "\u2500" })));
6406
+ break;
6407
+ case "heading": {
6408
+ const inline = parseInline(block.text, inlineOpts);
6409
+ if (block.level === 1) {
6410
+ out.push(color.bold(gradient(inline, h1Colors)));
6411
+ } else if (block.level === 2) {
6412
+ out.push(color.bold(color.underline(color.hex(t.h2)(inline))));
6413
+ } else {
6414
+ const colorKey = `h${block.level}`;
6415
+ const hex = t[colorKey];
6416
+ out.push(color.bold(color.hex(hex)(inline)));
6417
+ }
6418
+ break;
6419
+ }
6420
+ case "paragraph": {
6421
+ out.push(parseInline(block.text, inlineOpts));
6422
+ break;
6423
+ }
6424
+ case "codeblock": {
6425
+ const codeText = block.code.length > 0 ? block.code : " ";
6426
+ if (boxCodeBlocks) {
6427
+ const labeled = block.lang ? ` ${block.lang} ` : null;
6428
+ const box3 = ascii.box(codeText, {
6429
+ borderStyle: "rounded",
6430
+ padding: 1,
6431
+ title: labeled
6432
+ });
6433
+ out.push(color.hex(t.codeBlockBorder)(box3));
6434
+ } else {
6435
+ const indented = codeText.split("\n").map((l) => " " + l).join("\n");
6436
+ out.push(color.dim(indented));
6437
+ }
6438
+ break;
6439
+ }
6440
+ case "list": {
6441
+ const lines = [];
6442
+ for (let idx = 0; idx < block.items.length; idx++) {
6443
+ const marker = block.ordered ? `${idx + 1}.` : "\u2022";
6444
+ const rendered = parseInline(block.items[idx], inlineOpts);
6445
+ lines.push(` ${color.hex(t.h3)(marker)} ${rendered}`);
6446
+ }
6447
+ out.push(lines.join("\n"));
6448
+ break;
6449
+ }
6450
+ case "blockquote": {
6451
+ const rendered = parseInline(block.text, inlineOpts);
6452
+ const quoted = rendered.split("\n").map((l) => color.hex(t.blockquote)("\u2502 ") + color.dim(l)).join("\n");
6453
+ out.push(quoted);
6454
+ break;
6455
+ }
6456
+ case "table": {
6457
+ const styledHeaders = block.headers.map(
6458
+ (h) => color.bold(color.hex(t.tableHeader)(parseInline(h, inlineOpts)))
6459
+ );
6460
+ const styledRows = block.rows.map(
6461
+ (row) => row.map((cell) => parseInline(cell, inlineOpts))
6462
+ );
6463
+ out.push(components.table([styledHeaders, ...styledRows], {
6464
+ borderStyle: "rounded",
6465
+ padding: 1
6466
+ }));
6467
+ break;
6468
+ }
6469
+ }
6470
+ }
6471
+ while (out.length > 0 && out[out.length - 1] === "") out.pop();
6472
+ return out.join("\n");
6473
+ };
6474
+ var markdown = {
6475
+ render,
6476
+ parseBlocks,
6477
+ parseInline
6478
+ };
6479
+
6217
6480
  // src/configure.ts
6218
6481
  var DEFAULTS = Object.freeze({
6219
6482
  colorMode: "auto",
@@ -6521,7 +6784,23 @@ var resolveEasingByName = (e) => {
6521
6784
  };
6522
6785
 
6523
6786
  // src/index.ts
6524
- var ansimax = { color, animate, ascii, loader, frames, components, trees, themes, images, configure };
6787
+ var ansimax = {
6788
+ color,
6789
+ animate,
6790
+ ascii,
6791
+ loader,
6792
+ frames,
6793
+ components,
6794
+ trees,
6795
+ themes,
6796
+ images,
6797
+ configure,
6798
+ // v1.3.0+
6799
+ panels,
6800
+ json,
6801
+ // v1.4.0
6802
+ markdown
6803
+ };
6525
6804
  var index_default = ansimax;
6526
6805
  export {
6527
6806
  ASCII_RAMPS,
@@ -6621,6 +6900,7 @@ export {
6621
6900
  listPresets,
6622
6901
  loader,
6623
6902
  mapTree,
6903
+ markdown,
6624
6904
  measureBlock,
6625
6905
  measureTree,
6626
6906
  memoize,
@@ -6636,6 +6916,8 @@ export {
6636
6916
  padStart,
6637
6917
  panels,
6638
6918
  parseFiglet,
6919
+ parseBlocks as parseMarkdownBlocks,
6920
+ parseInline as parseMarkdownInline,
6639
6921
  pauseListeners,
6640
6922
  presetNames,
6641
6923
  presets,
@@ -6643,6 +6925,7 @@ export {
6643
6925
  rainbow,
6644
6926
  registerFont,
6645
6927
  registerPreset,
6928
+ render as renderMarkdown,
6646
6929
  renderPixelArt,
6647
6930
  renderTree,
6648
6931
  renderTreeStream,
@@ -118,7 +118,7 @@ async function main() {
118
118
  console.log(components.section('🏷️ Badges & Status', { width: 60 }));
119
119
  console.log();
120
120
  console.log(' ',
121
- components.badge('VERSION', 'v1.3.7'),
121
+ components.badge('VERSION', 'v1.4.0'),
122
122
  components.badge('BUILD', 'passing'),
123
123
  components.badge('LICENSE', 'Apache 2.0'));
124
124
  console.log();
@@ -117,7 +117,7 @@ console.log();
117
117
  console.log(components.section('🏷️ Badges & Status', { width: 60 }));
118
118
  console.log();
119
119
  console.log(' ',
120
- components.badge('VERSION', 'v1.3.7'),
120
+ components.badge('VERSION', 'v1.4.0'),
121
121
  components.badge('BUILD', 'passing'),
122
122
  components.badge('LICENSE', 'Apache 2.0'));
123
123
  console.log();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ansimax",
3
- "version": "1.3.7",
3
+ "version": "1.4.0",
4
4
  "description": "Zero-dependency CLI rendering library: colors, gradients, animations, ASCII art, pixel art, components, and themes \u2014 all in TypeScript.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",