update to support fenced code

This commit is contained in:
Luke Boswell 2023-03-08 17:30:30 +11:00
parent a87794e7b2
commit 890f3db10a
No known key found for this signature in database
GPG key ID: F6DB3C9DB47377B0
10 changed files with 828 additions and 724 deletions

View file

@ -677,7 +677,7 @@ fn doc_url<'a>(
module_name = symbol.module_string(interns);
}
Err(_) => {
dbg!(scope);
// TODO return Err here
panic!(
"Tried to generate an automatic link in docs for symbol `{}`, but that symbol was not in scope in this module.",
@ -806,65 +806,24 @@ fn markdown_to_html(
let markdown_options = pulldown_cmark::Options::ENABLE_TABLES;
let mut in_code_block = false;
let mut in_code_block: Option<CowStr> = None;
let mut to_highlight = String::new();
let mut docs_parser = vec![];
let (_, _) = pulldown_cmark::Parser::new_with_broken_link_callback(
let parser = pulldown_cmark::Parser::new_with_broken_link_callback(
markdown,
markdown_options,
Some(&mut broken_link_callback),
)
.fold((0, 0), |(start_quote_count, end_quote_count), event| {
match &event {
// Replace this sequence (`>>>` syntax):
// Start(BlockQuote)
// Start(BlockQuote)
// Start(BlockQuote)
// Start(Paragraph)
// For `Start(CodeBlock(Fenced(Borrowed("roc"))))`
Event::Start(BlockQuote) => {
docs_parser.push(event);
(start_quote_count + 1, 0)
);
for event in parser {
match event {
Event::Code(cow_str) => {
let highlighted_html =
roc_highlight::highlight_roc_code_inline(cow_str.to_string().as_str());
docs_parser.push(Event::Html(CowStr::from(highlighted_html)));
}
Event::Start(Paragraph) => {
if start_quote_count == 3 {
docs_parser.pop();
docs_parser.pop();
docs_parser.pop();
docs_parser.push(Event::Start(CodeBlock(CodeBlockKind::Fenced(
CowStr::Borrowed("roc"),
))));
} else {
docs_parser.push(event);
}
(0, 0)
}
// Replace this sequence (`>>>` syntax):
// End(Paragraph)
// End(BlockQuote)
// End(BlockQuote)
// End(BlockQuote)
// For `End(CodeBlock(Fenced(Borrowed("roc"))))`
Event::End(Paragraph) => {
docs_parser.push(event);
(0, 1)
}
Event::End(BlockQuote) => {
if end_quote_count == 3 {
docs_parser.pop();
docs_parser.pop();
docs_parser.pop();
docs_parser.push(Event::End(CodeBlock(CodeBlockKind::Fenced(
CowStr::Borrowed("roc"),
))));
(0, 0)
} else {
docs_parser.push(event);
(0, end_quote_count + 1)
}
}
Event::End(Link(LinkType::ShortcutUnknown, _url, _title)) => {
Event::End(Link(LinkType::ShortcutUnknown, ref _url, ref _title)) => {
// Replace the preceding Text node with a Code node, so it
// renders as the equivalent of [`List.len`] instead of [List.len]
match docs_parser.pop() {
@ -878,39 +837,61 @@ fn markdown_to_html(
}
docs_parser.push(event);
(start_quote_count, end_quote_count)
}
Event::Start(CodeBlock(_)) => {
in_code_block = true;
(0, 0)
Event::Start(CodeBlock(CodeBlockKind::Fenced(cow_str))) => {
in_code_block = Some(cow_str);
}
Event::End(CodeBlock(_)) => {
if in_code_block {
let highlighted_html = roc_highlight::highlight_roc_code(&to_highlight);
docs_parser.push(pulldown_cmark::Event::Html(pulldown_cmark::CowStr::from(
highlighted_html,
)));
to_highlight = String::new();
in_code_block = false;
match in_code_block {
Some(cow_str) => {
if cow_str.contains("unchecked") {
// TODO HANDLE UNCHECKED
let highlighted_html = roc_highlight::highlight_roc_code(&to_highlight);
docs_parser.push(Event::Html(CowStr::from(highlighted_html)));
} else if cow_str.contains("repl") {
// TODO HANDLE REPL
let highlighted_html = roc_highlight::highlight_roc_code(&to_highlight);
docs_parser.push(Event::Html(CowStr::from(highlighted_html)));
} else {
// TODO HANDLE CHECKING BY DEFAULT
let highlighted_html = roc_highlight::highlight_roc_code(&to_highlight);
docs_parser.push(Event::Html(CowStr::from(highlighted_html)));
}
}
None => {
// Indented code block
let highlighted_html = roc_highlight::highlight_roc_code(&to_highlight);
docs_parser.push(Event::Html(CowStr::from(highlighted_html)));
}
}
(0, 0)
// Reset codeblock buffer
to_highlight = String::new();
in_code_block = None;
// Push Event::End(CodeBlock)
docs_parser.push(event);
}
Event::Text(t) => {
if in_code_block {
// If we're in a code block, build up the string of text
to_highlight.push_str(t);
} else {
docs_parser.push(event);
match in_code_block {
Some(_) => {
// If we're in a code block, build up the string of text
to_highlight.push_str(&t);
}
None => {
docs_parser.push(Event::Text(t));
}
}
(0, 0)
}
_ => {
docs_parser.push(event);
(0, 0)
e => {
docs_parser.push(e);
}
}
});
}
pulldown_cmark::html::push_html(buf, docs_parser.into_iter());
}

View file

@ -145,9 +145,11 @@ a:hover code {
body {
display: grid;
grid-template-columns: [before-sidebar] 1fr [sidebar] var(--sidebar-width) [main-content] fit-content(
calc(1280px - var(--sidebar-width))
) [end] 1fr;
grid-template-columns:
[before-sidebar] 1fr [sidebar] var(
--sidebar-width
) [main-content] fit-content(calc(1280px - var(--sidebar-width)))
[end] 1fr;
grid-template-rows: [top-header] var(--top-header-height) [above-footer] auto [footer] auto;
box-sizing: border-box;
margin: 0;
@ -514,7 +516,15 @@ pre {
samp .backpass,
samp .brace,
samp .bracket,
samp .paren {
samp .paren,
code .kw,
code .pipe,
code .backslash,
code .arrow,
code .backpass,
code .brace,
code .bracket,
code .paren {
/* language keywords, e.g. `if` */
color: #00c3ff;
}
@ -523,16 +533,17 @@ pre {
samp .comma,
samp .qmark,
samp .bar,
samp .colon {
samp .colon,
code .op,
code .comma,
code .qmark,
code .bar,
code .colon {
/* operators, e.g. `+` */
color: #ff3966;
}
samp .str {
/* string literals */
color: var(--link-color);
}
samp .str,
code .str {
/* string literals */
color: var(--link-color);
@ -540,11 +551,14 @@ pre {
/* autovar = automatic variable names in the repl, e.g. # val1 */
samp .comment,
samp .autovar {
samp .autovar,
code .comment,
code .autovar {
color: #4ed86c;
}
samp .number {
samp .number,
code .number {
color: #00c3ff;
}
}
@ -659,11 +673,13 @@ pre {
}
}
samp .ann {
samp .ann,
code .ann {
/* type annotation - purple in the repl */
color: #f384fd;
}
code .autovar,
samp .autovar {
/* automatic variable names in the repl, e.g. # val1 */
color: #338545;
@ -676,40 +692,64 @@ samp .arrow,
samp .backpass,
samp .brace,
samp .bracket,
samp .paren {
samp .paren,
code .kw,
code .pipe,
code .backslash,
code .arrow,
code .backpass,
code .brace,
code .bracket,
code .paren {
/* language keywords, e.g. `if`*/
color: #004cc2;
}
samp .upperident,
code .upperident {
/* Upper identifiers e.g. Types */
color: var(--purple-5);
}
samp .op,
samp .comma,
samp .qmark,
samp .bar,
samp .colon {
samp .colon,
code .op,
code .comma,
code .qmark,
code .bar,
code .colon {
/* operators, e.g. `+` */
color: #c20000;
}
samp .number {
samp .number,
code .number {
/* number literals */
color: #158086;
}
samp .str {
samp .str,
code .str {
/* string literals */
color: #158086;
}
samp .str-esc,
samp .str-interp {
samp .str-interp,
code .str-esc,
code .str-interp {
/* escapes inside string literals, e.g. \t */
color: #3474db;
}
samp .dim {
samp .dim,
code .dim {
opacity: 0.55;
}
samp .comment {
samp .comment code .comment {
color: #338545;
}