Skip to content

Commit

Permalink
refactor(hiccup-markdown): update serializeElement, add SerializeState
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Aug 20, 2019
1 parent c281f17 commit 745ea65
Showing 1 changed file with 67 additions and 63 deletions.
130 changes: 67 additions & 63 deletions packages/hiccup-markdown/src/serialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,17 @@ import { illegalArgs } from "@thi.ng/errors";
import { normalize } from "@thi.ng/hiccup";
import { repeat, wrap } from "@thi.ng/strings";

interface SerializeState {
indent: number;
sep: string;
id?: number;
pre?: boolean;
}

export const serialize = (tree: any, ctx: any) =>
_serialize(tree, ctx, { indent: 0, sep: "" });

const _serialize = (tree: any, ctx: any, state: any): string => {
const _serialize = (tree: any, ctx: any, state: SerializeState): string => {
if (tree == null) return "";
if (Array.isArray(tree)) {
if (!tree.length) {
Expand Down Expand Up @@ -62,7 +69,11 @@ const _serialize = (tree: any, ctx: any, state: any): string => {
return tree.toString();
};

const serializeIter = (iter: Iterable<any>, ctx: any, state: any) => {
const serializeIter = (
iter: Iterable<any>,
ctx: any,
state: SerializeState
) => {
if (!iter) return "";
const res = [];
for (let i of iter) {
Expand All @@ -71,86 +82,79 @@ const serializeIter = (iter: Iterable<any>, ctx: any, state: any) => {
return res.join(state.sep);
};

const header = (level: number) => (el: any[], ctx: any, state: any) =>
repeat("#", level) + " " + body(el, ctx, state) + "\n\n";
const header = (level: number) => (
el: any[],
ctx: any,
state: SerializeState
) => repeat("#", level) + " " + body(el, ctx, state) + "\n\n";

const body = (el: any[], ctx: any, state: any) =>
const body = (el: any[], ctx: any, state: SerializeState) =>
serializeIter(el[2], ctx, state);

export const serializeElement: MultiFn3<any, any, any, string> = defmulti(
(el) => el[0]
);
export const serializeElement: MultiFn3<
any,
any,
SerializeState,
string
> = defmulti((el) => el[0]);
serializeElement.add(DEFAULT, body);
serializeElement.add("h1", header(1));
serializeElement.add("h2", header(2));
serializeElement.add("h3", header(3));
serializeElement.add("h4", header(4));
serializeElement.add("h5", header(5));
serializeElement.add("h6", header(6));

serializeElement.add("p", (el, ctx, state) => `\n${body(el, ctx, state)}\n`);
serializeElement.addAll({
h1: header(1),
h2: header(2),
h3: header(3),
h4: header(4),
h5: header(5),
h6: header(6),

p: (el, ctx, state) => `\n${body(el, ctx, state)}\n`,

serializeElement.add("img", (el) => `![${el[1].alt || ""}](${el[1].src})`);
img: (el) => `![${el[1].alt || ""}](${el[1].src})`,

serializeElement.add(
"a",
(el, ctx, state) => `[${body(el, ctx, state)}](${el[1].href})`
);
a: (el, ctx, state) => `[${body(el, ctx, state)}](${el[1].href})`,

serializeElement.add("em", (el, ctx, state) => `_${body(el, ctx, state)}_`);
em: (el, ctx, state) => `_${body(el, ctx, state)}_`,

serializeElement.add(
"strong",
(el, ctx, state) => `**${body(el, ctx, state)}**`
);
strong: (el, ctx, state) => `**${body(el, ctx, state)}**`,

serializeElement.add(
"pre",
(el, ctx, state) =>
pre: (el, ctx, state) =>
`\n\`\`\`${el[1].lang || ""}\n${body(el, ctx, {
...state,
pre: true,
sep: "\n"
})}\n\`\`\`\n`
);

serializeElement.add("code", (el, ctx, state) =>
state.pre ? el[2][0] : `\`${body(el, ctx, state)}\``
);

serializeElement.add("ul", (el, ctx, state) => {
const cstate = {
...state,
indent: state.indent + 4,
sep: "\n"
};
return wrap(state.indent === 0 ? "\n" : "")(body(el, ctx, cstate));
});
})}\n\`\`\`\n`,

serializeElement.add("ol", (el, ctx, state) => {
const cstate = {
...state,
indent: state.indent + 4,
id: 0,
sep: "\n"
};
return wrap(state.indent === 0 ? "\n" : "")(body(el, ctx, cstate));
});
code: (el, ctx, state) =>
state.pre ? el[2][0] : `\`${body(el, ctx, state)}\``,

serializeElement.add(
"li",
(el, ctx, state) =>
ul: (el, ctx, state) => {
const cstate: SerializeState = {
...state,
indent: state.indent + 4,
sep: "\n"
};
return wrap(state.indent === 0 ? "\n" : "")(body(el, ctx, cstate));
},

ol: (el, ctx, state) => {
const cstate: SerializeState = {
...state,
indent: state.indent + 4,
id: 0,
sep: "\n"
};
return wrap(state.indent === 0 ? "\n" : "")(body(el, ctx, cstate));
},

li: (el, ctx, state) =>
repeat(" ", state.indent - 4) +
(state.id != null ? ++state.id + "." : "-") +
" " +
body(el, ctx, { ...state, sep: "" })
);
body(el, ctx, { ...state, sep: "" }),

serializeElement.add(
"blockquote",
(el, ctx, state) => `\n> ${body(el, ctx, state)}\n`
);
blockquote: (el, ctx, state) => `\n> ${body(el, ctx, state)}\n`,

serializeElement.add("br", () => "\\\n");
br: () => "\\\n",

serializeElement.add("hr", () => "\n---\n");
hr: () => "\n---\n"
});

0 comments on commit 745ea65

Please sign in to comment.