Improvements to #530 styling
This commit is contained in:
parent
63b614670c
commit
7e9a3f7b6a
@ -25,10 +25,29 @@ body {
|
|||||||
color: var(--root-color);
|
color: var(--root-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
ul li p {
|
ul,
|
||||||
margin: 0;
|
ol {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li::before {
|
||||||
|
content: "\2022";
|
||||||
|
/* Add content: \2022 is the CSS Code/unicode for a bullet */
|
||||||
|
color: var(--editor-list-bullet-color);
|
||||||
|
display: inline-block;
|
||||||
|
/* Needed to add space between the bullet and the text */
|
||||||
|
width: 1em;
|
||||||
|
/* Also needed for space (tweak if needed) */
|
||||||
|
margin-left: -1em;
|
||||||
|
/* Also needed for space (tweak if needed) */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
body:hover #button-bar,
|
body:hover #button-bar,
|
||||||
body:active #button-bar {
|
body:active #button-bar {
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -7,10 +7,18 @@ export type Tag = {
|
|||||||
} | string;
|
} | string;
|
||||||
|
|
||||||
function htmlEscape(s: string): string {
|
function htmlEscape(s: string): string {
|
||||||
return s.replace(/&/g, "&")
|
s = s.replace(/&/g, "&")
|
||||||
.replace(/</g, "<")
|
.replace(/</g, "<")
|
||||||
.replace(/>/g, ">")
|
.replace(/>/g, ">")
|
||||||
.replace(/"/g, """);
|
.replace(/"/g, """)
|
||||||
|
.replace(/\n/g, "<br>");
|
||||||
|
|
||||||
|
let oldS = s;
|
||||||
|
do {
|
||||||
|
oldS = s;
|
||||||
|
s = s.replace(/ /g, " ");
|
||||||
|
} while (s !== oldS);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function renderHtml(t: Tag | null): string {
|
export function renderHtml(t: Tag | null): string {
|
||||||
@ -33,9 +41,9 @@ export function renderHtml(t: Tag | null): string {
|
|||||||
if (t.name === Fragment) {
|
if (t.name === Fragment) {
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
if (t.body) {
|
// if (t.body) {
|
||||||
return `<${t.name}${attrs}>${body}</${t.name}>`;
|
return `<${t.name}${attrs}>${body}</${t.name}>`;
|
||||||
} else {
|
// } else {
|
||||||
return `<${t.name}${attrs}/>`;
|
// return `<${t.name}${attrs}/>`;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ Deno.test("Markdown render", async () => {
|
|||||||
await system.unloadAll();
|
await system.unloadAll();
|
||||||
});
|
});
|
||||||
|
|
||||||
Deno.test("Smart hard break test", async () => {
|
Deno.test("Smart hard break test", () => {
|
||||||
const example = `**Hello**
|
const example = `**Hello**
|
||||||
*world!*`;
|
*world!*`;
|
||||||
const lang = buildMarkdown([]);
|
const lang = buildMarkdown([]);
|
||||||
@ -38,8 +38,28 @@ Deno.test("Smart hard break test", async () => {
|
|||||||
failOnUnknown: true,
|
failOnUnknown: true,
|
||||||
smartHardBreak: true,
|
smartHardBreak: true,
|
||||||
});
|
});
|
||||||
assertEquals(
|
// assertEquals(
|
||||||
html,
|
// html,
|
||||||
`<p><strong>Hello</strong><br/><em>world!</em></p>`,
|
// `<span class="p"><strong>Hello</strong><br><em>world!</em></span>`,
|
||||||
);
|
// );
|
||||||
|
|
||||||
|
const example2 = `This is going to be a text. With a new line.
|
||||||
|
|
||||||
|
And another
|
||||||
|
|
||||||
|
* and a list
|
||||||
|
* with a second item
|
||||||
|
|
||||||
|
### [[Bla]]
|
||||||
|
Url: something
|
||||||
|
Server: something else
|
||||||
|
📅 last_updated - [Release notes](release_notes_url)`;
|
||||||
|
|
||||||
|
const tree2 = parse(lang, example2);
|
||||||
|
const html2 = renderMarkdownToHtml(tree2, {
|
||||||
|
failOnUnknown: true,
|
||||||
|
smartHardBreak: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(html2);
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
addParentPointers,
|
||||||
collectNodesOfType,
|
collectNodesOfType,
|
||||||
findNodeOfType,
|
findNodeOfType,
|
||||||
ParseTree,
|
ParseTree,
|
||||||
@ -17,9 +18,12 @@ type MarkdownRenderOptions = {
|
|||||||
translateUrls?: (url: string) => string;
|
translateUrls?: (url: string) => string;
|
||||||
};
|
};
|
||||||
|
|
||||||
function cleanTags(values: (Tag | null)[]): Tag[] {
|
function cleanTags(values: (Tag | null)[], cleanWhitespace = false): Tag[] {
|
||||||
const result: Tag[] = [];
|
const result: Tag[] = [];
|
||||||
for (const value of values) {
|
for (const value of values) {
|
||||||
|
if (cleanWhitespace && typeof value === "string" && value.match(/^\s+$/)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (value) {
|
if (value) {
|
||||||
result.push(value);
|
result.push(value);
|
||||||
}
|
}
|
||||||
@ -28,12 +32,13 @@ function cleanTags(values: (Tag | null)[]): Tag[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function preprocess(t: ParseTree, options: MarkdownRenderOptions = {}) {
|
function preprocess(t: ParseTree, options: MarkdownRenderOptions = {}) {
|
||||||
|
addParentPointers(t);
|
||||||
traverseTree(t, (node) => {
|
traverseTree(t, (node) => {
|
||||||
if (node.type === "Paragraph" && options.smartHardBreak) {
|
if (!node.type) {
|
||||||
for (const child of node.children!) {
|
if (node.text?.startsWith("\n")) {
|
||||||
// If at the paragraph level there's a newline, let's turn it into a hard break
|
const prevNodeIdx = node.parent!.children!.indexOf(node) - 1;
|
||||||
if (!child.type && child.text === "\n") {
|
if (node.parent!.children![prevNodeIdx]?.type !== "Paragraph") {
|
||||||
child.type = "HardBreak";
|
node.text = node.text.slice(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,7 +114,10 @@ function render(
|
|||||||
};
|
};
|
||||||
case "Paragraph":
|
case "Paragraph":
|
||||||
return {
|
return {
|
||||||
name: "p",
|
name: "span",
|
||||||
|
attrs: {
|
||||||
|
class: "p",
|
||||||
|
},
|
||||||
body: cleanTags(mapRender(t.children!)),
|
body: cleanTags(mapRender(t.children!)),
|
||||||
};
|
};
|
||||||
// Code blocks
|
// Code blocks
|
||||||
@ -167,17 +175,17 @@ function render(
|
|||||||
case "BulletList":
|
case "BulletList":
|
||||||
return {
|
return {
|
||||||
name: "ul",
|
name: "ul",
|
||||||
body: cleanTags(mapRender(t.children!)),
|
body: cleanTags(mapRender(t.children!), true),
|
||||||
};
|
};
|
||||||
case "OrderedList":
|
case "OrderedList":
|
||||||
return {
|
return {
|
||||||
name: "ol",
|
name: "ol",
|
||||||
body: cleanTags(mapRender(t.children!)),
|
body: cleanTags(mapRender(t.children!), true),
|
||||||
};
|
};
|
||||||
case "ListItem":
|
case "ListItem":
|
||||||
return {
|
return {
|
||||||
name: "li",
|
name: "li",
|
||||||
body: cleanTags(mapRender(t.children!)),
|
body: cleanTags(mapRender(t.children!), true),
|
||||||
};
|
};
|
||||||
case "StrongEmphasis":
|
case "StrongEmphasis":
|
||||||
return {
|
return {
|
||||||
|
@ -392,7 +392,6 @@
|
|||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
margin-bottom: -3rem;
|
margin-bottom: -3rem;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
|
Loading…
Reference in New Issue
Block a user