ts-markdown-builder 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 CHANGED
@@ -11,9 +11,10 @@ Elegant markdown builder with minimal bundle size.
11
11
  ## Goal
12
12
 
13
13
  TypeScript markdown generation library:
14
+
14
15
  - easy to read and write API
15
16
  - build CommonMark & GFM compliant markdown
16
- - minimal bundle size + tree-shakable
17
+ - minimal bundle size + tree-shakable
17
18
 
18
19
  ## Installation
19
20
 
@@ -26,7 +27,7 @@ npm install ts-markdown-builder
26
27
  ```js
27
28
  import * as md from 'ts-markdown-builder';
28
29
 
29
- const output = md.joinBlocks([
30
+ const output = [
30
31
  md.heading('Welcome to TS Markdown Builder'),
31
32
  "It's an easy to use modern markdown generator.",
32
33
  'It supports:',
@@ -37,7 +38,7 @@ const output = md.joinBlocks([
37
38
  'blockquotes',
38
39
  'and more!',
39
40
  ]),
40
- ]);
41
+ ].join('\n\n');
41
42
  ```
42
43
 
43
44
  ```markdown
@@ -47,7 +48,7 @@ It's an easy to use modern markdown generator.
47
48
 
48
49
  It supports:
49
50
 
50
- - **bold** and *italic*
51
+ - **bold** and _italic_
51
52
  - \`code\` spans and code blocks
52
53
  - unordered and ordered lists
53
54
  - blockquotes
@@ -7,8 +7,9 @@ exports.horizontalRule = void 0;
7
7
  exports.list = list;
8
8
  exports.orderedList = orderedList;
9
9
  var _utils = require("./utils.js");
10
- const horizontalRule = exports.horizontalRule = '\n---\n';
11
- function heading(text, level = 1) {
10
+ const horizontalRule = exports.horizontalRule = '---';
11
+ function heading(text, options) {
12
+ const level = options?.level ?? 1;
12
13
  return `${'#'.repeat(level)} ${text}`;
13
14
  }
14
15
  function blockquote(content) {
@@ -1 +1 @@
1
- {"version":3,"file":"block.js","names":["horizontalRule","exports","heading","text","level","repeat","blockquote","content","prefixLines","codeBlock","list","items","map","item","join","orderedList","index"],"sources":["../../src/block.ts"],"sourcesContent":["import { prefixLines } from './utils';\n\n/**\n * Create a horizontal rule block.\n *\n * Markdown: `---`\n */\nexport const horizontalRule = '\\n---\\n';\n\n/**\n * Create a heading block.\n * Markdown: `# Heading`\n *\n * @param text - The text of the heading.\n * @param level - The level of the heading (defaults to 1).\n */\nexport function heading(text: string, level: number = 1): string {\n return `${'#'.repeat(level)} ${text}`;\n}\n\n/**\n * Create a blockquote block.\n *\n * Markdown:\n * ```\n * > Content\n * > Content\n * ```\n *\n * @param text - The content of the blockquote.\n */\nexport function blockquote(content: string): string {\n return prefixLines(content, '> ');\n}\n\n/**\n * Create a code block.\n *\n * Markdown:\n * ````\n * ```\n * Content\n * ```\n * ````\n *\n * @param content - The content of the code block.\n */\nexport function codeBlock(content: string): string {\n return `\\`\\`\\`\\n${content}\\n\\`\\`\\``;\n}\n\n/**\n * Create an unordered list block.\n *\n * Markdown:\n * ```\n * - Item\n * - Item\n * ```\n *\n * @param items - The items of the list.\n */\nexport function list(items: string[]): string {\n return items.map((item) => `- ${item}`).join('\\n');\n}\n\n/**\n * Create an ordered list block.\n *\n * Markdown:\n * ```\n * 1. Item\n * 2. Item\n * ```\n *\n * @param items - The items of the list.\n */\nexport function orderedList(items: string[]): string {\n return items.map((item, index) => `${index + 1}. ${item}`).join('\\n');\n}\n"],"mappings":";;;;;;;;;AAOO,MAAMA,cAAc,GAAAC,OAAA,CAAAD,cAAA,GAAG,SAAS;AAShC,SAASE,OAAOA,CAACC,IAAY,EAAEC,KAAa,GAAG,CAAC,EAAU;EAC/D,OAAO,GAAG,GAAG,CAACC,MAAM,CAACD,KAAK,CAAC,IAAID,IAAI,EAAE;AACvC;AAaO,SAASG,UAAUA,CAACC,OAAe,EAAU;EAClD,OAAO,IAAAC,kBAAW,EAACD,OAAO,EAAE,IAAI,CAAC;AACnC;AAcO,SAASE,SAASA,CAACF,OAAe,EAAU;EACjD,OAAO,WAAWA,OAAO,UAAU;AACrC;AAaO,SAASG,IAAIA,CAACC,KAAe,EAAU;EAC5C,OAAOA,KAAK,CAACC,GAAG,CAAEC,IAAI,IAAK,KAAKA,IAAI,EAAE,CAAC,CAACC,IAAI,CAAC,IAAI,CAAC;AACpD;AAaO,SAASC,WAAWA,CAACJ,KAAe,EAAU;EACnD,OAAOA,KAAK,CAACC,GAAG,CAAC,CAACC,IAAI,EAAEG,KAAK,KAAK,GAAGA,KAAK,GAAG,CAAC,KAAKH,IAAI,EAAE,CAAC,CAACC,IAAI,CAAC,IAAI,CAAC;AACvE","ignoreList":[]}
1
+ {"version":3,"file":"block.js","names":["horizontalRule","exports","heading","text","options","level","repeat","blockquote","content","prefixLines","codeBlock","list","items","map","item","join","orderedList","index"],"sources":["../../src/block.ts"],"sourcesContent":["import { prefixLines } from './utils';\n\n/**\n * Create a horizontal rule block.\n *\n * Markdown: `---`\n */\nexport const horizontalRule = '---';\n\ntype HeadingOptions = {\n level: number;\n};\n\n/**\n * Create a heading block.\n * Markdown: `# Heading`\n *\n * @param text - The text of the heading.\n * @param level - The level of the heading (defaults to 1).\n */\nexport function heading(text: string, options?: HeadingOptions): string {\n const level = options?.level ?? 1;\n return `${'#'.repeat(level)} ${text}`;\n}\n\n/**\n * Create a blockquote block.\n *\n * Markdown:\n * ```\n * > Content\n * > Content\n * ```\n *\n * @param text - The content of the blockquote.\n */\nexport function blockquote(content: string): string {\n return prefixLines(content, '> ');\n}\n\n/**\n * Create a code block.\n *\n * Markdown:\n * ````\n * ```\n * Content\n * ```\n * ````\n *\n * @param content - The content of the code block.\n */\nexport function codeBlock(content: string): string {\n return `\\`\\`\\`\\n${content}\\n\\`\\`\\``;\n}\n\n/**\n * Create an unordered list block.\n *\n * Markdown:\n * ```\n * - Item\n * - Item\n * ```\n *\n * @param items - The items of the list.\n */\nexport function list(items: readonly string[]): string {\n return items.map((item) => `- ${item}`).join('\\n');\n}\n\n/**\n * Create an ordered list block.\n *\n * Markdown:\n * ```\n * 1. Item\n * 2. Item\n * ```\n *\n * @param items - The items of the list.\n */\nexport function orderedList(items: readonly string[]): string {\n return items.map((item, index) => `${index + 1}. ${item}`).join('\\n');\n}\n"],"mappings":";;;;;;;;;AAOO,MAAMA,cAAc,GAAAC,OAAA,CAAAD,cAAA,GAAG,KAAK;AAa5B,SAASE,OAAOA,CAACC,IAAY,EAAEC,OAAwB,EAAU;EACtE,MAAMC,KAAK,GAAGD,OAAO,EAAEC,KAAK,IAAI,CAAC;EACjC,OAAO,GAAG,GAAG,CAACC,MAAM,CAACD,KAAK,CAAC,IAAIF,IAAI,EAAE;AACvC;AAaO,SAASI,UAAUA,CAACC,OAAe,EAAU;EAClD,OAAO,IAAAC,kBAAW,EAACD,OAAO,EAAE,IAAI,CAAC;AACnC;AAcO,SAASE,SAASA,CAACF,OAAe,EAAU;EACjD,OAAO,WAAWA,OAAO,UAAU;AACrC;AAaO,SAASG,IAAIA,CAACC,KAAwB,EAAU;EACrD,OAAOA,KAAK,CAACC,GAAG,CAAEC,IAAI,IAAK,KAAKA,IAAI,EAAE,CAAC,CAACC,IAAI,CAAC,IAAI,CAAC;AACpD;AAaO,SAASC,WAAWA,CAACJ,KAAwB,EAAU;EAC5D,OAAOA,KAAK,CAACC,GAAG,CAAC,CAACC,IAAI,EAAEG,KAAK,KAAK,GAAGA,KAAK,GAAG,CAAC,KAAKH,IAAI,EAAE,CAAC,CAACC,IAAI,CAAC,IAAI,CAAC;AACvE","ignoreList":[]}
@@ -1,7 +1,16 @@
1
1
  "use strict";
