diff --git a/src/modules/MdRender/index.css b/src/modules/MdRender/index.css index 926ecaf..6ab1a8f 100644 --- a/src/modules/MdRender/index.css +++ b/src/modules/MdRender/index.css @@ -239,4 +239,12 @@ padding-right: 5px; margin-left: 6px; color: var(--text-2); +} +#MD tr:first-child{ + border-width: 0px 0px 2px 0px; + border-style: solid; + border-color: var(--main-1);; +} +#MD td{ + padding: 5px; } \ No newline at end of file diff --git a/src/modules/MdRender/index.jsx b/src/modules/MdRender/index.jsx index 735f2ae..bd8438a 100644 --- a/src/modules/MdRender/index.jsx +++ b/src/modules/MdRender/index.jsx @@ -16,7 +16,7 @@ import Gitalk from 'gitalk' import Darkmode from 'drkmd-js' import ExifReader from 'exifreader'; import { siNikon, siLens, siApple } from 'simple-icons' - +import { mdTableToHTML } from './md-table-to-html' const axios = require('axios'); @@ -169,7 +169,7 @@ export default function MdRender({ doc_id }) { setPageTitle(`${gistTitle} - ${BLOG_NAME}`) setPageDescription(gistContent.replaceAll("#", " ").slice(0, 500)) }) - .catch(()=>{ + .catch(() => { window.location.href = "/?page=code-404" }) // eslint-disable-next-line @@ -188,7 +188,7 @@ export default function MdRender({ doc_id }) { }) gitalk.render("comments") } - }, [doc_id,postTitle]) + }, [doc_id, postTitle]) let { date = "", tags = [] } = documentInfo @@ -286,8 +286,21 @@ export default function MdRender({ doc_id }) { return
{children}
+ }, span({ node, inline, className, children, ...props }) { - + if (className === "math math-inline") { let math_tex = children[0] || ""; let math_html = katex.renderToString(math_tex, { @@ -297,7 +310,7 @@ export default function MdRender({ doc_id }) { }); return } - + else { return {children} } @@ -343,9 +356,9 @@ export default function MdRender({ doc_id }) { }) .catch(() => { // image without exif info - let exifText = document.getElementById(img_url+"EXIF-Text") + let exifText = document.getElementById(img_url + "EXIF-Text") try { - exifText.parentNode.removeChild(exifText) + exifText.parentNode.removeChild(exifText) } catch (error) { // pass } @@ -358,7 +371,7 @@ export default function MdRender({ doc_id }) { - | + | diff --git a/src/modules/MdRender/md-table-to-html.js b/src/modules/MdRender/md-table-to-html.js new file mode 100644 index 0000000..6feadc7 --- /dev/null +++ b/src/modules/MdRender/md-table-to-html.js @@ -0,0 +1,133 @@ +const alignments = ['left', 'center', 'right']; + +/** + * Converts a markdown table string into HTML. + * @param {string} md Markdown table as a string. + */ +export function mdTableToHTML(md) { + var lines = getLines(md); + var isHeader = true; + var table = new HTMLTable(); + var colAlignments = []; + lines.forEach(function(line) { + if (isHeaderSeparation(line)) { + isHeader = false; + colAlignments = getAlignment(line); + return; + } + var vals = splitLine(line); + table.addRow(vals, isHeader); + }); + table.setAlignments(colAlignments); + return { + html: table.getHTML(), + htmlString: table.getHTMLString() + } +} + +/** + * Converts a document into an array of string, where each element corresponds to one row. + * @param {string} doc Document + * @returns {string[]} The lines of the document. + */ +function getLines(doc) { + return doc.replace(/\r\n/g,"\n").split("\n") +} + +/** + * Checks whether a line contains the table syntax that separates table header from body. + * Example for a separation line: "| --- |:---:| ---:|" + * @param {string} line A line of a markdown document. + * @returns {boolean} True if the line is a separation line. + */ +function isHeaderSeparation(line) { + let match = line.match(/(\|\s*(:)?\s*-{3,}\s*(:)?\s*)+\|/g); + if (!Array.isArray(match)) return false; + return match.length > 0; +} + +/** + * Reads the column alignment information from a separation line. + * E.g. "| --- |:---:| ---:|" is ['left', 'center', 'right'] + * @param {string} headerLine A line for which isHeaderSeparation returns true. + * @returns {string[]} The alignment of each column, entries are in ['left', 'center', 'right']. + */ +function getAlignment(headerLine) { + let parts = splitLine(headerLine); + + return parts.map(col => { + if (col.length === 0) return alignments[0]; + let firstChar = col.charAt(0), + lastChar = col.slice(-1); + if (firstChar === ':' && lastChar === ':') return alignments[1]; + if (lastChar === ':') return alignments[2]; + return alignments[0]; + }) +} + +/** + * Converts an alignment into the corresponding style tag. + * Empty string for alignment: left (default). + * @param {string} alignment Alignment, i.e. either of ['left', 'center', 'right']. + * @returns {string} The style attribute with text-alignment. + */ +function getStyleAttribute(alignment) { + if (alignment === alignments[0]) return ''; + return ' style="text-align: ' + alignment + ';"'; +} + +/** + * Splits a Markdown table line into its trimmed column values. + * @param {string} line Markdown table line. + * @returns {string[]} The trimmed column values. + */ +function splitLine(line) { + return line.split('|').map(x => x.trim()).filter((x, i, a) => { return x.length > 0 || [0, a.length].indexOf(i) === -1}) +} + +/** + * HTML table creation helper class. + * Constructs the table and returns the HTML code. + */ +function HTMLTable() { + this.ths = []; + this.tds = []; + this.alignments = []; + + this.getHTMLString = function() { + let newline = '\n'; + return "