diff --git a/src/components/markdown.ts b/src/components/markdown.ts index cfca251..1f5fa03 100644 --- a/src/components/markdown.ts +++ b/src/components/markdown.ts @@ -1,23 +1,24 @@ import { FlatTemplatable } from "tempstream"; import { Component } from "../component"; import { ExtractStructuredComponentArgumentsValues, MarkdownArgument, } from "../component-arguments"; import { marked } from "marked"; +import { insert_nbsp } from "../utils/insert_nbsp"; const component_arguments = { markdown: new MarkdownArgument() }; export class Markdown extends Component { getArguments() { return component_arguments; } toHTML({ markdown, }: ExtractStructuredComponentArgumentsValues< typeof component_arguments >): FlatTemplatable { - return marked.parse(markdown); + return marked.parse(insert_nbsp(markdown)); } } diff --git a/src/index.ts b/src/index.ts index ccddb9a..ca0fbdf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,45 +1,48 @@ import { FlatTemplatable, tempstream } from "tempstream"; import { Registry } from "./registry"; import { marked } from "marked"; +import { insert_nbsp } from "./utils/insert_nbsp"; export * from "./component-arguments"; export * from "./component"; export * from "./registry"; +export { insert_nbsp } from "./utils/insert_nbsp"; export type JDDocument = Array<{ component_name: string; args: Record; }>; export interface JDDContext { render_image: (path_to_image: string) => FlatTemplatable; render_markdown: (markdown: string) => FlatTemplatable; } export const simpleJDDContext: JDDContext = { - render_image: (path) => /* HTML */ ``, - render_markdown: (string) => (string ? marked.parse(string) : ""), + render_image: () => /* HTML */ ``, + render_markdown: (string) => + string ? marked.parse(insert_nbsp(string)) : "", }; export function render( registry: Registry, document: JDDocument, context: JDDContext ) { return tempstream`${document.map(({ component_name, args }) => { const component = registry.get(component_name); if (!component) { console.warn( "Component not found in the registry: " + component_name ); return ""; } for (const arg_name in component?.getArguments()) { if (!Object.prototype.hasOwnProperty.call(args, arg_name)) { args[arg_name] = component ?.getArguments() [arg_name]?.getEmptyValue(); } } return component.toHTML(args, context); })}`; } diff --git a/src/utils/insert_nbsp.test.ts b/src/utils/insert_nbsp.test.ts new file mode 100644 index 0000000..92912c0 --- /dev/null +++ b/src/utils/insert_nbsp.test.ts @@ -0,0 +1,25 @@ +import assert from "assert"; +import { insert_nbsp } from "./insert_nbsp"; + +describe("create non braking space util", () => { + it("should replace space for one letter word with non braking space", async () => { + const example = "Taki o to przykład!"; + + assert.strictEqual(insert_nbsp(example), "Taki o to przykład!"); + }); + + it("should keep original copy if there isn't any one letter word", async () => { + const example = "Uwaga przykład!"; + + assert.strictEqual(insert_nbsp(example), example); + }); + + it("shold find one letter word on first position", async () => { + const example = "O taką Polskę walczyłem"; + + assert.strictEqual( + insert_nbsp(example), + "O taką Polskę walczyłem" + ); + }); +}); diff --git a/src/utils/insert_nbsp.ts b/src/utils/insert_nbsp.ts new file mode 100644 index 0000000..33d9014 --- /dev/null +++ b/src/utils/insert_nbsp.ts @@ -0,0 +1,2 @@ +export const insert_nbsp = (string: string) => + string.replace(/(?<=\s[A-Za-z])\s|(?<=^[A-Za-z])\s/gm, " ");