mdast#HTML TypeScript Examples
The following examples show how to use
mdast#HTML.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.ts From dendron with GNU Affero General Public License v3.0 | 6 votes |
static isHTML(node: Node): node is HTML {
return node.type === DendronASTTypes.HTML;
}
Example #2
Source File: remark.ts From vite-plugin-md-preview with MIT License | 5 votes |
export function remarkVue(options: RemarkVueOptions): Plugin {
const { file, root, highlighter, remove, update } = options
const resolve = (...args: string[]) => {
let ret = path.resolve(path.dirname(file), ...args)
ret = path.relative(root, ret)
return `/${ret}`
}
function transformer(tree): Transformer {
const oldBlocks = fileCodeMap.get(file) || []
const blocks: CodeBlock[] = []
visit(tree, 'code', (node: Code, i: number, parent: Parent) => {
const attrs = (node.meta || '').split(' ').reduce((prev, curr) => {
const [key, value] = curr.split('=')
if (typeof value === 'undefined') {
prev[key] = true
} else {
prev[key] = value
}
return prev
}, {} as Record<string, string | boolean>)
if (node.lang === 'vue' && attrs['preview']) {
const name = `VueCode${md5(file).substr(0, 8)}I${i}`
const component = typeof attrs['preview'] === 'string' ? attrs['preview'] : 'VueCode'
const code = highlighter(node.value)
blocks.push({ name, path: resolve(`./${name}.vue`), code: node.value })
const demoNode: HTML = {
type: 'html',
value: `<${component} source="${encodeURIComponent(code)}">
<${name} />
</${component}>`,
}
parent.children.splice(i, 1, demoNode)
}
})
const names = blocks.map(i => i.name)
remove(oldBlocks)
fileCodeMap.set(file, names)
update(blocks)
const imports = names.reduce((prev, curr) => {
return `${prev}import ${curr} from "${resolve(`./${curr}.vue`)}"\n`
}, '')
const script = `<script setup>\n${imports}</script>`
tree.children.splice(0, 0, { type: 'html', value: script })
return tree
}
return transformer
}
Example #3
Source File: backlinksHover.ts From dendron with GNU Affero General Public License v3.0 | 4 votes |
/**
* Unified processor for rendering text in the backlinks hover control. This
* processor returns a transformer that does the following:
* 1. Highlights the backlink text
* 2. Changes the backlink node away from a wikilink/noteref to prevent the
* backlink text from being altered
* 3. Adds contextual " --- line # ---" information
* 4. Removes all elements that lie beyond the contextual lines limit of the
* backlink
* @param this
* @param _opts
* @returns
*/
export function backlinksHover(
this: Unified.Processor,
_opts?: BacklinkOpts
): Transformer {
function transformer(tree: Node, _file: VFile) {
if (!_opts) {
return;
}
const backlinkLineNumber = _opts.location.start.line;
const lowerLineLimit = backlinkLineNumber - _opts.linesOfContext;
const upperLineLimit = backlinkLineNumber + _opts.linesOfContext;
/**
* The last line of the YAML frontmatter counts as line 0.
*/
let documentBodyStartLine = 0;
let documentEndLine = 0;
// In the first visit, set the beginning and end markers of the document.
visit(tree, [DendronASTTypes.ROOT], (node, _index, _parent) => {
if (RemarkUtils.isRoot(node)) {
documentEndLine = node.position?.end.line ?? 0;
// Count the last line of YAML as the 0 indexed start of the body of the document
if (RemarkUtils.isYAML(node.children[0])) {
documentBodyStartLine = node.children[0].position?.end.line ?? 0;
}
}
});
// In the second visit, modify the wikilink/ref/candidate that is the
// backlink to highlight it and to change its node type so that it appears
// in its text form to the user (we don't want to convert a noteref backlink
// into its reffed contents for example)
visit(tree, (node, index, parent) => {
if (!node.position) {
return;
}
// Remove all elements that fall outside of the context boundary limits
if (
node.position.end.line < lowerLineLimit ||
node.position.start.line > upperLineLimit
) {
if (parent) {
parent.children.splice(index, 1);
return index;
}
}
// Make special adjustments for preceding and succeeding code blocks that
// straddle the context boundaries
if (node.position && node.position.start.line < lowerLineLimit) {
if (RemarkUtils.isCode(node)) {
const lines = node.value.split("\n");
node.value = lines
.slice(
Math.max(0, lowerLineLimit - node.position.start.line - 2), // Adjust an offset to account for the code block ``` lines
lines.length - 1
)
.join("\n");
}
} else if (node.position && node.position.end.line > upperLineLimit) {
if (RemarkUtils.isCode(node)) {
const lines = node.value.split("\n");
node.value = lines
.slice(
0,
upperLineLimit - node.position.end.line + 1 // Adjust an offset of 1 to account for the code block ``` line
)
.join("\n");
}
}
// Do the node replacement for wikilinks, node refs, and text blocks when
// it's a candidate link
if (RemarkUtils.isWikiLink(node)) {
if (
backlinkLineNumber === node.position?.start.line &&
node.position.start.column === _opts.location.start.column
) {
let wiklinkText = `${node.value}`;
if (node.data.anchorHeader) {
wiklinkText += `#${node.data.anchorHeader}`;
}
(node as Node).type = DendronASTTypes.HTML;
(node as unknown as HTML).value = getHTMLToHighlightText(
`[[${wiklinkText}]]`
);
}
} else if (RemarkUtils.isNoteRefV2(node)) {
if (
backlinkLineNumber === node.position?.start.line &&
node.position.start.column === _opts.location.start.column
) {
let noteRefText = `${node.value}`;
if (node.data.link.data.anchorStart) {
noteRefText += `#${node.data.link.data.anchorStart}`;
}
if (node.data.link.data.anchorEnd) {
noteRefText += `:#${node.data.link.data.anchorEnd}`;
}
(node as Node).type = DendronASTTypes.HTML;
(node as unknown as HTML).value = getHTMLToHighlightText(
`![[${noteRefText}]]`
);
}
} else if (RemarkUtils.isText(node)) {
// If the backlink location falls within the range of this text node,
// then proceed with formatting. Note: a text node can span multiple
// lines if it ends with a '\n'
if (
backlinkLineNumber === node.position?.start.line &&
(node.position.end.column > _opts.location.start.column ||
node.position.end.line > _opts.location.start.line) &&
(node.position.start.column < _opts.location.end.column ||
node.position.start.line < _opts.location.end.line)
) {
const contents = node.value;
const prefix = contents.substring(0, _opts.location.start.column - 1);
const candidate = contents.substring(
_opts.location.start.column - 1,
_opts.location.end.column - 1
);
const suffix = contents.substring(
_opts.location.end.column - 1,
contents.length
);
(node as Node).type = DendronASTTypes.HTML;
(node as unknown as HTML).value = `${prefix}${getHTMLToHighlightText(
candidate
)}${suffix}`;
return index;
}
} else if (RemarkUtils.isHashTag(node) || RemarkUtils.isUserTag(node)) {
if (
backlinkLineNumber === node.position?.start.line &&
node.position.start.column === _opts.location.start.column
) {
(node as Node).type = DendronASTTypes.HTML;
(node as unknown as HTML).value = getHTMLToHighlightText(node.value);
}
}
return;
});
// In the third visit, add the contextual line marker information
visit(tree, [DendronASTTypes.ROOT], (node, _index, _parent) => {
if (!RemarkUtils.isRoot(node) || !node.position) {
return;
}
const lowerBoundText =
lowerLineLimit <= documentBodyStartLine
? "Start of Note"
: `Line ${lowerLineLimit - 1}`;
const lowerBoundParagraph: Paragraph = {
type: DendronASTTypes.PARAGRAPH,
children: [
{
type: DendronASTTypes.HTML,
value: `--- <i>${lowerBoundText}</i> ---`,
},
],
};
node.children.unshift(lowerBoundParagraph);
const upperBoundText =
upperLineLimit >= documentEndLine
? "End of Note"
: `Line ${upperLineLimit + 1}`;
const upperBoundParagraph: Paragraph = {
type: DendronASTTypes.PARAGRAPH,
children: [
{
type: DendronASTTypes.HTML,
value: `--- <i>${upperBoundText}</i> ---`,
},
],
};
node.children.push(upperBoundParagraph);
});
}
return transformer;
}