2
2
 
3
3
  exports.disclosure = disclosure;
4
- function disclosure(title, content) {
5
- return `<details>\n<summary>${title}</summary>\n${content}\n</details>`;
4
+ exports.lineBreak = void 0;
5
+ const lineBreak = exports.lineBreak = '<br/>';
6
+ function disclosure(title, content, options) {
7
+ const headerHack = title.startsWith('#') ? '\n\n' : '';
8
+ return `<details${options?.open ? ' open' : ''}>
9
+ <summary>${headerHack}${title}${headerHack}</summary>
10
+ ${escapeMarkdownInHtml(content)}
11
+ </details>`;
12
+ }
13
+ function escapeMarkdownInHtml(markdown) {
14
+ return `\n${markdown}\n`;
6
15
  }
7
16
  //# sourceMappingURL=html.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"html.js","names":["disclosure","title","content"],"sources":["../../src/html.ts"],"sourcesContent":["/**\n * Create a disclosure block.\n *\n * Markdown/Html:\n * ```\n * <details>\n * <summary>Title</summary>\n * Content\n * </details>\n * ```\n *\n * @param title - The title of the disclosure.\n * @param content - The content of the disclosure.\n */\nexport function disclosure(title: string, content: string): string {\n return `<details>\\n<summary>${title}</summary>\\n${content}\\n</details>`;\n}\n"],"mappings":";;;AAcO,SAASA,UAAUA,CAACC,KAAa,EAAEC,OAAe,EAAU;EACjE,OAAO,uBAAuBD,KAAK,eAAeC,OAAO,cAAc;AACzE","ignoreList":[]}
1
+ {"version":3,"file":"html.js","names":["lineBreak","exports","disclosure","title","content","options","headerHack","startsWith","open","escapeMarkdownInHtml","markdown"],"sources":["../../src/html.ts"],"sourcesContent":["/**\n * Create a line break.\n *\n * Markdown (as HTML): `<br/>`\n */\nexport const lineBreak = '<br/>';\n\n/**\n * Options for the `disclosure` block.\n */\nexport type DisclosureOptions = {\n /**\n * Whether the disclosure block should be open by default (defaults to false).\n */\n open?: boolean;\n};\n\n/**\n * Create a disclosure block.\n *\n * Markdown (as HTML):\n * ```\n * <details>\n * <summary>Title</summary>\n * Content\n * </details>\n * ```\n *\n * @param title - The title of the disclosure (text only or markdown heading: `# heading`).\n * @param content - The content of the disclosure (can include markdown).\n * @param options - The options for the disclosure.\n */\nexport function disclosure(title: string, content: string, options?: DisclosureOptions): string {\n // Add extra with lines to render header properly. New line should not be added for regular text\n // as it messes up the formatting.\n const headerHack = title.startsWith('#') ? '\\n\\n' : '';\n\n return `<details${options?.open ? ' open' : ''}>\n<summary>${headerHack}${title}${headerHack}</summary>\n${escapeMarkdownInHtml(content)}\n</details>`;\n}\n\n// Blank lines are required for rendering a markdown section inside html tag.\n// See https://gist.github.com/scmx/eca72d44afee0113ceb0349dd54a84a2\nfunction escapeMarkdownInHtml(markdown: string): string {\n return `\\n${markdown}\\n`;\n}\n"],"mappings":";;;;AAKO,MAAMA,SAAS,GAAAC,OAAA,CAAAD,SAAA,GAAG,OAAO;AA2BzB,SAASE,UAAUA,CAACC,KAAa,EAAEC,OAAe,EAAEC,OAA2B,EAAU;EAG9F,MAAMC,UAAU,GAAGH,KAAK,CAACI,UAAU,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,EAAE;EAEtD,OAAO,WAAWF,OAAO,EAAEG,IAAI,GAAG,OAAO,GAAG,EAAE;AAChD,WAAWF,UAAU,GAAGH,KAAK,GAAGG,UAAU;AAC1C,EAAEG,oBAAoB,CAACL,OAAO,CAAC;AAC/B,WAAW;AACX;AAIA,SAASK,oBAAoBA,CAACC,QAAgB,EAAU;EACtD,OAAO,KAAKA,QAAQ,IAAI;AAC1B","ignoreList":[]}
@@ -54,16 +54,10 @@ Object.defineProperty(exports, "italic", {
54
54
  return _inline.italic;
55
55
  }
56
56
  });
57
- Object.defineProperty(exports, "joinBlocks", {
58
- enumerable: true,
59
- get: function () {
60
- return _joinBlocks.joinBlocks;
61
- }
62
- });
63
57
  Object.defineProperty(exports, "lineBreak", {
64
58
  enumerable: true,
65
59
  get: function () {
66
- return _inline.lineBreak;
60
+ return _html.lineBreak;
67
61
  }
68
62
  });
