fleshed out more latex

master
Kenton Hamaluik 5 years ago
parent 78721af6b6
commit 07e86d6a0b

@ -0,0 +1,11 @@
---
title = "Task Lists"
---
You can also use [GFM](https://help.github.com/en/github/writing-on-github)-style [task lists](https://github.blog/2013-01-09-task-lists-in-gfm-issues-pulls-comments/) to indicate a TODO list:
- [ ] a task list item
- [ ] list syntax required
- [ ] normal **formatting**
- [ ] incomplete
- [x] completed

@ -57,24 +57,44 @@ fn format_text<'a>(node: &'a comrak::nodes::AstNode<'a>, output: &mut String) {
output.push_str(&escape_text(text));
}
},
NodeValue::Code(text) => {
if let Ok(text) = std::str::from_utf8(text) {
output.push_str("\\texttt{");
output.push_str(&escape_text(text));
output.push_str("}");
}
},
//NodeValue::Code(text) => {
// if let Ok(text) = std::str::from_utf8(text) {
// output.push_str("\\texttt{");
// output.push_str(&escape_text(text));
// output.push_str("}");
// }
//},
//NodeValue::Emph => {
// output.push_str("\\emph{");
// for child in node.children() { format_text(child, output); }
// output.push_str("}");
//},
//NodeValue::Strong => {
// output.push_str("\\textbf{");
// for child in node.children() { format_text(child, output); }
// output.push_str("}");
//},
//NodeValue::Strikethrough => {
// output.push_str("\\sout{");
// for child in node.children() { format_text(child, output); }
// output.push_str("}");
//},
//NodeValue::Superscript => {
// output.push_str("\\textsuperscript{");
// for child in node.children() { format_text(child, output); }
// output.push_str("}");
//},
_ => for child in node.children() { format_text(child, output); },
}
}
fn format_node<'a>(node: &'a comrak::nodes::AstNode<'a>, output: &mut String) {
fn format_node<'a>(section_offset: u32, node: &'a comrak::nodes::AstNode<'a>, output: &mut String) {
use comrak::nodes::NodeValue;
match &node.data.borrow().value {
NodeValue::Document => for child in node.children() { format_node(child, output); },
NodeValue::Document => for child in node.children() { format_node(section_offset, child, output); },
NodeValue::BlockQuote => {
output.push_str("\\begin{quote}\n");
for child in node.children() { format_node(child, output); }
for child in node.children() { format_node(section_offset, child, output); }
output.push_str("\\end{quote}\n");
},
NodeValue::List(node_list) => {
@ -82,7 +102,7 @@ fn format_node<'a>(node: &'a comrak::nodes::AstNode<'a>, output: &mut String) {
comrak::nodes::ListType::Bullet => output.push_str("\\begin{itemize}\n"),
comrak::nodes::ListType::Ordered => output.push_str("\\begin{enumerate}\n"),
}
for child in node.children() { format_node(child, output); }
for child in node.children() { format_node(section_offset, child, output); }
match node_list.list_type {
comrak::nodes::ListType::Bullet => output.push_str("\\end{itemize}\n"),
comrak::nodes::ListType::Ordered => output.push_str("\\end{enumerate}\n"),
@ -90,15 +110,19 @@ fn format_node<'a>(node: &'a comrak::nodes::AstNode<'a>, output: &mut String) {
},
NodeValue::Item(_) => {
output.push_str("\\item ");
for child in node.children() { format_node(child, output); }
let mut item: String = String::default();
for child in node.children() { format_node(section_offset, child, &mut item); }
output.push_str(item.trim());
output.push_str("\n");
},
NodeValue::DescriptionList => {
output.push_str("\\begin{description}\n");
for child in node.children() { format_node(child, output); }
let mut items: String = String::default();
for child in node.children() { format_node(section_offset, child, &mut items); }
output.push_str(&items.replace("\n\n\n", "\n").replace("\n\n", "\n"));
output.push_str("\\end{description}\n");
},
NodeValue::DescriptionItem(_) => for child in node.children() { format_node(child, output); },
NodeValue::DescriptionItem(_) => for child in node.children() { format_node(section_offset, child, output); },
NodeValue::DescriptionTerm => {
output.push_str("\\item [");
let mut term: String = String::default();
@ -107,7 +131,7 @@ fn format_node<'a>(node: &'a comrak::nodes::AstNode<'a>, output: &mut String) {
output.push_str("] ");
},
NodeValue::DescriptionDetails => {
for child in node.children() { format_node(child, output); }
for child in node.children() { format_node(section_offset, child, output); }
output.push_str("\n");
},
NodeValue::CodeBlock(node_code_block) => {
@ -133,23 +157,26 @@ fn format_node<'a>(node: &'a comrak::nodes::AstNode<'a>, output: &mut String) {
output.push_str("\\end{minted}\n\\end{absolutelynopagebreak}\n\n");
},
NodeValue::HtmlBlock(node_html_block) => {
log::warn!("can't handle html block, rendering it as syntax...");
let source = std::str::from_utf8(&node_html_block.literal).expect("valid utf-8");
output.push_str("\\begin{minted}[breaklines]{text}\n");
output.push_str(source);
output.push_str("\\end{minted}\n\n");
},
NodeValue::Paragraph => {
for child in node.children() {
format_node(child, output);
format_node(section_offset, child, output);
}
output.push_str("\n\n");
},
NodeValue::Heading(node_heading) => {
match node_heading.level {
match node_heading.level + section_offset {
1 => output.push_str("\\section{"),
2 => output.push_str("\\subsection{"),
3 => output.push_str("\\subsubsection{"),
4 => output.push_str("\\paragraph{"),
5 => output.push_str("\\subparagraph{"),
6 => output.push_str("\\textbf{"),
_ => unreachable!()
_ => output.push_str("\\textbf{"),
}
for child in node.children() { format_text(child, output); }
output.push_str("}");
@ -174,8 +201,16 @@ fn format_node<'a>(node: &'a comrak::nodes::AstNode<'a>, output: &mut String) {
output.push_str(&escape_text(text));
}
},
NodeValue::TaskItem(bool) => {
NodeValue::TaskItem(checked) => {
let mut item: String = String::default();
for child in node.children() { format_node(section_offset, child, &mut item); }
if *checked {
output.push_str(r"$\text{\rlap{$\checkmark$}}\square$ ");
}
else {
output.push_str(r"$\square$ ");
}
output.push_str(item.trim());
},
NodeValue::SoftBreak => {
output.push_str("\n");
@ -191,30 +226,41 @@ fn format_node<'a>(node: &'a comrak::nodes::AstNode<'a>, output: &mut String) {
}
},
NodeValue::HtmlInline(text) => {
let source = std::str::from_utf8(&text).expect("valid utf-8");
log::warn!("can't handle inline html `{}`, rendering it as syntax...", source);
output.push_str("\\mintinline{html}{");
output.push_str(&escape_text(source));
output.push_str("}");
},
NodeValue::Emph => {
output.push_str("\\emph{");
for child in node.children() { format_node(child, output); }
for child in node.children() { format_node(section_offset, child, output); }
output.push_str("}");
},
NodeValue::Strong => {
output.push_str("\\textbf{");
for child in node.children() { format_node(child, output); }
for child in node.children() { format_node(section_offset, child, output); }
output.push_str("}");
},
NodeValue::Strikethrough => {
output.push_str("\\sout{");
for child in node.children() { format_node(child, output); }
for child in node.children() { format_node(section_offset, child, output); }
output.push_str("}");
},
NodeValue::Superscript => {
output.push_str("\\textsuperscript{");
for child in node.children() { format_node(child, output); }
for child in node.children() { format_node(section_offset, child, output); }
output.push_str("}");
},
NodeValue::Link(node_link) => {
let url = std::str::from_utf8(&node_link.url).expect("valid utf-8");
output.push_str("\\href{");
output.push_str(&escape_text(url));
output.push_str("}{");
for child in node.children() { format_text(child, output); }
output.push_str("}\\footnote{\\url{");
output.push_str(&escape_text(url));
output.push_str("}}");
},
NodeValue::Image(node_link) => {
@ -225,7 +271,7 @@ fn format_node<'a>(node: &'a comrak::nodes::AstNode<'a>, output: &mut String) {
}
}
fn format_markdown(src: &str) -> Result<String, Box<dyn std::error::Error>> {
fn format_markdown(section_offset: u32, src: &str) -> Result<String, Box<dyn std::error::Error>> {
let arena = comrak::Arena::new();
let root = comrak::parse_document(
&arena,
@ -233,7 +279,7 @@ fn format_markdown(src: &str) -> Result<String, Box<dyn std::error::Error>> {
&COMRAK_OPTIONS);
let mut latex: String = String::with_capacity(src.len());
format_node(&root, &mut latex);
format_node(section_offset, &root, &mut latex);
Ok(latex)
}
@ -252,11 +298,11 @@ pub fn build<PIn: AsRef<Path>, POut: AsRef<Path>>(src: PIn, dest: POut) -> Resul
let mut book = super::load_book(&src)?;
// then convert all the markdown
book.description = format_markdown(&book.description)?;
book.description = format_markdown(0, &book.description)?;
for chapter in book.chapters.iter_mut() {
chapter.contents = format_markdown(&chapter.contents)?;
chapter.contents = format_markdown(0, &chapter.contents)?;
for section in chapter.sections.iter_mut() {
section.contents = format_markdown(&section.contents)?;
section.contents = format_markdown(1, &section.contents)?;
}
}

@ -3,3 +3,7 @@ use chrono::prelude::*;
pub fn human_date(d: &DateTime<Utc>) -> askama::Result<String> {
Ok(d.format("%b %e, %Y").to_string())
}
pub fn year(d: &DateTime<Utc>) -> askama::Result<String> {
Ok(d.format("%Y").to_string())
}

@ -29,10 +29,18 @@
{\par\xdef\tpd{\the\prevdepth}\egroup
\prevdepth=\tpd}
%\makeatletter
%\renewcommand{\frontmatter}{\cleardoublepage\@mainmatterfalse}
%\renewcommand{\mainmatter}{\cleardoublepage\@mainmattertrue}
%\makeatother
% urls
\usepackage[hidelinks]{hyperref}
% extra symbols
\usepackage{amsmath}
\usepackage{amssymb}
% make the TOC work with our preface
\makeatletter
\renewcommand{\frontmatter}{\cleardoublepage\@mainmatterfalse}
\renewcommand{\mainmatter}{\cleardoublepage\@mainmattertrue}
\makeatother
\title{ {{ front.title }} }
\author{ {{ front.author }} }
@ -40,10 +48,22 @@
\begin{document}
\frontmatter
\pagestyle{empty}
\maketitle
\clearpage
% copyright
\pagestyle{empty}
\topskip0pt
\vspace*{\fill}
\begin{center}
\textcopyright{} {{ front.pubdate|year }} {{ front.author }}
\end{center}
\vspace*{\fill}
\clearpage
\tableofcontents
\cleardoublepage
\chapter{Preface}
@ -57,7 +77,7 @@
{{ chapter.contents }}
{% for section in chapter.sections %}
\chapter{ {{ section.front.title }} }
\section{ {{ section.front.title }} }
{{ section.contents }}
{% endfor %}

Loading…
Cancel
Save