language = {
const textParser = (r) =>
P.regex(/[A-Za-z'\-":!?,.]+/).map((value) => ({
type: "text",
value
}));
const boldParser = (r) =>
P.seqObj(P.string("**"), ["children", r.value], P.string("**")).map(
({ children }) => ({
type: "bold",
children
})
);
const italicParser = (r) =>
P.seqObj(P.string("_"), ["children", r.value], P.string("_")).map(
({ children }) => ({
type: "italic",
children
})
);
const whitespaceParser = (r) => P.regex(/ +/).result({ type: "whitespace" });
const newlineParser = (r) => P.regex(/\n/).result({ type: "newline" });
const urlRegex = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/;
const markdownUrlParser = (r) =>
P.seqObj(
P.string("["),
["children", r.phrasing.many()],
P.string("]("),
["href", P.regex(urlRegex)],
P.string(")")
).map(({ children, href }) => ({
type: "url",
children,
href
}));
const plainURLParser = P.regex(urlRegex).map((result) => ({
type: "url",
children: [{ type: "text", value: result }],
href: result
}));
const urlParser = (r) => P.alt(markdownUrlParser(r), plainURLParser);
const language = P.createLanguage({
phrasing: (r) => P.alt(r.whitespace, r.bold, r.italic, r.text),
whitespace: whitespaceParser,
newline: newlineParser,
bold: boldParser,
italic: italicParser,
text: textParser,
url: urlParser,
value: (r) => P.alt(r.newline, r.url, r.phrasing).many()
});
return language;
}