mdast#Content TypeScript Examples
The following examples show how to use
mdast#Content.
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: case.ts From reskript with MIT License | 6 votes |
extractMeta = async (metaNode: Content): Promise<PlayCaseMeta> => {
const parsedMeta: PlayCaseMeta = metaNode.type === 'list'
? parseMeta(metaNode)
: {createAt: '', createBy: '', lastRunAt: '', lastRunBy: ''};
const now = new Date();
const user = await currentUserName();
if (!parsedMeta.createAt) {
parsedMeta.createAt = formatTime(now);
parsedMeta.createBy = user;
}
if (!parsedMeta.lastRunAt) {
parsedMeta.lastRunAt = formatTime(now);
parsedMeta.lastRunBy = user;
}
return parsedMeta;
}
Example #2
Source File: case.ts From reskript with MIT License | 6 votes |
parseToCase = async ([heading, meta, ...nodes]: Content[]): Promise<PlayCase | null> => {
if (heading.type !== 'heading' || heading.depth !== 2) {
return null;
}
const replCodeBlock = findReplCodeBlock(nodes);
if (!replCodeBlock) {
return null;
}
const description = stringifyNodesToMarkdown(nodes.filter(v => v !== replCodeBlock));
const metaInfo = await extractMeta(meta);
return {
name: (heading.children[0] as Text).value,
description: description.trim(),
code: (replCodeBlock as Code).value,
...metaInfo,
};
}
Example #3
Source File: case.ts From reskript with MIT License | 6 votes |
splitToCaseNodes = (markdown: string): Content[][] => {
const root = parser.parse(markdown);
const {saved, workingInProgress} = root.children.reduce(
(context, node) => {
// 每个二级标题是一个用例
if (node.type === 'heading' && node.depth === 2) {
context.saved.push(context.workingInProgress);
context.workingInProgress = [node];
}
else {
context.workingInProgress.push(node);
}
return context;
},
{saved: [], workingInProgress: []} as ParseContext
);
return [...saved, workingInProgress];
}
Example #4
Source File: case.ts From reskript with MIT License | 5 votes |
stringifyNodesToMarkdown = (nodes: Content[]): string => {
const root: Root = {
type: 'root',
children: nodes,
};
return serializer.stringify(root);
}
Example #5
Source File: case.ts From reskript with MIT License | 5 votes |
findReplCodeBlock = (nodes: Content[]) => findLast(v => v.type === 'code' && v.lang === 'jsx', nodes)
Example #6
Source File: case.ts From reskript with MIT License | 5 votes |
isListItem = (node: Content) => node.type === 'listItem'
Example #7
Source File: case.ts From reskript with MIT License | 5 votes |
isMatchCaseName = (nodes: Content[], name: string): boolean => {
const [heading] = nodes;
return heading.type === 'heading' && heading.depth === 2 && (heading.children[0] as Text).value === name;
}
Example #8
Source File: backlinks.ts From dendron with GNU Affero General Public License v3.0 | 4 votes |
plugin: Plugin = function (this: Unified.Processor) {
const proc = this;
function transformer(tree: Node): void {
const root = tree as Root;
let fname: string;
let vault: DVault;
let dest: DendronASTDest;
let insideNoteRef: boolean | undefined;
let config: IntermediateDendronConfig;
let engine: DEngineClient;
if (MDUtilsV5.isV5Active(proc)) {
({ fname, vault, dest, insideNoteRef, config, engine } =
MDUtilsV5.getProcData(proc));
} else {
({ fname, vault, dest, insideNoteRef, config } =
MDUtilsV4.getDendronData(proc));
engine = MDUtilsV4.getEngineFromProc(proc).engine;
}
// Don't show backlinks for the following cases:
// - we are inside a note ref
// - the destination isn't HTML
// - the note can't be found
// - neableChild links is toggled off
// enableBackLinks is set to false
if (!fname || insideNoteRef) {
return;
}
if (dest !== DendronASTDest.HTML) {
return;
}
const note = NoteUtils.getNoteByFnameFromEngine({ fname, vault, engine });
if (_.isUndefined(note)) {
return;
}
if (
ConfigUtils.getEnableBackLinks(config, {
note,
shouldApplyPublishingRules: MDUtilsV5.shouldApplyPublishingRules(proc),
}) === false
) {
return;
}
const backlinks = _.uniqBy(
(note?.links || []).filter((ent) => ent.type === "backlink"),
(ent) => ent.from.fname + (ent.from.vaultName || "")
);
const backlinksToPublish = _.filter(backlinks, (backlink) => {
const vaultName = backlink.from.vaultName!;
const vault = VaultUtils.getVaultByName({
vaults: engine.vaults,
vname: vaultName,
})!;
const note = NoteUtils.getNoteByFnameFromEngine({
fname: backlink.from.fname!,
engine,
vault,
});
if (!note) {
return false;
}
const out = SiteUtils.canPublish({
note,
engine,
config: engine.config,
});
return out;
});
if (!_.isEmpty(backlinksToPublish)) {
root.children.push({
type: "thematicBreak",
});
root.children.push(u("strong", [{ type: "text", value: "Backlinks" }]));
root.children.push(
list(
"unordered",
backlinksToPublish.map((mdLink) => {
let alias;
const note = NoteUtils.getNoteByFnameFromEngine({
fname: mdLink.from.fname!,
vault: VaultUtils.getVaultByName({
vaults: engine.vaults,
vname: mdLink.from.vaultName!,
})!,
engine,
});
if (note) {
alias =
note.title +
(engine.vaults.length > 1
? ` (${mdLink.from.vaultName!})`
: "");
} else {
alias = `Unable to find backlinked note ${mdLink.from.fname!}.`;
}
return listItem(
paragraph({
type: DendronASTTypes.WIKI_LINK,
value: mdLink.from.fname,
data: {
alias,
vaultName: mdLink.from.vaultName!,
},
children: [],
} as WikiLinkNoteV4)
);
})
) as Content
);
}
// end transformer
}
return transformer;
}
Example #9
Source File: hierarchies.ts From dendron with GNU Affero General Public License v3.0 | 4 votes |
plugin: Plugin = function (this: Unified.Processor, _opts?: PluginOpts) {
const proc = this;
const { config } = MDUtilsV5.getProcData(this);
let hierarchyDisplayTitle = config?.hierarchyDisplayTitle || "Children";
let hierarchyDisplay = config?.hierarchyDisplay;
if (MDUtilsV5.shouldApplyPublishingRules(proc)) {
const hierarchyConfigForPublishing =
ConfigUtils.getHierarchyDisplayConfigForPublishing(config);
hierarchyDisplay = hierarchyConfigForPublishing.hierarchyDisplay;
if (!_.isUndefined(hierarchyConfigForPublishing.hierarchyDisplayTitle)) {
hierarchyDisplayTitle =
hierarchyConfigForPublishing.hierarchyDisplayTitle;
}
}
if (hierarchyDisplay === undefined) hierarchyDisplay = true;
function transformer(tree: Node): void {
const root = tree as Root;
const { fname, vault, dest, config, insideNoteRef } =
MDUtilsV4.getDendronData(proc);
let addedBreak = false;
if (dest !== DendronASTDest.HTML) {
return;
}
// TODO: remove
if (!hierarchyDisplay) {
return;
}
function addBreak() {
if (addedBreak) return;
root.children.push({
type: "thematicBreak",
});
addedBreak = true;
}
function addFootnotes() {
/** Maps footnote identifiers to their definitions. */
const footnotes = new Map(
RemarkUtils.extractFootnoteDefs(root).map((definition) => [
definition.identifier,
definition,
])
);
/** All footnote definitions that have been referenced in this document. */
const usedFootnotes = new Set<FootnoteDefinition>();
visit(
root,
[DendronASTTypes.FOOTNOTE_REFERENCE],
(reference: FootnoteReference, index, parent) => {
const definition = footnotes.get(reference.identifier);
if (definition && parent) {
parent.children[index] = footnote2html(reference);
usedFootnotes.add(definition);
}
}
);
if (usedFootnotes.size > 0) {
addBreak();
root.children.push(heading(2, text("Footnotes")) as Content);
const footnoteItems: Node[] = [];
for (const definition of usedFootnotes) {
footnoteItems.push(listItem(footnoteDef2html(definition)));
}
root.children.push(list("ordered", footnoteItems) as Content);
}
}
if (!fname || insideNoteRef) {
// Even inside a note ref, render footnotes because we want them in there too
addFootnotes();
return;
}
const { engine } = MDUtilsV4.getEngineFromProc(proc);
const note = NoteUtils.getNoteByFnameFromEngine({
fname,
engine,
vault: vault!,
});
// check if v5 is active
if (MDUtilsV5.isV5Active(proc)) {
const resp = MDUtilsV5.getProcData(proc);
hierarchyDisplay = ConfigUtils.getEnableChildLinks(resp.config, { note });
}
/** Add frontmatter tags, if any, ahead of time. This way wikilink compiler will pick them up and render them. */
function addTags() {
const shouldApplyPublishRules =
MDUtilsV5.shouldApplyPublishingRules(proc);
const enableFrontmatterTags = ConfigUtils.getEnableFrontmatterTags({
config,
shouldApplyPublishRules,
});
const enableHashesForFMTags = ConfigUtils.getEnableHashesForFMTags({
config,
shouldApplyPublishRules,
});
if (
enableFrontmatterTags !== false &&
note?.tags &&
note.tags.length > 0
) {
addBreak();
root.children.push(heading(2, text("Tags")) as Content);
const tags = _.isString(note.tags) ? [note.tags] : note.tags;
const tagLinks = _.sortBy(
_.map(tags, (tag) =>
listItem(
paragraph(
frontmatterTag2WikiLinkNoteV4(tag, enableHashesForFMTags)
)
)
),
["custom.nav_order", "title"]
);
root.children.push(list("ordered", tagLinks) as Content);
}
}
function addChildren() {
// don't include if collection present
if (!note || note.children.length <= 0 || note?.custom?.has_collection) {
return;
}
if (
_.isBoolean(note.custom?.hierarchyDisplay) &&
!note.custom.hierarchyDisplay
) {
return;
}
const children = HierarchyUtils.getChildren({
skipLevels: note.custom?.skipLevels || 0,
note,
notes: engine.notes,
})
.filter((note) => SiteUtils.canPublish({ note, engine, config }))
.filter(
(note) =>
_.isUndefined(note.custom?.nav_exclude) || !note.custom?.nav_exclude
);
if (!_.isEmpty(children)) {
addBreak();
root.children.push(
u("strong", [{ type: "text", value: hierarchyDisplayTitle }])
);
root.children.push(
list(
"ordered",
_.sortBy(children, ["custom.nav_order", "title"]).map((note) => {
return listItem(
paragraph({
type: DendronASTTypes.WIKI_LINK,
value: note.fname,
data: {
alias: note.title,
vaultName: VaultUtils.getName(note.vault),
},
children: [],
} as WikiLinkNoteV4)
);
})
) as Content
);
}
}
// Will appear on page in this order
if (hierarchyDisplay) {
addChildren();
}
addTags();
addFootnotes();
// end transformer
}
return transformer;
}
Example #10
Source File: descriptionFormatter.ts From prettier-plugin-jsdoc with MIT License | 4 votes |
/**
* Trim, make single line with capitalized text. Insert dot if flag for it is
* set to true and last character is a word character
*
* @private
*/
function formatDescription(
tag: string,
text: string,
options: AllOptions,
formatOptions: FormatOptions,
): string {
if (!text) return text;
const { printWidth } = options;
const { tagStringLength = 0, beginningSpace } = formatOptions;
/**
* change list with dash to dot for example:
* 1- a thing
*
* to
*
* 1. a thing
*/
text = text.replace(/^(\d+)[-][\s|]+/g, "$1. "); // Start
text = text.replace(/\n+(\s*\d+)[-][\s]+/g, "\n$1. ");
const fencedCodeBlocks = text.matchAll(/```\S*?\n[\s\S]+?```/gm);
const indentedCodeBlocks = text.matchAll(
/^\r?\n^(?:(?:(?:[ ]{4}|\t).*(?:\r?\n|$))+)/gm,
);
const allCodeBlocks = [...fencedCodeBlocks, ...indentedCodeBlocks];
const tables: string[] = [];
text = text.replace(
/((\n|^)\|[\s\S]*?)((\n[^|])|$)/g,
(code, _1, _2, _3, _, offs: number) => {
// If this potential table is inside a code block, don't touch it
for (const block of allCodeBlocks) {
if (
block.index !== undefined &&
block.index <= offs + 1 &&
offs + code.length + 1 <= block.index + block[0].length
) {
return code;
}
}
code = _3 ? code.slice(0, -1) : code;
tables.push(code);
return `\n\n${TABLE}\n\n${_3 ? _3.slice(1) : ""}`;
},
);
if (
options.jsdocCapitalizeDescription &&
!TAGS_PEV_FORMATE_DESCRIPTION.includes(tag)
) {
text = capitalizer(text);
}
text = `${tagStringLength ? `${"!".repeat(tagStringLength - 1)}?` : ""}${
text.startsWith("```") ? "\n" : ""
}${text}`;
let tableIndex = 0;
const rootAst = fromMarkdown(text);
function stringifyASTWithoutChildren(
mdAst: Content | Root,
intention: string,
parent: Content | Root | null,
) {
if (mdAst.type === "inlineCode") {
return `\`${mdAst.value}\``;
}
if (mdAst.type === "code") {
let result = mdAst.value || "";
let _intention = intention;
if (result) {
// Remove two space from lines, maybe added previous format
if (mdAst.lang) {
const supportParsers = parserSynonyms(mdAst.lang.toLowerCase());
const parser = supportParsers?.includes(options.parser as any)
? options.parser
: supportParsers?.[0] || mdAst.lang;
result = formatCode(result, intention, {
...options,
parser,
jsdocKeepUnParseAbleExampleIndent: true,
});
} else if (options.jsdocPreferCodeFences || false) {
result = formatCode(result, _intention, {
...options,
jsdocKeepUnParseAbleExampleIndent: true,
});
} else {
_intention = intention + " ".repeat(4);
result = formatCode(result, _intention, {
...options,
jsdocKeepUnParseAbleExampleIndent: true,
});
}
}
const addFence = options.jsdocPreferCodeFences || !!mdAst.lang;
result = addFence ? result : result.trimEnd();
return result
? addFence
? `\n\n${_intention}\`\`\`${mdAst.lang || ""}${result}\`\`\``
: `\n${result}`
: "";
}
if ((mdAst as Text).value === TABLE) {
if (parent) {
(parent as any).costumeType = TABLE;
}
if (tables.length > 0) {
let result = tables?.[tableIndex] || "";
tableIndex++;
if (result) {
result = format(result, {
...options,
parser: "markdown",
}).trim();
}
return `${
result
? `\n\n${intention}${result.split("\n").join(`\n${intention}`)}`
: (mdAst as Text).value
}`;
}
}
if (mdAst.type === "break") {
return `\\\n`;
}
return ((mdAst as Text).value ||
(mdAst as Link).title ||
(mdAst as Image).alt ||
"") as string;
}
function stringyfy(
mdAst: Content | Root,
intention: string,
parent: Content | Root | null,
): string {
if (!Array.isArray((mdAst as Root).children)) {
return stringifyASTWithoutChildren(mdAst, intention, parent);
}
return ((mdAst as Root).children as Content[])
.map((ast, index) => {
switch (ast.type) {
case "listItem": {
let _listCount = `\n${intention}- `;
// .replace(/((?!(^))\n)/g, "\n" + _intention);
if (typeof (mdAst as List).start === "number") {
const count = index + (((mdAst as List).start as number) ?? 1);
_listCount = `\n${intention}${count}. `;
}
const _intention = intention + " ".repeat(_listCount.length - 1);
const result = stringyfy(ast, _intention, mdAst).trim();
return `${_listCount}${result}`;
}
case "list": {
let end = "";
/**
* Add empty line after list if that is end of description
* issue: {@link https://github.com/hosseinmd/prettier-plugin-jsdoc/issues/98}
*/
if (
tag !== DESCRIPTION &&
mdAst.type === "root" &&
index === mdAst.children.length - 1
) {
end = "\n";
}
return `\n${stringyfy(ast, intention, mdAst)}${end}`;
}
case "paragraph": {
const paragraph = stringyfy(ast, intention, parent);
if ((ast as any).costumeType === TABLE) {
return paragraph;
}
return `\n\n${paragraph
/**
* Break by backslash\
* issue: https://github.com/hosseinmd/prettier-plugin-jsdoc/issues/102
*/
.split("\\\n")
.map((_paragraph) => {
const links: string[] = [];
// Find jsdoc links and remove spaces
_paragraph = _paragraph.replace(
/{@(link|linkcode|linkplain)[\s](([^{}])*)}/g,
(_, tag: string, link: string) => {
links.push(link);
return `{@${tag}${"_".repeat(link.length)}}`;
},
);
_paragraph = _paragraph.replace(/\s+/g, " "); // Make single line
if (
options.jsdocCapitalizeDescription &&
!TAGS_PEV_FORMATE_DESCRIPTION.includes(tag)
)
_paragraph = capitalizer(_paragraph);
if (options.jsdocDescriptionWithDot)
_paragraph = _paragraph.replace(/([\w\p{L}])$/u, "$1."); // Insert dot if needed
let result = breakDescriptionToLines(
_paragraph,
printWidth,
intention,
);
// Replace links
result = result.replace(
/{@(link|linkcode|linkplain)([_]+)}/g,
(original: string, tag: string, underline: string) => {
const link = links[0];
if (link.length === underline.length) {
links.shift();
return `{@${tag} ${link}}`;
}
return original;
},
);
return result;
})
.join("\\\n")}`;
}
case "strong": {
return `**${stringyfy(ast, intention, mdAst)}**`;
}
case "emphasis": {
return `_${stringyfy(ast, intention, mdAst)}_`;
}
case "heading": {
return `\n\n${intention}${"#".repeat(ast.depth)} ${stringyfy(
ast,
intention,
mdAst,
)}`;
}
case "link":
case "image": {
return `[${stringyfy(ast, intention, mdAst)}](${ast.url})`;
}
case "linkReference": {
return `[${stringyfy(ast, intention, mdAst)}][${ast.label}]`;
}
case "definition": {
return `\n\n[${ast.label}]: ${ast.url}`;
}
case "blockquote": {
const paragraph = stringyfy(ast, "", mdAst);
return `${intention}> ${paragraph
.trim()
.replace(/(\n+)/g, `$1${intention}> `)}`;
}
}
return stringyfy(ast, intention, mdAst);
})
.join("");
}
let result = stringyfy(rootAst, beginningSpace, null);
result = result.replace(/^[\s\n]+/g, "");
result = result.replace(/^([!]+\?)/g, "");
return result;
}