Skip to content

Commit

Permalink
Support attrs
Browse files Browse the repository at this point in the history
  • Loading branch information
thetarnav committed Feb 28, 2024
1 parent ca2e98d commit ae5762e
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 23 deletions.
65 changes: 54 additions & 11 deletions mds/mds.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,29 @@ export function token_type_to_string(type) {
}
}

export const
HREF = 1,
SRC = 2,
LANG = 4

/** @enum {(typeof Attr_Type)[keyof typeof Attr_Type]} */
export const Attr_Type = /** @type {const} */({
Href: HREF,
Src: SRC,
Lang: LANG,
})

/**
* @param {Attr_Type} type
* @returns {string } */
export function attr_type_to_html_attr(type) {
switch (type) {
case HREF: return "href"
case SRC : return "src"
case LANG: return "lang"
}
}

/**
* @typedef {import("./t.js").Any_Renderer} Any_Renderer
* @typedef {import("./t.js").Parser } Parser
Expand Down Expand Up @@ -117,7 +140,7 @@ export function parser_end(p) {
export function parser_add_text(p) {
if (p.text.length === 0) return
console.assert(p.len > 0, "Never adding text to root")
p.renderer.add_text(p.text, p.renderer.data)
p.renderer.add_text(p.renderer.data, p.text)
p.text = ""
}

Expand All @@ -139,7 +162,7 @@ export function parser_add_token(p, type) {
p.pending = ""
p.len += 1
p.types[p.len] = type
p.renderer.add_node(type, p.renderer.data)
p.renderer.add_node(p.renderer.data, type)
}

/**
Expand Down Expand Up @@ -247,9 +270,12 @@ export function parser_write(p, chunk) {
}
continue
default: /* parsing langiage */
p.code_block = '\n' === char
? 1
: p.code_block + char
if ('\n' === char) {
p.renderer.set_attr(p.renderer.data, LANG, p.code_block)
p.code_block = 1
} else {
p.code_block += char
}
continue
}
}
Expand Down Expand Up @@ -359,6 +385,9 @@ export function parser_write(p, chunk) {
^
*/
if (')' === char) {
const type = in_token === LINK ? HREF : SRC
const url = p.pending.slice(2)
p.renderer.set_attr(p.renderer.data, type, url)
parser_end_token(p)
} else {
p.pending += char
Expand All @@ -381,7 +410,7 @@ export function parser_write(p, chunk) {
}
/* Line break */
else {
p.renderer.add_text('\n', p.renderer.data)
p.renderer.add_text(p.renderer.data, '\n')
p.pending = char
}
continue
Expand Down Expand Up @@ -489,6 +518,7 @@ export function parser_write(p, chunk) {
* @typedef {import("./t.js").Default_Renderer_Add_Node} Default_Renderer_Add_Node
* @typedef {import("./t.js").Default_Renderer_End_Node} Default_Renderer_End_Node
* @typedef {import("./t.js").Default_Renderer_Add_Text} Default_Renderer_Add_Text
* @typedef {import("./t.js").Default_Renderer_Set_Attr} Default_Renderer_Set_Attr
*/

/**
Expand All @@ -499,6 +529,7 @@ export function default_renderer(root) {
add_node: default_add_node,
end_node: default_end_node,
add_text: default_add_text,
set_attr: default_set_attr,
data : {
nodes: /**@type {*}*/([root,,,,,]),
index: 0,
Expand All @@ -507,7 +538,7 @@ export function default_renderer(root) {
}

/** @type {Default_Renderer_Add_Node} */
export function default_add_node(type, data) {
export function default_add_node(data, type) {
/**@type {HTMLElement}*/ let mount
/**@type {HTMLElement}*/ let slot

Expand Down Expand Up @@ -545,20 +576,26 @@ export function default_end_node(data) {
}

/** @type {Default_Renderer_Add_Text} */
export function default_add_text(text, data) {
export function default_add_text(data, text) {
switch (text) {
case "" : break
case "\n": data.nodes[data.index].appendChild(document.createElement("br")) ;break
default : data.nodes[data.index].appendChild(document.createTextNode(text))
}
}

/** @type {Default_Renderer_Set_Attr} */
export function default_set_attr(data, type, value) {
data.nodes[data.index].setAttribute(attr_type_to_html_attr(type), value)
}


/**
* @typedef {import("./t.js").Logger_Renderer } Logger_Renderer
* @typedef {import("./t.js").Logger_Renderer_Add_Node} Logger_Renderer_Add_Node
* @typedef {import("./t.js").Logger_Renderer_End_Node} Logger_Renderer_End_Node
* @typedef {import("./t.js").Logger_Renderer_Add_Text} Logger_Renderer_Add_Text
* @typedef {import("./t.js").Logger_Renderer_Set_Attr} Logger_Renderer_Set_Attr
*/

/** @returns {Logger_Renderer} */
Expand All @@ -568,11 +605,12 @@ export function logger_renderer() {
add_node: logger_add_node,
end_node: logger_end_node,
add_text: logger_add_text,
set_attr: logger_set_attr,
}
}

/** @type {Logger_Renderer_Add_Node} */
export function logger_add_node(type, data) {
export function logger_add_node(data, type) {
console.log("add_node:", token_type_to_string(type))
}

Expand All @@ -582,6 +620,11 @@ export function logger_end_node(data) {
}

/** @type {Logger_Renderer_Add_Text} */
export function logger_add_text(text, data) {
console.log('add_text: "' + text + '"')
export function logger_add_text(data, text) {
console.log('add_text: "%s"', text)
}

/** @type {Logger_Renderer_Set_Attr} */
export function logger_set_attr(data, type, value) {
console.log('set_attr: %s="%s"', attr_type_to_html_attr(type), value)
}
10 changes: 7 additions & 3 deletions mds/t.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Token_Type} from './mds.js'
import {Attr_Type, Token_Type} from './mds.js'

export type Parser = {
/** {@link Renderer} interface */
Expand All @@ -19,15 +19,17 @@ export type Parser = {
code_block: string | 0 | 1
}

export type Renderer_Add_Node<TData> = (type: Token_Type, data: TData) => void
export type Renderer_Add_Node<TData> = (data: TData, type: Token_Type) => void
export type Renderer_End_Node<TData> = (data: TData) => void
export type Renderer_Add_Text<TData> = (text: string, data: TData) => void
export type Renderer_Add_Text<TData> = (data: TData, text: string) => void
export type Renderer_Set_Attr<TData> = (data: TData, type: Attr_Type, value: string) => void

export type Renderer<TData> = {
data : TData
add_node: Renderer_Add_Node<TData>
end_node: Renderer_End_Node<TData>
add_text: Renderer_Add_Text<TData>
set_attr: Renderer_Set_Attr<TData>
}

export type Any_Renderer = Renderer<any>
Expand All @@ -40,9 +42,11 @@ export type Default_Renderer = Renderer <Default_Renderer_Data>
export type Default_Renderer_Add_Node = Renderer_Add_Node<Default_Renderer_Data>
export type Default_Renderer_End_Node = Renderer_End_Node<Default_Renderer_Data>
export type Default_Renderer_Add_Text = Renderer_Add_Text<Default_Renderer_Data>
export type Default_Renderer_Set_Attr = Renderer_Set_Attr<Default_Renderer_Data>

export type Logger_Renderer_Data = undefined
export type Logger_Renderer = Renderer <Logger_Renderer_Data>
export type Logger_Renderer_Add_Node = Renderer_Add_Node<Logger_Renderer_Data>
export type Logger_Renderer_End_Node = Renderer_End_Node<Logger_Renderer_Data>
export type Logger_Renderer_Add_Text = Renderer_Add_Text<Logger_Renderer_Data>
export type Logger_Renderer_Set_Attr = Renderer_Set_Attr<Logger_Renderer_Data>
10 changes: 6 additions & 4 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ mds.parser_end(parser)
- [x] Single line breaks don't end tokens
- [x] Escaping line breaks
- [x] Headers
- [x] code block with triple backticks
- [ ] send language to renderer
- [ ] Code Block with indent
- [x] Code Block with triple backticks
- [x] language attr
- [x] `inline code` with backticks
- [x] *italic* with single asterisks
- [x] **Bold** with double asterisks
Expand All @@ -76,12 +77,13 @@ mds.parser_end(parser)
- [x] ***bold>em*bold**
- [x] *em**em>bold***
- [x] ***bold>em**em*
- [ ] Strikethrough
- [x] Escape characters (e.g. \* or \_ with \\\* or \\\_)
- [x] \[Link\](url)
- [ ] href attr
- [x] href attr
- [x] Escaping escaping bug: \\[Link\\](url)
- [x] Images
- [ ] src attr
- [x] src attr
- [ ] Lists
- [ ] Blockquotes
- [ ] Tables
Expand Down
32 changes: 27 additions & 5 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as mds from "./mds/mds.js"
/**
* @typedef {(string | Test_Renderer_Node)[]} Children
* @typedef {Map<Test_Renderer_Node, Test_Renderer_Node>} Parent_Map
* @typedef {{[key in mds.Attr_Type]?: string}} Node_Attrs
*
* @typedef {object} Test_Renderer_Data
* @property {Test_Renderer_Node} root
Expand All @@ -15,11 +16,13 @@ import * as mds from "./mds/mds.js"
* @typedef {object} Test_Renderer_Node
* @property {mds.Token_Type} type
* @property {Children } children
* @property {Node_Attrs= } attrs
*
* @typedef {mds.Renderer <Test_Renderer_Data>} Test_Renderer
* @typedef {mds.Renderer_Add_Node<Test_Renderer_Data>} Test_Add_Node
* @typedef {mds.Renderer_End_Node<Test_Renderer_Data>} Test_End_Node
* @typedef {mds.Renderer_Add_Text<Test_Renderer_Data>} Test_Add_Text
* @typedef {mds.Renderer_Set_Attr<Test_Renderer_Data>} Test_Set_Attr
*/

/** @returns {Test_Renderer} */
Expand All @@ -33,6 +36,7 @@ function test_renderer() {
add_node: test_renderer_add_node,
end_node: test_renderer_end_node,
add_text: test_renderer_add_text,
set_attr: test_renderer_set_attr,
data : {
parent_map: new Map(),
root: root,
Expand All @@ -41,7 +45,7 @@ function test_renderer() {
}
}
/** @type {Test_Add_Node} */
function test_renderer_add_node(type, data) {
function test_renderer_add_node(data, type) {
/** @type {Test_Renderer_Node} */
const node = {type, children: []}
const parent = data.node
Expand All @@ -50,7 +54,7 @@ function test_renderer_add_node(type, data) {
data.node = node
}
/** @type {Test_Add_Text} */
function test_renderer_add_text(text, data) {
function test_renderer_add_text(data, text) {
if (text === "") return

if (text !== "\n" &&
Expand All @@ -68,6 +72,16 @@ function test_renderer_end_node(data) {
assert.notEqual(parent, undefined)
data.node = /** @type {Test_Renderer_Node} */(parent)
}
/** @type {Test_Set_Attr} */
function test_renderer_set_attr(data, type, value) {
if (value.length === 0) return

if (data.node.attrs === undefined) {
data.node.attrs = {[type]: value}
} else {
data.node.attrs[type] = value
}
}

/**
* @param {string } title
Expand Down Expand Up @@ -238,7 +252,8 @@ test_single_write("Code_Block with language",
"```js\nfoo\n```",
[{
type : mds.Token_Type.Code_Block,
children: ["foo"]
children: ["foo"],
attrs : {[mds.Attr_Type.Lang]: "js"}
}]
)

Expand Down Expand Up @@ -326,6 +341,7 @@ test_single_write("Link",
type : mds.Token_Type.Paragraph,
children: [{
type : mds.Token_Type.Link,
attrs : {[mds.Attr_Type.Href]: "url"},
children: ["title"],
}]
}]
Expand All @@ -337,6 +353,7 @@ test_single_write("Link with code",
type : mds.Token_Type.Paragraph,
children: [{
type : mds.Token_Type.Link,
attrs : {[mds.Attr_Type.Href]: "url"},
children: [{
type : mds.Token_Type.Code_Inline,
children: ["title"],
Expand All @@ -351,6 +368,7 @@ test_single_write("Image",
type : mds.Token_Type.Paragraph,
children: [{
type : mds.Token_Type.Image,
attrs : {[mds.Attr_Type.Src]: "url"},
children: ["title"],
}]
}]
Expand All @@ -362,6 +380,7 @@ test_single_write("Image with code",
type : mds.Token_Type.Paragraph,
children: [{
type : mds.Token_Type.Image,
attrs : {[mds.Attr_Type.Src]: "url"},
children: ["`title`"],
}]
}]
Expand All @@ -373,8 +392,10 @@ test_single_write("Link with Image",
type : mds.Token_Type.Paragraph,
children: [{
type : mds.Token_Type.Link,
attrs : {[mds.Attr_Type.Href]: "href"},
children: [{
type : mds.Token_Type.Image,
attrs : {[mds.Attr_Type.Src]: "src"},
children: ["title"],
}],
}]
Expand Down Expand Up @@ -406,6 +427,7 @@ test_single_write("Un-Escaped link Both",
type : mds.Token_Type.Paragraph,
children: ["\\", {
type : mds.Token_Type.Link,
attrs : {[mds.Attr_Type.Href]: "url"},
children: ["foo\\"],
}]
}]
Expand Down Expand Up @@ -483,5 +505,5 @@ for (const {c, italic, strong} of [{
children: ["em"]
}]
}]
)
}
)
}

0 comments on commit ae5762e

Please sign in to comment.