mdast#FrontmatterContent TypeScript Examples
The following examples show how to use
mdast#FrontmatterContent.
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: decorations.ts From dendron with GNU Affero General Public License v3.0 | 6 votes |
/** Dispatches the correct decorator based on the type of AST node. */
function runDecorator(
opts: DecoratorIn
): DecoratorOut | Promise<DecoratorOut> | undefined {
const { node } = opts;
switch (node.type) {
case DendronASTTypes.BLOCK_ANCHOR:
return decorateBlockAnchor(opts as DecoratorIn<BlockAnchor>);
case DendronASTTypes.HASHTAG:
return decorateHashTag(opts as DecoratorIn<HashTag>);
case DendronASTTypes.FRONTMATTER:
return decorateFrontmatter(opts as DecoratorIn<FrontmatterContent>);
case DendronASTTypes.USERTAG:
return decorateUserTag(opts as DecoratorIn<UserTag>);
case DendronASTTypes.WIKI_LINK:
return decorateWikilink(opts as DecoratorIn<WikiLinkNoteV4>);
case DendronASTTypes.REF_LINK_V2: // fall-through deliberate
return decorateReference(opts as DecoratorIn<NoteRefNoteV4>);
default:
return undefined;
}
}
Example #2
Source File: utils.ts From dendron with GNU Affero General Public License v3.0 | 6 votes |
static isFrontmatter(node: Node): node is FrontmatterContent {
return node.type === DendronASTTypes.FRONTMATTER;
}
Example #3
Source File: diagnostics.ts From dendron with GNU Affero General Public License v3.0 | 5 votes |
export function checkAndWarnBadFrontmatter(
note: NoteProps,
frontmatter: FrontmatterContent
) {
const diagnostics: Diagnostic[] = [];
const errors: IDendronError[] = [];
const range = position2VSCodeRange(frontmatter.position!);
try {
const frontmatterData = YAML.load(frontmatter.value) as any;
if (!_.isString(frontmatterData.id)) {
// Missing id
diagnostics.push(
badFrontmatter({
message: `Note id is missing. ${RESOLVE_MESSAGE_AUTO_ONLY}`,
range,
code: BAD_FRONTMATTER_CODE,
severity: DiagnosticSeverity.Error,
})
);
} else if (frontmatterData.id.match(/^[-_]|[-_]$/)) {
diagnostics.push(
badFrontmatter({
message: `Note id is bad, it will not work in Github publishing. ${RESOLVE_MESSAGE}`,
range,
code: BAD_FRONTMATTER_CODE,
severity: DiagnosticSeverity.Warning,
})
);
} else if (note && frontmatterData.stub && /[^\s]/.test(note.body)) {
// note body has non-whitespace characters in it
diagnostics.push(
badFrontmatter({
message: `This note is not a stub, Please remove the stub property or update it to false`,
range,
code: NOT_A_STUB,
severity: DiagnosticSeverity.Warning,
})
);
}
} catch (err) {
errors.push(
new DendronError({
message: "failed to parse frontmatter",
payload: err,
})
);
diagnostics.push(
badFrontmatter({
message: `The frontmatter is broken. ${RESOLVE_MESSAGE}`,
range,
severity: DiagnosticSeverity.Error,
})
);
}
return { diagnostics, errors };
}
Example #4
Source File: frontmatter.ts From dendron with GNU Affero General Public License v3.0 | 5 votes |
decorateFrontmatter: Decorator<
FrontmatterContent,
DecorationsForDecorateFrontmatter
> = async (opts) => {
const { node: frontmatter, engine } = opts;
const { value: contents, position } = frontmatter;
// Decorate the timestamps
const entries = contents.split("\n");
const lineOffset =
point2VSCodePosition(position.start).line +
1; /* `---` line of frontmatter */
const timestampDecorations = entries
.map((entry, line): undefined | DecorationTimestamp => {
const match = NoteUtils.RE_FM_UPDATED_OR_CREATED.exec(entry);
if (!_.isNull(match) && match.groups?.timestamp) {
const timestamp = _.toInteger(match.groups.timestamp);
const decoration: DecorationTimestamp = {
range: {
start: {
line: line + lineOffset,
character: match.groups.beforeTimestamp.length,
},
end: {
line: line + lineOffset,
character:
match.groups.beforeTimestamp.length +
match.groups.timestamp.length,
},
},
timestamp,
type: DECORATION_TYPES.timestamp,
};
return decoration;
}
return undefined;
})
.filter(isNotUndefined);
// Decorate the frontmatter tags
const tags = getFrontmatterTags(parseFrontmatter(contents));
const tagDecorations: DecorationHashTag[] = [];
const errors: IDendronError[] = [];
await Promise.all(
tags.map(async (tag) => {
const { errors, decorations } = await decorateTag({
fname: `${TAGS_HIERARCHY}${tag.value}`,
position: tag.position,
lineOffset,
engine,
});
tagDecorations.push(...decorations);
errors.push(...errors);
})
);
const decorations: DecorationsForDecorateFrontmatter[] = [
...tagDecorations,
...timestampDecorations,
];
return {
decorations,
errors,
};
}
Example #5
Source File: decorations.ts From dendron with GNU Affero General Public License v3.0 | 4 votes |
/** Get all decorations within the visible ranges for given note. */
export async function runAllDecorators(
opts: Omit<GetDecorationsOpts, "id"> & { note: NoteProps; engine: DEngine }
) {
const { note, ranges, engine } = opts;
const allDecorations: Decoration[] = [];
const allDiagnostics: Diagnostic[] = [];
const allErrors: IDendronError[] = [];
const proc = MDUtilsV5.procRemarkParse(
{
mode: ProcMode.FULL,
parseOnly: true,
},
{
dest: DendronASTDest.MD_DENDRON,
engine,
vault: note.vault,
fname: note.fname,
}
);
for (const { range, text } of ranges) {
if (text.length > ConfigUtils.getWorkspace(engine.config).maxNoteLength) {
return {
errors: [
new DendronError({
message: `Stopping decorations because visible range is too large. Unless you have a massive screen or really long lines of text, this may be a bug.`,
payload: {
maxNoteLength: ConfigUtils.getWorkspace(engine.config)
.maxNoteLength,
textLength: text.length,
},
}),
],
};
}
const tree = proc.parse(text);
// eslint-disable-next-line no-await-in-loop
await MdastUtils.visitAsync(tree, [], async (nodeIn) => {
// This was parsed, it must have a position
const node = nodeIn as NonOptional<DendronASTNode, "position">;
// Need to update node position with the added offset from the range
const decoratorOut = await runDecorator({
...opts,
node,
note,
noteText: text,
});
if (decoratorOut) {
const { decorations, errors } = decoratorOut;
allDecorations.push(
...decorations.map((decoration) => {
// Add the offset from the start of the range so these decorations match up in the original document
decoration.range = offsetRange(decoration.range, {
line: range.start.line,
});
return decoration;
})
);
if (errors) allErrors.push(...errors);
}
});
}
// Check for frontmatter diagnostics. Diagnostics always run on the whole note because they need to be active even when they are not visible.
let frontmatter: FrontmatterContent | undefined;
const fullTree = proc.parse(opts.text);
visit(fullTree, ["yaml"], (node: FrontmatterContent) => {
frontmatter = node;
return false; // stop iterating
});
if (_.isUndefined(frontmatter)) {
allDiagnostics.push(warnMissingFrontmatter());
} else {
const { diagnostics, errors } = checkAndWarnBadFrontmatter(
note,
frontmatter
);
allDiagnostics.push(...diagnostics);
if (errors) allErrors.push(...errors);
}
return {
allDecorations,
allDiagnostics,
allErrors,
};
}