69
63
  Object.defineProperty(exports, "link", {
@@ -90,7 +84,6 @@ Object.defineProperty(exports, "table", {
90
84
  return _table.table;
91
85
  }
92
86
  });
93
- var _joinBlocks = require("./join-blocks.js");
94
87
  var _block = require("./block.js");
95
88
  var _inline = require("./inline.js");
96
89
  var _table = require("./table.js");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":["export { joinBlocks } from './join-blocks';\nexport { horizontalRule, heading, blockquote, orderedList, list, codeBlock } from './block';\nexport { lineBreak, code, italic, bold, link, image } from './inline';\nexport { table } from './table';\nexport { disclosure } from './html';\n\nexport type { TableOptions } from './table';\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":["export { horizontalRule, heading, blockquote, orderedList, list, codeBlock } from './block';\nexport { code, italic, bold, link, image } from './inline';\nexport { table } from './table';\nexport { lineBreak, disclosure } from './html';\n\nexport type { TableOptions } from './table';\nexport type { DisclosureOptions } from './html';\n"],"mappings":"","ignoreList":[]}
@@ -4,9 +4,7 @@ exports.bold = bold;
4
4
  exports.code = code;
5
5
  exports.image = image;
6
6
  exports.italic = italic;
7
- exports.lineBreak = void 0;
8
7
  exports.link = link;
9
- const lineBreak = exports.lineBreak = ' \n';
10
8
  function italic(text) {
11
9
  return `*${text}*`;
12
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"inline.js","names":["lineBreak","exports","italic","text","bold","code","link","url","image"],"sources":["../../src/inline.ts"],"sourcesContent":["/**\n * Create a line break.\n *\n * Markdown: `__\\n`\n */\nexport const lineBreak = ' \\n';\n\n/**\n * Create an italic text.\n *\n * Markdown: `*text*`\n *\n * @param text - The text to be italicized.\n */\nexport function italic(text: string): string {\n return `*${text}*`;\n}\n\n/**\n * Create a bold text.\n *\n * Markdown: `**text**`\n *\n * @param text - The text to be bolded.\n */\nexport function bold(text: string): string {\n return `**${text}**`;\n}\n\n/**\n * Create a code text.\n *\n * Markdown: `\\`text\\``\n *\n * @param text - The text to be marked as code.\n */\nexport function code(text: string): string {\n return `\\`${text}\\``;\n}\n\n/**\n * Create a link or autolink span.\n *\n * Markdown:\n * - `[text](url)` link when `text` is provided\n * - `<url>` autolink when `text` is not provided\n *\n * @param url - The URL to be linked.\n * @param text - The title for the link (optional).\n */\nexport function link(url: string, text?: string): string {\n return text ? `[${text}](${url})` : `<${url}>`;\n}\n\n/**\n * Create an image text.\n *\n * Markdown: `![text](url)`\n *\n * @param url - The URL of the image.\n * @param text - The description for the image (optional).\n */\nexport function image(url: string, text?: string): string {\n return `![${text ?? ''}](${url})`;\n}\n"],"mappings":";;;;;;;;AAKO,MAAMA,SAAS,GAAAC,OAAA,CAAAD,SAAA,GAAG,MAAM;AASxB,SAASE,MAAMA,CAACC,IAAY,EAAU;EAC3C,OAAO,IAAIA,IAAI,GAAG;AACpB;AASO,SAASC,IAAIA,CAACD,IAAY,EAAU;EACzC,OAAO,KAAKA,IAAI,IAAI;AACtB;AASO,SAASE,IAAIA,CAACF,IAAY,EAAU;EACzC,OAAO,KAAKA,IAAI,IAAI;AACtB;AAYO,SAASG,IAAIA,CAACC,GAAW,EAAEJ,IAAa,EAAU;EACvD,OAAOA,IAAI,GAAG,IAAIA,IAAI,KAAKI,GAAG,GAAG,GAAG,IAAIA,GAAG,GAAG;AAChD;AAUO,SAASC,KAAKA,CAACD,GAAW,EAAEJ,IAAa,EAAU;EACxD,OAAO,KAAKA,IAAI,IAAI,EAAE,KAAKI,GAAG,GAAG;AACnC","ignoreList":[]}
1
+ {"version":3,"file":"inline.js","names":["italic","text","bold","code","link","url","image"],"sources":["../../src/inline.ts"],"sourcesContent":["/**\n * Create an italic text.\n *\n * Markdown: `*text*`\n *\n * @param text - The text to be italicized.\n */\nexport function italic(text: string): string {\n return `*${text}*`;\n}\n\n/**\n * Create a bold text.\n *\n * Markdown: `**text**`\n *\n * @param text - The text to be bolded.\n */\nexport function bold(text: string): string {\n return `**${text}**`;\n}\n\n/**\n * Create a code text.\n *\n * Markdown: `code`\n *\n * @param text - The text to be marked as code.\n */\nexport function code(text: string): string {\n return `\\`${text}\\``;\n}\n\n/**\n * Create a link or autolink span.\n *\n * Markdown:\n * - `[text](url)` link when `text` is provided\n * - `<url>` autolink when `text` is not provided\n *\n * @param url - The URL to be linked.\n * @param text - The title for the link (optional).\n */\nexport function link(url: string, text?: string): string {\n return text ? `[${text}](${url})` : `<${url}>`;\n}\n\n/**\n * Create an image text.\n *\n * Markdown: `![text](url)`\n *\n * @param url - The URL of the image.\n * @param text - The description for the image (optional).\n */\nexport function image(url: string, text?: string): string {\n return `![${text ?? ''}](${url})`;\n}\n"],"mappings":";;;;;;;AAOO,SAASA,MAAMA,CAACC,IAAY,EAAU;EAC3C,OAAO,IAAIA,IAAI,GAAG;AACpB;AASO,SAASC,IAAIA,CAACD,IAAY,EAAU;EACzC,OAAO,KAAKA,IAAI,IAAI;AACtB;AASO,SAASE,IAAIA,CAACF,IAAY,EAAU;EACzC,OAAO,KAAKA,IAAI,IAAI;AACtB;AAYO,SAASG,IAAIA,CAACC,GAAW,EAAEJ,IAAa,EAAU;EACvD,OAAOA,IAAI,GAAG,IAAIA,IAAI,KAAKI,GAAG,GAAG,GAAG,IAAIA,GAAG,GAAG;AAChD;AAUO,SAASC,KAAKA,CAACD,GAAW,EAAEJ,IAAa,EAAU;EACxD,OAAO,KAAKA,IAAI,IAAI,EAAE,KAAKI,GAAG,GAAG;AACnC","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"table.js","names":["table","header","rows","options","length","map","escapeCellContent","row","widths","compact","getColumnsWidth","separators","_","i","repeat","renderRow","join","index","getColumnWidth","Math","max","paddedCells","cell","padEnd","replace"],"sources":["../../src/table.ts"],"sourcesContent":["export type TableOptions = {\n compact: boolean;\n};\n\nexport function table(header: string[], rows: string[][], options?: TableOptions): string {\n if (header.length === 0) {\n return '';\n }\n\n // Escape the header and rows content\n header = header.map(escapeCellContent);\n rows = rows.map((row) => row.map(escapeCellContent));\n\n const widths = !options?.compact ? getColumnsWidth(header, rows) : header.map(() => 1);\n const separators = header.map((_, i) => '-'.repeat(widths[i] ?? 0));\n\n return [\n renderRow(header, widths),\n renderRow(separators, widths),\n ...rows.map((row) => renderRow(row, widths)),\n ].join('\\n');\n}\n\nfunction getColumnsWidth(header: string[], rows: string[][]): number[] {\n return header.map((_, index) => getColumnWidth(header, rows, index));\n}\n\nfunction getColumnWidth(header: string[], rows: string[][], index: number): number {\n return Math.max(header[index]?.length ?? 0, ...rows.map((row) => row[index]?.length ?? 0));\n}\n\nfunction renderRow(row: string[], widths: number[]): string {\n const paddedCells = row.map((cell, index) => cell.padEnd(widths[index] ?? 0));\n return `| ${paddedCells.join(' | ')} |`;\n}\n\nfunction escapeCellContent(cell: string): string {\n return cell.replace(/\\|/g, '\\\\|').replace(/\\n/g, '<br/>');\n}\n"],"mappings":";;;AAIO,SAASA,KAAKA,CAACC,MAAgB,EAAEC,IAAgB,EAAEC,OAAsB,EAAU;EACxF,IAAIF,MAAM,CAACG,MAAM,KAAK,CAAC,EAAE;IACvB,OAAO,EAAE;EACX;EAGAH,MAAM,GAAGA,MAAM,CAACI,GAAG,CAACC,iBAAiB,CAAC;EACtCJ,IAAI,GAAGA,IAAI,CAACG,GAAG,CAAEE,GAAG,IAAKA,GAAG,CAACF,GAAG,CAACC,iBAAiB,CAAC,CAAC;EAEpD,MAAME,MAAM,GAAG,CAACL,OAAO,EAAEM,OAAO,GAAGC,eAAe,CAACT,MAAM,EAAEC,IAAI,CAAC,GAAGD,MAAM,CAACI,GAAG,CAAC,MAAM,CAAC,CAAC;EACtF,MAAMM,UAAU,GAAGV,MAAM,CAACI,GAAG,CAAC,CAACO,CAAC,EAAEC,CAAC,KAAK,GAAG,CAACC,MAAM,CAACN,MAAM,CAACK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EAEnE,OAAO,CACLE,SAAS,CAACd,MAAM,EAAEO,MAAM,CAAC,EACzBO,SAAS,CAACJ,UAAU,EAAEH,MAAM,CAAC,EAC7B,GAAGN,IAAI,CAACG,GAAG,CAAEE,GAAG,IAAKQ,SAAS,CAACR,GAAG,EAAEC,MAAM,CAAC,CAAC,CAC7C,CAACQ,IAAI,CAAC,IAAI,CAAC;AACd;AAEA,SAASN,eAAeA,CAACT,MAAgB,EAAEC,IAAgB,EAAY;EACrE,OAAOD,MAAM,CAACI,GAAG,CAAC,CAACO,CAAC,EAAEK,KAAK,KAAKC,cAAc,CAACjB,MAAM,EAAEC,IAAI,EAAEe,KAAK,CAAC,CAAC;AACtE;AAEA,SAASC,cAAcA,CAACjB,MAAgB,EAAEC,IAAgB,EAAEe,KAAa,EAAU;EACjF,OAAOE,IAAI,CAACC,GAAG,CAACnB,MAAM,CAACgB,KAAK,CAAC,EAAEb,MAAM,IAAI,CAAC,EAAE,GAAGF,IAAI,CAACG,GAAG,CAAEE,GAAG,IAAKA,GAAG,CAACU,KAAK,CAAC,EAAEb,MAAM,IAAI,CAAC,CAAC,CAAC;AAC5F;AAEA,SAASW,SAASA,CAACR,GAAa,EAAEC,MAAgB,EAAU;EAC1D,MAAMa,WAAW,GAAGd,GAAG,CAACF,GAAG,CAAC,CAACiB,IAAI,EAAEL,KAAK,KAAKK,IAAI,CAACC,MAAM,CAACf,MAAM,CAACS,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;EAC7E,OAAO,KAAKI,WAAW,CAACL,IAAI,CAAC,KAAK,CAAC,IAAI;AACzC;AAEA,SAASV,iBAAiBA,CAACgB,IAAY,EAAU;EAC/C,OAAOA,IAAI,CAACE,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAACA,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;AAC3D","ignoreList":[]}
1
+ {"version":3,"file":"table.js","names":["table","header","rows","options","length","map","escapeCellContent","row","widths","compact","getColumnsWidth","separators","_","i","repeat","renderRow","join","index","getColumnWidth","Math","max","paddedCells","cell","padEnd","replace"],"sources":["../../src/table.ts"],"sourcesContent":["export type TableOptions = {\n compact: boolean;\n};\n\nexport function table(\n header: readonly string[],\n rows: readonly string[][],\n options?: TableOptions,\n): string {\n if (header.length === 0) {\n return '';\n }\n\n // Escape the header and rows content\n header = header.map(escapeCellContent);\n rows = rows.map((row) => row.map(escapeCellContent));\n\n const widths = !options?.compact ? getColumnsWidth(header, rows) : header.map(() => 1);\n const separators = header.map((_, i) => '-'.repeat(widths[i] ?? 0));\n\n return [\n renderRow(header, widths),\n renderRow(separators, widths),\n ...rows.map((row) => renderRow(row, widths)),\n ].join('\\n');\n}\n\nfunction getColumnsWidth(header: readonly string[], rows: readonly string[][]): number[] {\n return header.map((_, index) => getColumnWidth(header, rows, index));\n}\n\nfunction getColumnWidth(\n header: readonly string[],\n rows: readonly string[][],\n index: number,\n): number {\n return Math.max(header[index]?.length ?? 0, ...rows.map((row) => row[index]?.length ?? 0));\n}\n\nfunction renderRow(row: readonly string[], widths: readonly number[]): string {\n const paddedCells = row.map((cell, index) => cell.padEnd(widths[index] ?? 0));\n return `| ${paddedCells.join(' | ')} |`;\n}\n\nfunction escapeCellContent(cell: string): string {\n return cell.replace(/\\|/g, '\\\\|').replace(/\\n/g, '<br/>');\n}\n"],"mappings":";;;AAIO,SAASA,KAAKA,CACnBC,MAAyB,EACzBC,IAAyB,EACzBC,OAAsB,EACd;EACR,IAAIF,MAAM,CAACG,MAAM,KAAK,CAAC,EAAE;IACvB,OAAO,EAAE;EACX;EAGAH,MAAM,GAAGA,MAAM,CAACI,GAAG,CAACC,iBAAiB,CAAC;EACtCJ,IAAI,GAAGA,IAAI,CAACG,GAAG,CAAEE,GAAG,IAAKA,GAAG,CAACF,GAAG,CAACC,iBAAiB,CAAC,CAAC;EAEpD,MAAME,MAAM,GAAG,CAACL,OAAO,EAAEM,OAAO,GAAGC,eAAe,CAACT,MAAM,EAAEC,IAAI,CAAC,GAAGD,MAAM,CAACI,GAAG,CAAC,MAAM,CAAC,CAAC;EACtF,MAAMM,UAAU,GAAGV,MAAM,CAACI,GAAG,CAAC,CAACO,CAAC,EAAEC,CAAC,KAAK,GAAG,CAACC,MAAM,CAACN,MAAM,CAACK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EAEnE,OAAO,CACLE,SAAS,CAACd,MAAM,EAAEO,MAAM,CAAC,EACzBO,SAAS,CAACJ,UAAU,EAAEH,MAAM,CAAC,EAC7B,GAAGN,IAAI,CAACG,GAAG,CAAEE,GAAG,IAAKQ,SAAS,CAACR,GAAG,EAAEC,MAAM,CAAC,CAAC,CAC7C,CAACQ,IAAI,CAAC,IAAI,CAAC;AACd;AAEA,SAASN,eAAeA,CAACT,MAAyB,EAAEC,IAAyB,EAAY;EACvF,OAAOD,MAAM,CAACI,GAAG,CAAC,CAACO,CAAC,EAAEK,KAAK,KAAKC,cAAc,CAACjB,MAAM,EAAEC,IAAI,EAAEe,KAAK,CAAC,CAAC;AACtE;AAEA,SAASC,cAAcA,CACrBjB,MAAyB,EACzBC,IAAyB,EACzBe,KAAa,EACL;EACR,OAAOE,IAAI,CAACC,GAAG,CAACnB,MAAM,CAACgB,KAAK,CAAC,EAAEb,MAAM,IAAI,CAAC,EAAE,GAAGF,IAAI,CAACG,GAAG,CAAEE,GAAG,IAAKA,GAAG,CAACU,KAAK,CAAC,EAAEb,MAAM,IAAI,CAAC,CAAC,CAAC;AAC5F;AAEA,SAASW,SAASA,CAACR,GAAsB,EAAEC,MAAyB,EAAU;EAC5E,MAAMa,WAAW,GAAGd,GAAG,CAACF,GAAG,CAAC,CAACiB,IAAI,EAAEL,KAAK,KAAKK,IAAI,CAACC,MAAM,CAACf,MAAM,CAACS,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;EAC7E,OAAO,KAAKI,WAAW,CAACL,IAAI,CAAC,KAAK,CAAC,IAAI;AACzC;AAEA,SAASV,iBAAiBA,CAACgB,IAAY,EAAU;EAC/C,OAAOA,IAAI,CAACE,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAACA,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;AAC3D","ignoreList":[]}
@@ -1,6 +1,7 @@
1
1
  import { prefixLines } from "./utils.mjs";
2
- export const horizontalRule = '\n---\n';
3
- export function heading(text, level = 1) {
2
+ export const horizontalRule = '---';
3
+ export function heading(text, options) {
4
+ const level = options?.level ?? 1;
4
5
  return `${'#'.repeat(level)} ${text}`;
5
6
  }
6
7
  export function blockquote(content) {
@@ -1 +1 @@
1
- {"version":3,"file":"block.mjs","names":["prefixLines","horizontalRule","heading","text","level","repeat","blockquote","content","codeBlock","list","items","map","item","join","orderedList","index"],"sources":["../../src/block.ts"],"sourcesContent":["import { prefixLines } from './utils';\n\n/**\n * Create a horizontal rule block.\n *\n * Markdown: `---`\n */\nexport const horizontalRule = '\\n---\\n';\n\n/**\n * Create a heading block.\n * Markdown: `# Heading`\n *\n * @param text - The text of the heading.\n * @param level - The level of the heading (defaults to 1).\n */\nexport function heading(text: string, level: number = 1): string {\n return `${'#'.repeat(level)} ${text}`;\n}\n\n/**\n * Create a blockquote block.\n *\n * Markdown:\n * ```\n * > Content\n * > Content\n * ```\n *\n * @param text - The content of the blockquote.\n */\nexport function blockquote(content: string): string {\n return prefixLines(content, '> ');\n}\n\n/**\n * Create a code block.\n *\n * Markdown:\n * ````\n * ```\n * Content\n * ```\n * ````\n *\n * @param content - The content of the code block.\n */\nexport function codeBlock(content: string): string {\n return `\\`\\`\\`\\n${content}\\n\\`\\`\\``;\n}\n\n/**\n * Create an unordered list block.\n *\n * Markdown:\n * ```\n * - Item\n * - Item\n * ```\n *\n * @param items - The items of the list.\n */\nexport function list(items: string[]): string {\n return items.map((item) => `- ${item}`).join('\\n');\n}\n\n/**\n * Create an ordered list block.\n *\n * Markdown:\n * ```\n * 1. Item\n * 2. Item\n * ```\n *\n * @param items - The items of the list.\n */\nexport function orderedList(items: string[]): string {\n return items.map((item, index) => `${index + 1}. ${item}`).join('\\n');\n}\n"],"mappings":"SAASA,WAAW;AAOpB,OAAO,MAAMC,cAAc,GAAG,SAAS;AASvC,OAAO,SAASC,OAAOA,CAACC,IAAY,EAAEC,KAAa,GAAG,CAAC,EAAU;EAC/D,OAAO,GAAG,GAAG,CAACC,MAAM,CAACD,KAAK,CAAC,IAAID,IAAI,EAAE;AACvC;AAaA,OAAO,SAASG,UAAUA,CAACC,OAAe,EAAU;EAClD,OAAOP,WAAW,CAACO,OAAO,EAAE,IAAI,CAAC;AACnC;AAcA,OAAO,SAASC,SAASA,CAACD,OAAe,EAAU;EACjD,OAAO,WAAWA,OAAO,UAAU;AACrC;AAaA,OAAO,SAASE,IAAIA,CAACC,KAAe,EAAU;EAC5C,OAAOA,KAAK,CAACC,GAAG,CAAEC,IAAI,IAAK,KAAKA,IAAI,EAAE,CAAC,CAACC,IAAI,CAAC,IAAI,CAAC;AACpD;AAaA,OAAO,SAASC,WAAWA,CAACJ,KAAe,EAAU;EACnD,OAAOA,KAAK,CAACC,GAAG,CAAC,CAACC,IAAI,EAAEG,KAAK,KAAK,GAAGA,KAAK,GAAG,CAAC,KAAKH,IAAI,EAAE,CAAC,CAACC,IAAI,CAAC,IAAI,CAAC;AACvE","ignoreList":[]}
1
+ {"version":3,"file":"block.mjs","names":["prefixLines","horizontalRule","heading","text","options","level","repeat","blockquote","content","codeBlock","list","items","map","item","join","orderedList","index"],"sources":["../../src/block.ts"],"sourcesContent":["import { prefixLines } from './utils';\n\n/**\n * Create a horizontal rule block.\n *\n * Markdown: `---`\n */\nexport const horizontalRule = '---';\n\ntype HeadingOptions = {\n level: number;\n};\n\n/**\n * Create a heading block.\n * Markdown: `# Heading`\n *\n * @param text - The text of the heading.\n * @param level - The level of the heading (defaults to 1).\n */\nexport function heading(text: string, options?: HeadingOptions): string {\n const level = options?.level ?? 1;\n return `${'#'.repeat(level)} ${text}`;\n}\n\n/**\n * Create a blockquote block.\n *\n * Markdown:\n * ```\n * > Content\n * > Content\n * ```\n *\n * @param text - The content of the blockquote.\n */\nexport function blockquote(content: string): string {\n return prefixLines(content, '> ');\n}\n\n/**\n * Create a code block.\n *\n * Markdown:\n * ````\n * ```\n * Content\n * ```\n * ````\n *\n * @param content - The content of the code block.\n */\nexport function codeBlock(content: string): string {\n return `\\`\\`\\`\\n${content}\\n\\`\\`\\``;\n}\n\n/**\n * Create an unordered list block.\n *\n * Markdown:\n * ```\n * - Item\n * - Item\n * ```\n *\n * @param items - The items of the list.\n */\nexport function list(items: readonly string[]): string {\n return items.map((item) => `- ${item}`).join('\\n');\n}\n\n/**\n * Create an ordered list block.\n *\n * Markdown:\n * ```\n * 1. Item\n * 2. Item\n * ```\n *\n * @param items - The items of the list.\n */\nexport function orderedList(items: readonly string[]): string {\n return items.map((item, index) => `${index + 1}. ${item}`).join('\\n');\n}\n"],"mappings":"SAASA,WAAW;AAOpB,OAAO,MAAMC,cAAc,GAAG,KAAK;AAanC,OAAO,SAASC,OAAOA,CAACC,IAAY,EAAEC,OAAwB,EAAU;EACtE,MAAMC,KAAK,GAAGD,OAAO,EAAEC,KAAK,IAAI,CAAC;EACjC,OAAO,GAAG,GAAG,CAACC,MAAM,CAACD,KAAK,CAAC,IAAIF,IAAI,EAAE;AACvC;AAaA,OAAO,SAASI,UAAUA,CAACC,OAAe,EAAU;EAClD,OAAOR,WAAW,CAACQ,OAAO,EAAE,IAAI,CAAC;AACnC;AAcA,OAAO,SAASC,SAASA,CAACD,OAAe,EAAU;EACjD,OAAO,WAAWA,OAAO,UAAU;AACrC;AAaA,OAAO,SAASE,IAAIA,CAACC,KAAwB,EAAU;EACrD,OAAOA,KAAK,CAACC,GAAG,CAAEC,IAAI,IAAK,KAAKA,IAAI,EAAE,CAAC,CAACC,IAAI,CAAC,IAAI,CAAC;AACpD;AAaA,OAAO,SAASC,WAAWA,CAACJ,KAAwB,EAAU;EAC5D,OAAOA,KAAK,CAACC,GAAG,CAAC,CAACC,IAAI,EAAEG,KAAK,KAAK,GAAGA,KAAK,GAAG,CAAC,KAAKH,IAAI,EAAE,CAAC,CAACC,IAAI,CAAC,IAAI,CAAC;AACvE","ignoreList":[]}
package/dist/esm/html.mjs CHANGED
@@ -1,4 +1,12 @@
1
- export function disclosure(title, content) {
2
- return `<details>\n<summary>${title}</summary>\n${content}\n</details>`;
1
+ export const lineBreak = '<br/>';
2
+ export function disclosure(title, content, options) {
3
+ const headerHack = title.startsWith('#') ? '\n\n' : '';
4
+ return `<details${options?.open ? ' open' : ''}>
5
+ <summary>${headerHack}${title}${headerHack}</summary>
6
+ ${escapeMarkdownInHtml(content)}
7
+ </details>`;
8
+ }
9
+ function escapeMarkdownInHtml(markdown) {
10
+ return `\n${markdown}\n`;
3
11
  }
4
12
  //# sourceMappingURL=html.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"html.mjs","names":["disclosure","title","content"],"sources":["../../src/html.ts"],"sourcesContent":["/**\n * Create a disclosure block.\n *\n * Markdown/Html:\n * ```\n * <details>\n * <summary>Title</summary>\n * Content\n * </details>\n * ```\n *\n * @param title - The title of the disclosure.\n * @param content - The content of the disclosure.\n */\nexport function disclosure(title: string, content: string): string {\n return `<details>\\n<summary>${title}</summary>\\n${content}\\n</details>`;\n}\n"],"mappings":"AAcA,OAAO,SAASA,UAAUA,CAACC,KAAa,EAAEC,OAAe,EAAU;EACjE,OAAO,uBAAuBD,KAAK,eAAeC,OAAO,cAAc;AACzE","ignoreList":[]}
1
+ {"version":3,"file":"html.mjs","names":["lineBreak","disclosure","title","content","options","headerHack","startsWith","open","escapeMarkdownInHtml","markdown"],"sources":["../../src/html.ts"],"sourcesContent":["/**\n * Create a line break.\n *\n * Markdown (as HTML): `<br/>`\n */\nexport const lineBreak = '<br/>';\n\n/**\n * Options for the `disclosure` block.\n */\nexport type DisclosureOptions = {\n /**\n * Whether the disclosure block should be open by default (defaults to false).\n */\n open?: boolean;\n};\n\n/**\n * Create a disclosure block.\n *\n * Markdown (as HTML):\n * ```\n * <details>\n * <summary>Title</summary>\n * Content\n * </details>\n * ```\n *\n * @param title - The title of the disclosure (text only or markdown heading: `# heading`).\n * @param content - The content of the disclosure (can include markdown).\n * @param options - The options for the disclosure.\n */\nexport function disclosure(title: string, content: string, options?: DisclosureOptions): string {\n // Add extra with lines to render header properly. New line should not be added for regular text\n // as it messes up the formatting.\n const headerHack = title.startsWith('#') ? '\\n\\n' : '';\n\n return `<details${options?.open ? ' open' : ''}>\n<summary>${headerHack}${title}${headerHack}</summary>\n${escapeMarkdownInHtml(content)}\n</details>`;\n}\n\n// Blank lines are required for rendering a markdown section inside html tag.\n// See https://gist.github.com/scmx/eca72d44afee0113ceb0349dd54a84a2\nfunction escapeMarkdownInHtml(markdown: string): string {\n return `\\n${markdown}\\n`;\n}\n"],"mappings":"AAKA,OAAO,MAAMA,SAAS,GAAG,OAAO;AA2BhC,OAAO,SAASC,UAAUA,CAACC,KAAa,EAAEC,OAAe,EAAEC,OAA2B,EAAU;EAG9F,MAAMC,UAAU,GAAGH,KAAK,CAACI,UAAU,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,EAAE;EAEtD,OAAO,WAAWF,OAAO,EAAEG,IAAI,GAAG,OAAO,GAAG,EAAE;AAChD,WAAWF,UAAU,GAAGH,KAAK,GAAGG,UAAU;AAC1C,EAAEG,oBAAoB,CAACL,OAAO,CAAC;AAC/B,WAAW;AACX;AAIA,SAASK,oBAAoBA,CAACC,QAAgB,EAAU;EACtD,OAAO,KAAKA,QAAQ,IAAI;AAC1B","ignoreList":[]}
@@ -1,6 +1,5 @@
1
- export { joinBlocks } from "./join-blocks.mjs";
2
1
  export { horizontalRule, heading, blockquote, orderedList, list, codeBlock } from "./block.mjs";
3
- export { lineBreak, code, italic, bold, link, image } from "./inline.mjs";
2
+ export { code, italic, bold, link, image } from "./inline.mjs";
4
3
  export { table } from "./table.mjs";
5
- export { disclosure } from "./html.mjs";
4
+ export { lineBreak, disclosure } from "./html.mjs";
6
5
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["joinBlocks","horizontalRule","heading","blockquote","orderedList","list","codeBlock","lineBreak","code","italic","bold","link","image","table","disclosure"],"sources":["../../src/index.ts"],"sourcesContent":["export { joinBlocks } from './join-blocks';\nexport { horizontalRule, heading, blockquote, orderedList, list, codeBlock } from './block';\nexport { lineBreak, code, italic, bold, link, image } from './inline';\nexport { table } from './table';\nexport { disclosure } from './html';\n\nexport type { TableOptions } from './table';\n"],"mappings":"SAASA,UAAU;AAAA,SACVC,cAAc,EAAEC,OAAO,EAAEC,UAAU,EAAEC,WAAW,EAAEC,IAAI,EAAEC,SAAS;AAAA,SACjEC,SAAS,EAAEC,IAAI,EAAEC,MAAM,EAAEC,IAAI,EAAEC,IAAI,EAAEC,KAAK;AAAA,SAC1CC,KAAK;AAAA,SACLC,UAAU","ignoreList":[]}
1
+ {"version":3,"file":"index.mjs","names":["horizontalRule","heading","blockquote","orderedList","list","codeBlock","code","italic","bold","link","image","table","lineBreak","disclosure"],"sources":["../../src/index.ts"],"sourcesContent":["export { horizontalRule, heading, blockquote, orderedList, list, codeBlock } from './block';\nexport { code, italic, bold, link, image } from './inline';\nexport { table } from './table';\nexport { lineBreak, disclosure } from './html';\n\nexport type { TableOptions } from './table';\nexport type { DisclosureOptions } from './html';\n"],"mappings":"SAASA,cAAc,EAAEC,OAAO,EAAEC,UAAU,EAAEC,WAAW,EAAEC,IAAI,EAAEC,SAAS;AAAA,SACjEC,IAAI,EAAEC,MAAM,EAAEC,IAAI,EAAEC,IAAI,EAAEC,KAAK;AAAA,SAC/BC,KAAK;AAAA,SACLC,SAAS,EAAEC,UAAU","ignoreList":[]}
@@ -1,4 +1,3 @@
1
- export const lineBreak = ' \n';
2
1
  export function italic(text) {
3
2
  return `*${text}*`;
4
3
  }
@@ -1 +1 @@
1
- {"version":3,"file":"inline.mjs","names":["lineBreak","italic","text","bold","code","link","url","image"],"sources":["../../src/inline.ts"],"sourcesContent":["/**\n * Create a line break.\n *\n * Markdown: `__\\n`\n */\nexport const lineBreak = ' \\n';\n\n/**\n * Create an italic text.\n *\n * Markdown: `*text*`\n *\n * @param text - The text to be italicized.\n */\nexport function italic(text: string): string {\n return `*${text}*`;\n}\n\n/**\n * Create a bold text.\n *\n * Markdown: `**text**`\n *\n * @param text - The text to be bolded.\n */\nexport function bold(text: string): string {\n return `**${text}**`;\n}\n\n/**\n * Create a code text.\n *\n * Markdown: `\\`text\\``\n *\n * @param text - The text to be marked as code.\n */\nexport function code(text: string): string {\n return `\\`${text}\\``;\n}\n\n/**\n * Create a link or autolink span.\n *\n * Markdown:\n * - `[text](url)` link when `text` is provided\n * - `<url>` autolink when `text` is not provided\n *\n * @param url - The URL to be linked.\n * @param text - The title for the link (optional).\n */\nexport function link(url: string, text?: string): string {\n return text ? `[${text}](${url})` : `<${url}>`;\n}\n\n/**\n * Create an image text.\n *\n * Markdown: `![text](url)`\n *\n * @param url - The URL of the image.\n * @param text - The description for the image (optional).\n */\nexport function image(url: string, text?: string): string {\n return `![${text ?? ''}](${url})`;\n}\n"],"mappings":"AAKA,OAAO,MAAMA,SAAS,GAAG,MAAM;AAS/B,OAAO,SAASC,MAAMA,CAACC,IAAY,EAAU;EAC3C,OAAO,IAAIA,IAAI,GAAG;AACpB;AASA,OAAO,SAASC,IAAIA,CAACD,IAAY,EAAU;EACzC,OAAO,KAAKA,IAAI,IAAI;AACtB;AASA,OAAO,SAASE,IAAIA,CAACF,IAAY,EAAU;EACzC,OAAO,KAAKA,IAAI,IAAI;AACtB;AAYA,OAAO,SAASG,IAAIA,CAACC,GAAW,EAAEJ,IAAa,EAAU;EACvD,OAAOA,IAAI,GAAG,IAAIA,IAAI,KAAKI,GAAG,GAAG,GAAG,IAAIA,GAAG,GAAG;AAChD;AAUA,OAAO,SAASC,KAAKA,CAACD,GAAW,EAAEJ,IAAa,EAAU;EACxD,OAAO,KAAKA,IAAI,IAAI,EAAE,KAAKI,GAAG,GAAG;AACnC","ignoreList":[]}
1
+ {"version":3,"file":"inline.mjs","names":["italic","text","bold","code","link","url","image"],"sources":["../../src/inline.ts"],"sourcesContent":["/**\n * Create an italic text.\n *\n * Markdown: `*text*`\n *\n * @param text - The text to be italicized.\n */\nexport function italic(text: string): string {\n return `*${text}*`;\n}\n\n/**\n * Create a bold text.\n *\n * Markdown: `**text**`\n *\n * @param text - The text to be bolded.\n */\nexport function bold(text: string): string {\n return `**${text}**`;\n}\n\n/**\n * Create a code text.\n *\n * Markdown: `code`\n *\n * @param text - The text to be marked as code.\n */\nexport function code(text: string): string {\n return `\\`${text}\\``;\n}\n\n/**\n * Create a link or autolink span.\n *\n * Markdown:\n * - `[text](url)` link when `text` is provided\n * - `<url>` autolink when `text` is not provided\n *\n * @param url - The URL to be linked.\n * @param text - The title for the link (optional).\n */\nexport function link(url: string, text?: string): string {\n return text ? `[${text}](${url})` : `<${url}>`;\n}\n\n/**\n * Create an image text.\n *\n * Markdown: `![text](url)`\n *\n * @param url - The URL of the image.\n * @param text - The description for the image (optional).\n */\nexport function image(url: string, text?: string): string {\n return `![${text ?? ''}](${url})`;\n}\n"],"mappings":"AAOA,OAAO,SAASA,MAAMA,CAACC,IAAY,EAAU;EAC3C,OAAO,IAAIA,IAAI,GAAG;AACpB;AASA,OAAO,SAASC,IAAIA,CAACD,IAAY,EAAU;EACzC,OAAO,KAAKA,IAAI,IAAI;AACtB;AASA,OAAO,SAASE,IAAIA,CAACF,IAAY,EAAU;EACzC,OAAO,KAAKA,IAAI,IAAI;AACtB;AAYA,OAAO,SAASG,IAAIA,CAACC,GAAW,EAAEJ,IAAa,EAAU;EACvD,OAAOA,IAAI,GAAG,IAAIA,IAAI,KAAKI,GAAG,GAAG,GAAG,IAAIA,GAAG,GAAG;AAChD;AAUA,OAAO,SAASC,KAAKA,CAACD,GAAW,EAAEJ,IAAa,EAAU;EACxD,OAAO,KAAKA,IAAI,IAAI,EAAE,KAAKI,GAAG,GAAG;AACnC","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"table.mjs","names":["table","header","rows","options","length","map","escapeCellContent","row","widths","compact","getColumnsWidth","separators","_","i","repeat","renderRow","join","index","getColumnWidth","Math","max","paddedCells","cell","padEnd","replace"],"sources":["../../src/table.ts"],"sourcesContent":["export type TableOptions = {\n compact: boolean;\n};\n\nexport function table(header: string[], rows: string[][], options?: TableOptions): string {\n if (header.length === 0) {\n return '';\n }\n\n // Escape the header and rows content\n header = header.map(escapeCellContent);\n rows = rows.map((row) => row.map(escapeCellContent));\n\n const widths = !options?.compact ? getColumnsWidth(header, rows) : header.map(() => 1);\n const separators = header.map((_, i) => '-'.repeat(widths[i] ?? 0));\n\n return [\n renderRow(header, widths),\n renderRow(separators, widths),\n ...rows.map((row) => renderRow(row, widths)),\n ].join('\\n');\n}\n\nfunction getColumnsWidth(header: string[], rows: string[][]): number[] {\n return header.map((_, index) => getColumnWidth(header, rows, index));\n}\n\nfunction getColumnWidth(header: string[], rows: string[][], index: number): number {\n return Math.max(header[index]?.length ?? 0, ...rows.map((row) => row[index]?.length ?? 0));\n}\n\nfunction renderRow(row: string[], widths: number[]): string {\n const paddedCells = row.map((cell, index) => cell.padEnd(widths[index] ?? 0));\n return `| ${paddedCells.join(' | ')} |`;\n}\n\nfunction escapeCellContent(cell: string): string {\n return cell.replace(/\\|/g, '\\\\|').replace(/\\n/g, '<br/>');\n}\n"],"mappings":"AAIA,OAAO,SAASA,KAAKA,CAACC,MAAgB,EAAEC,IAAgB,EAAEC,OAAsB,EAAU;EACxF,IAAIF,MAAM,CAACG,MAAM,KAAK,CAAC,EAAE;IACvB,OAAO,EAAE;EACX;EAGAH,MAAM,GAAGA,MAAM,CAACI,GAAG,CAACC,iBAAiB,CAAC;EACtCJ,IAAI,GAAGA,IAAI,CAACG,GAAG,CAAEE,GAAG,IAAKA,GAAG,CAACF,GAAG,CAACC,iBAAiB,CAAC,CAAC;EAEpD,MAAME,MAAM,GAAG,CAACL,OAAO,EAAEM,OAAO,GAAGC,eAAe,CAACT,MAAM,EAAEC,IAAI,CAAC,GAAGD,MAAM,CAACI,GAAG,CAAC,MAAM,CAAC,CAAC;EACtF,MAAMM,UAAU,GAAGV,MAAM,CAACI,GAAG,CAAC,CAACO,CAAC,EAAEC,CAAC,KAAK,GAAG,CAACC,MAAM,CAACN,MAAM,CAACK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EAEnE,OAAO,CACLE,SAAS,CAACd,MAAM,EAAEO,MAAM,CAAC,EACzBO,SAAS,CAACJ,UAAU,EAAEH,MAAM,CAAC,EAC7B,GAAGN,IAAI,CAACG,GAAG,CAAEE,GAAG,IAAKQ,SAAS,CAACR,GAAG,EAAEC,MAAM,CAAC,CAAC,CAC7C,CAACQ,IAAI,CAAC,IAAI,CAAC;AACd;AAEA,SAASN,eAAeA,CAACT,MAAgB,EAAEC,IAAgB,EAAY;EACrE,OAAOD,MAAM,CAACI,GAAG,CAAC,CAACO,CAAC,EAAEK,KAAK,KAAKC,cAAc,CAACjB,MAAM,EAAEC,IAAI,EAAEe,KAAK,CAAC,CAAC;AACtE;AAEA,SAASC,cAAcA,CAACjB,MAAgB,EAAEC,IAAgB,EAAEe,KAAa,EAAU;EACjF,OAAOE,IAAI,CAACC,GAAG,CAACnB,MAAM,CAACgB,KAAK,CAAC,EAAEb,MAAM,IAAI,CAAC,EAAE,GAAGF,IAAI,CAACG,GAAG,CAAEE,GAAG,IAAKA,GAAG,CAACU,KAAK,CAAC,EAAEb,MAAM,IAAI,CAAC,CAAC,CAAC;AAC5F;AAEA,SAASW,SAASA,CAACR,GAAa,EAAEC,MAAgB,EAAU;EAC1D,MAAMa,WAAW,GAAGd,GAAG,CAACF,GAAG,CAAC,CAACiB,IAAI,EAAEL,KAAK,KAAKK,IAAI,CAACC,MAAM,CAACf,MAAM,CAACS,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;EAC7E,OAAO,KAAKI,WAAW,CAACL,IAAI,CAAC,KAAK,CAAC,IAAI;AACzC;AAEA,SAASV,iBAAiBA,CAACgB,IAAY,EAAU;EAC/C,OAAOA,IAAI,CAACE,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAACA,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;AAC3D","ignoreList":[]}
1
+ {"version":3,"file":"table.mjs","names":["table","header","rows","options","length","map","escapeCellContent","row","widths","compact","getColumnsWidth","separators","_","i","repeat","renderRow","join","index","getColumnWidth","Math","max","paddedCells","cell","padEnd","replace"],"sources":["../../src/table.ts"],"sourcesContent":["export type TableOptions = {\n compact: boolean;\n};\n\nexport function table(\n header: readonly string[],\n rows: readonly string[][],\n options?: TableOptions,\n): string {\n if (header.length === 0) {\n return '';\n }\n\n // Escape the header and rows content\n header = header.map(escapeCellContent);\n rows = rows.map((row) => row.map(escapeCellContent));\n\n const widths = !options?.compact ? getColumnsWidth(header, rows) : header.map(() => 1);\n const separators = header.map((_, i) => '-'.repeat(widths[i] ?? 0));\n\n return [\n renderRow(header, widths),\n renderRow(separators, widths),\n ...rows.map((row) => renderRow(row, widths)),\n ].join('\\n');\n}\n\nfunction getColumnsWidth(header: readonly string[], rows: readonly string[][]): number[] {\n return header.map((_, index) => getColumnWidth(header, rows, index));\n}\n\nfunction getColumnWidth(\n header: readonly string[],\n rows: readonly string[][],\n index: number,\n): number {\n return Math.max(header[index]?.length ?? 0, ...rows.map((row) => row[index]?.length ?? 0));\n}\n\nfunction renderRow(row: readonly string[], widths: readonly number[]): string {\n const paddedCells = row.map((cell, index) => cell.padEnd(widths[index] ?? 0));\n return `| ${paddedCells.join(' | ')} |`;\n}\n\nfunction escapeCellContent(cell: string): string {\n return cell.replace(/\\|/g, '\\\\|').replace(/\\n/g, '<br/>');\n}\n"],"mappings":"AAIA,OAAO,SAASA,KAAKA,CACnBC,MAAyB,EACzBC,IAAyB,EACzBC,OAAsB,EACd;EACR,IAAIF,MAAM,CAACG,MAAM,KAAK,CAAC,EAAE;IACvB,OAAO,EAAE;EACX;EAGAH,MAAM,GAAGA,MAAM,CAACI,GAAG,CAACC,iBAAiB,CAAC;EACtCJ,IAAI,GAAGA,IAAI,CAACG,GAAG,CAAEE,GAAG,IAAKA,GAAG,CAACF,GAAG,CAACC,iBAAiB,CAAC,CAAC;EAEpD,MAAME,MAAM,GAAG,CAACL,OAAO,EAAEM,OAAO,GAAGC,eAAe,CAACT,MAAM,EAAEC,IAAI,CAAC,GAAGD,MAAM,CAACI,GAAG,CAAC,MAAM,CAAC,CAAC;EACtF,MAAMM,UAAU,GAAGV,MAAM,CAACI,GAAG,CAAC,CAACO,CAAC,EAAEC,CAAC,KAAK,GAAG,CAACC,MAAM,CAACN,MAAM,CAACK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EAEnE,OAAO,CACLE,SAAS,CAACd,MAAM,EAAEO,MAAM,CAAC,EACzBO,SAAS,CAACJ,UAAU,EAAEH,MAAM,CAAC,EAC7B,GAAGN,IAAI,CAACG,GAAG,CAAEE,GAAG,IAAKQ,SAAS,CAACR,GAAG,EAAEC,MAAM,CAAC,CAAC,CAC7C,CAACQ,IAAI,CAAC,IAAI,CAAC;AACd;AAEA,SAASN,eAAeA,CAACT,MAAyB,EAAEC,IAAyB,EAAY;EACvF,OAAOD,MAAM,CAACI,GAAG,CAAC,CAACO,CAAC,EAAEK,KAAK,KAAKC,cAAc,CAACjB,MAAM,EAAEC,IAAI,EAAEe,KAAK,CAAC,CAAC;AACtE;AAEA,SAASC,cAAcA,CACrBjB,MAAyB,EACzBC,IAAyB,EACzBe,KAAa,EACL;EACR,OAAOE,IAAI,CAACC,GAAG,CAACnB,MAAM,CAACgB,KAAK,CAAC,EAAEb,MAAM,IAAI,CAAC,EAAE,GAAGF,IAAI,CAACG,GAAG,CAAEE,GAAG,IAAKA,GAAG,CAACU,KAAK,CAAC,EAAEb,MAAM,IAAI,CAAC,CAAC,CAAC;AAC5F;AAEA,SAASW,SAASA,CAACR,GAAsB,EAAEC,MAAyB,EAAU;EAC5E,MAAMa,WAAW,GAAGd,GAAG,CAACF,GAAG,CAAC,CAACiB,IAAI,EAAEL,KAAK,KAAKK,IAAI,CAACC,MAAM,CAACf,MAAM,CAACS,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;EAC7E,OAAO,KAAKI,WAAW,CAACL,IAAI,CAAC,KAAK,CAAC,IAAI;AACzC;AAEA,SAASV,iBAAiBA,CAACgB,IAAY,EAAU;EAC/C,OAAOA,IAAI,CAACE,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAACA,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;AAC3D","ignoreList":[]}
@@ -3,7 +3,10 @@
3
3
  *
4
4
  * Markdown: `---`
5
5
  */
6
- export declare const horizontalRule = "\n---\n";
6
+ export declare const horizontalRule = "---";
7
+ type HeadingOptions = {
8
+ level: number;
9
+ };
7
10
  /**
8
11
  * Create a heading block.
9
12
  * Markdown: `# Heading`
@@ -11,7 +14,7 @@ export declare const horizontalRule = "\n---\n";
11
14
  * @param text - The text of the heading.
12
15
  * @param level - The level of the heading (defaults to 1).
13
16
  */
14
- export declare function heading(text: string, level?: number): string;
17
+ export declare function heading(text: string, options?: HeadingOptions): string;
15
18
  /**
16
19
  * Create a blockquote block.
17
20
  *
@@ -48,7 +51,7 @@ export declare function codeBlock(content: string): string;
48
51
  *
49
52
  * @param items - The items of the list.
50
53
  */
51
- export declare function list(items: string[]): string;
54
+ export declare function list(items: readonly string[]): string;
52
55
  /**
53
56
  * Create an ordered list block.
54
57
  *
@@ -60,4 +63,5 @@ export declare function list(items: string[]): string;
60
63
  *
61
64
  * @param items - The items of the list.
62
65
  */
63
- export declare function orderedList(items: string[]): string;
66
+ export declare function orderedList(items: readonly string[]): string;
67
+ export {};
@@ -1,7 +1,22 @@
1
+ /**
2
+ * Create a line break.
3
+ *
4
+ * Markdown (as HTML): `<br/>`
5
+ */
6
+ export declare const lineBreak = "<br/>";
7
+ /**
8
+ * Options for the `disclosure` block.
9
+ */
10
+ export type DisclosureOptions = {
11
+ /**
12
+ * Whether the disclosure block should be open by default (defaults to false).
13
+ */
14
+ open?: boolean;
15
+ };
1
16
  /**
2
17
  * Create a disclosure block.
3
18
  *
4
- * Markdown/Html:
19
+ * Markdown (as HTML):
5
20
  * ```
6
21
  * <details>
7
22
  * <summary>Title</summary>
@@ -9,7 +24,8 @@
9
24
  * </details>
10
25
  * ```
11
26
  *
12
- * @param title - The title of the disclosure.
13
- * @param content - The content of the disclosure.
27
+ * @param title - The title of the disclosure (text only or markdown heading: `# heading`).
28
+ * @param content - The content of the disclosure (can include markdown).
29
+ * @param options - The options for the disclosure.
14
30
  */
15
- export declare function disclosure(title: string, content: string): string;
31
+ export declare function disclosure(title: string, content: string, options?: DisclosureOptions): string;
@@ -1,6 +1,6 @@
1
- export { joinBlocks } from './join-blocks';
2
1
  export { horizontalRule, heading, blockquote, orderedList, list, codeBlock } from './block';
3
- export { lineBreak, code, italic, bold, link, image } from './inline';
2
+ export { code, italic, bold, link, image } from './inline';
4
3
  export { table } from './table';
5
- export { disclosure } from './html';
4
+ export { lineBreak, disclosure } from './html';
6
5
  export type { TableOptions } from './table';
6
+ export type { DisclosureOptions } from './html';
@@ -1,9 +1,3 @@
1
- /**
2
- * Create a line break.
3
- *
4
- * Markdown: `__\n`
5
- */
6
- export declare const lineBreak = " \n";
7
1
  /**
8
2
  * Create an italic text.
9
3
  *
@@ -23,7 +17,7 @@ export declare function bold(text: string): string;
23
17
  /**
24
18
  * Create a code text.
25
19
  *
26
- * Markdown: `\`text\``
20
+ * Markdown: `code`
27
21
  *
28
22
  * @param text - The text to be marked as code.
29
23
  */
@@ -1,4 +1,4 @@
1
1
  export type TableOptions = {
2
2
  compact: boolean;
3
3
  };
4
- export declare function table(header: string[], rows: string[][], options?: TableOptions): string;
4
+ export declare function table(header: readonly string[], rows: readonly string[][], options?: TableOptions): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-markdown-builder",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Elegant markdown builder with minimal bundle size.",
5
5
  "main": "dist/commonjs/index.js",
6
6
  "module": "dist/esm/index.mjs",
@@ -24,12 +24,12 @@
24
24
  "typecheck": "tsc --noEmit",
25
25
  "lint": "eslint \"**/*.{js,ts,tsx}\"",
26
26
  "clean": "del-cli dist",
27
- "release": "release-it",
28
- "release:beta": "release-it --preRelease=beta",
29
- "build": "yarn clean && yarn build:commonjs && yarn build:esm && yarn build:typescript",
27
+ "build": "yarn clean && yarn build:commonjs && yarn build:esm && yarn build:types",
30
28
  "build:commonjs": "BABEL_ENV=cjs babel src --out-dir \"dist/commonjs\" --extensions .js,.ts --out-file-extension .js --source-maps --no-comments",
31
29
  "build:esm": "BABEL_ENV=esm babel src --out-dir \"dist/esm\" --extensions .js,.ts --out-file-extension .mjs --source-maps --no-comments",
32
- "build:typescript": "tsc --project tsconfig.release.json --outDir \"dist/types\""
30
+ "build:types": "tsc --project tsconfig.release.json --outDir \"dist/types\"",
31
+ "release": "release-it",
32
+ "release:beta": "release-it --preRelease=beta"
33
33
  },
34
34
  "keywords": [
35
35
  "markdown",
@@ -84,6 +84,15 @@
84
84
  ]
85
85
  },
86
86
  "release-it": {
87
+ "hooks": {
88
+ "before:init": [
89
+ "yarn typecheck",
90
+ "yarn test",
91
+ "yarn lint"
92
+ ],
93
+ "after:bump": "yarn build",
94
+ "after:release": "echo Successfully released ${name} v${version} to ${repo.repository}."
95
+ },
87
96
  "git": {
88
97
  "commitMessage": "chore: release ${version}",
89
98
  "tagName": "v${version}"
@@ -1,10 +0,0 @@
1
- "use strict";
2
-
3
- exports.joinBlocks = joinBlocks;
4
- function joinBlocks(blocks) {
5
- return blocks.map(trimBlock).join('\n\n');
6
- }
7
- function trimBlock(block) {
8
- return block.replace(/^\n+|\n+$/g, '');
9
- }
10
- //# sourceMappingURL=join-blocks.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"join-blocks.js","names":["joinBlocks","blocks","map","trimBlock","join","block","replace"],"sources":["../../src/join-blocks.ts"],"sourcesContent":["/**\n * Join blocks of text into a single markdown document (string).\n *\n * @param blocks - The blocks of text to join.\n * @returns Markdown document string.\n */\nexport function joinBlocks(blocks: string[]): string {\n return blocks.map(trimBlock).join('\\n\\n');\n}\n\nfunction trimBlock(block: string): string {\n return block.replace(/^\\n+|\\n+$/g, '');\n}\n"],"mappings":";;;AAMO,SAASA,UAAUA,CAACC,MAAgB,EAAU;EACnD,OAAOA,MAAM,CAACC,GAAG,CAACC,SAAS,CAAC,CAACC,IAAI,CAAC,MAAM,CAAC;AAC3C;AAEA,SAASD,SAASA,CAACE,KAAa,EAAU;EACxC,OAAOA,KAAK,CAACC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;AACxC","ignoreList":[]}
@@ -1,7 +0,0 @@
1
- export function joinBlocks(blocks) {
2
- return blocks.map(trimBlock).join('\n\n');
3
- }
4
- function trimBlock(block) {
5
- return block.replace(/^\n+|\n+$/g, '');
6
- }
7
- //# sourceMappingURL=join-blocks.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"join-blocks.mjs","names":["joinBlocks","blocks","map","trimBlock","join","block","replace"],"sources":["../../src/join-blocks.ts"],"sourcesContent":["/**\n * Join blocks of text into a single markdown document (string).\n *\n * @param blocks - The blocks of text to join.\n * @returns Markdown document string.\n */\nexport function joinBlocks(blocks: string[]): string {\n return blocks.map(trimBlock).join('\\n\\n');\n}\n\nfunction trimBlock(block: string): string {\n return block.replace(/^\\n+|\\n+$/g, '');\n}\n"],"mappings":"AAMA,OAAO,SAASA,UAAUA,CAACC,MAAgB,EAAU;EACnD,OAAOA,MAAM,CAACC,GAAG,CAACC,SAAS,CAAC,CAACC,IAAI,CAAC,MAAM,CAAC;AAC3C;AAEA,SAASD,SAASA,CAACE,KAAa,EAAU;EACxC,OAAOA,KAAK,CAACC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;AACxC","ignoreList":[]}
@@ -1,7 +0,0 @@
1
- /**
2
- * Join blocks of text into a single markdown document (string).
3
- *
4
- * @param blocks - The blocks of text to join.
5
- * @returns Markdown document string.
6
- */
7
- export declare function joinBlocks(blocks: string[]): string;