diff --git a/.gitignore b/.gitignore index 088ba6b..8a966af 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk + +ci/book +ci/mdBook diff --git a/Cargo.lock b/Cargo.lock index 5bcabdf..cbc2d62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1012,7 +1012,6 @@ dependencies = [ [[package]] name = "md2tex" version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "Inflector 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1061,7 +1060,7 @@ dependencies = [ name = "mdbook-latex" version = "0.1.4" dependencies = [ - "md2tex 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "md2tex 0.1.2", "mdbook 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2544,7 +2543,6 @@ dependencies = [ "checksum markup5ever 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f1af46a727284117e09780d05038b1ce6fc9c76cc6df183c3dae5a8955a25e21" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum md-5 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a18af3dcaf2b0219366cdb4e2af65a6101457b415c3d1a5c71dd9c2b7c77b9c8" -"checksum md2tex 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "041e1af3a96ff77dfbe6238a2453777e80285c562efbaf59a2bf90fa9eca8baa" "checksum mdbook 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "949bb2acb2cff9fa5c375cf9c43e70b3dba0a974d9fe01c31285d7a84d2a0fa2" "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" "checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" diff --git a/Cargo.toml b/Cargo.toml index 1819303..5fe0769 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,5 +13,5 @@ mdbook = "0.3.1" serde = "1.0.98" serde_derive = "1.0.98" tectonic = "0.1.11" -md2tex = "0.1.2" -#md2tex = { path = "/home/liam/Documents/code/projects/md2tex" } +#md2tex = "0.1.2" +md2tex = { path = "/home/liam/Documents/code/projects/md2tex" } diff --git a/README.md b/README.md index 3d03163..ff35438 100644 --- a/README.md +++ b/README.md @@ -164,10 +164,11 @@ Below is a list of features I am currently working on (loosely in a "top-down" d - [x] Configure [resvg](https://github.com/RazrFalcon/resvg) library to convert SVG's to PNG. - [ ] Save SVG's in `book/latex` directory to keep `src` clean. - [x] Add CI/CD pipeline ([travis](https://travis-ci.org/)) +- [x] Move all LaTeX data to single template file (src/template.tex). - [ ] Compile *The Rust Book* and *mdbook* documentation without any errors or warnings (e.g. missing Unicode characters). See [Status of Rust Bookshelf](#status-of-rust-bookshelf) for up to date progress. - [ ] Put "tectonic" dependency in "pdf" feature configuration. - [ ] Add "table of contents" mdbook toml option. -- [ ] Add "markdown" mdbook toml option. +- [x] Add "markdown" mdbook toml option. - [ ] Add "number of words" mdbook toml option. - [ ] Add "examples" directory. - [ ] Create documentation and move relevent docs to md2tex. diff --git a/src/header.tex b/src/header.tex deleted file mode 100644 index 321388b..0000000 --- a/src/header.tex +++ /dev/null @@ -1,86 +0,0 @@ -\UseRawInputEncoding -\documentclass{article} -\usepackage[english]{babel} -\usepackage{adjustbox} -\usepackage{colortbl} -\usepackage[T1]{fontenc} -\usepackage[margin=1in]{geometry} -\usepackage{graphicx} - -% https://tex.stackexchange.com/questions/219174/issue-with-page-breaks-before-section-and-toc-hyperlinks?rq=1 -\usepackage{titlesec} -\usepackage{hyperref} -\newcommand{\sectionbreak}{\clearpage} - -\usepackage[utf8]{inputenc} -\usepackage{listings} -\usepackage{longtable} -\usepackage{tabularx} -\usepackage{tabu} -\usepackage{textcomp} -\usepackage{xcolor} -\usepackage{array} - -\newcommand{\PreserveBackslash}[1]{\let\temp=\\#1\let\\=\temp} -\newcolumntype{C}[1]{>{\PreserveBackslash\centering}m{#1}} -\newcolumntype{R}[1]{>{\PreserveBackslash\raggedleft}p{#1}} -\newcolumntype{L}[1]{>{\PreserveBackslash\raggedright}p{#1}} - - -% https://tex.stackexchange.com/questions/143015/different-column-number-in-rows -\usepackage{booktabs,multirow,tabularx}% http://ctan.org/pkg/{booktabs,multirow,tabularx} -\newcommand{\makecell}[1]{\begin{tabular}{c}#1\end{tabular}} - -% https://tex.stackexchange.com/questions/823/remove-ugly-borders-around-clickable-cross-references-and-hyperlinks -\hypersetup{ - colorlinks, - linkcolor={red!50!black}, - citecolor={blue!50!black}, - urlcolor={blue!80!black} -} - -% https://tex.stackexchange.com/questions/215520/output-from-tree-command-in-a-listing -\usepackage{newunicodechar} -\newunicodechar{└}{{\smash{\raisebox{0.5ex}{\rule{0.5pt}{\dimexpr\baselineskip-1.5ex}}}\raisebox{0.5ex}{\rule{1ex}{0.5pt}}}} -\newunicodechar{─}{{\raisebox{0.5ex}{\rule{1.5ex}{0.5pt}}}} -\newunicodechar{├}{{\smash{\raisebox{-1ex}{\rule{0.5pt}{\baselineskip}}}\raisebox{0.5ex}{\rule{1ex}{0.5pt}}}} -\newunicodechar{’}{{'}} -\newunicodechar{“}{{"}} -\newunicodechar{”}{{"}} - -\definecolor{commentsColor}{rgb}{0.497495, 0.497587, 0.497464} -\definecolor{keywordsColor}{rgb}{0.000000, 0.000000, 0.635294} -\definecolor{stringColor}{rgb}{0.558215, 0.000000, 0.135316} -\lstset{ % - backgroundcolor=\color{white}, % choose the background color; you must add \usepackage{color} or \usepackage{xcolor} - basicstyle=\footnotesize\ttfamily, % the size of the fonts that are used for the code - breakatwhitespace=false, % sets if automatic breaks should only happen at whitespace - breaklines=true, % sets automatic line breaking - captionpos=b, % sets the caption-position to bottom - commentstyle=\color{commentsColor}\textit, % comment style - deletekeywords={...}, % if you want to delete keywords from the given language - escapeinside={\%*}{*)}, % if you want to add LaTeX within your code - extendedchars=true, % lets you use non-ASCII characters; for 8-bits encodings only, does not work with UTF-8 - frame=tb, % adds a frame around the code - keepspaces=true, % keeps spaces in text, useful for keeping indentation of code (possibly needs columns=flexible) - keywordstyle=\color{keywordsColor}\bfseries, % keyword style - language=Python, % the language of the code (can be overrided per snippet) - otherkeywords={*,...}, % if you want to add more keywords to the set - numbers=left, % where to put the line-numbers; possible values are (none, left, right) - numbersep=5pt, % how far the line-numbers are from the code - numberstyle=\tiny\color{commentsColor}, % the style that is used for the line-numbers - rulecolor=\color{black}, % if not set, the frame-color may be changed on line-breaks within not-black text (e.g. comments (green here)) - showspaces=false, % show spaces everywhere adding particular underscores; it overrides 'showstringspaces' - showstringspaces=false, % underline spaces within strings only - showtabs=false, % show tabs within strings adding particular underscores - stepnumber=1, % the step between two line-numbers. If it's 1, each line will be numbered - stringstyle=\color{stringColor}, % string literal style - prebreak=\raisebox{0ex}[0ex][0ex]{\ensuremath{\hookrightarrow}}, - tabsize=2, % sets default tabsize to 2 spaces - title=\lstname, % show the filename of files included with \lstinputlisting; also try caption instead of title - columns=fixed, % Using fixed column width (for e.g. nice alignment) - inputencoding=utf8, % https://tex.stackexchange.com/questions/24528/having-problems-with-listings-and-utf-8-can-it-be-fixed - literate={└}{{\smash{\raisebox{0.5ex}{\rule{0.5pt}{\dimexpr\baselineskip-1.5ex}}}\raisebox{0.5ex}{\rule{1ex}{0.5pt}}}}1 {─}{{\raisebox{0.5ex}{\rule{1.5ex}{0.5pt}}}}1 {├}{{\smash{\raisebox{-1ex}{\rule{0.5pt}{\baselineskip}}}\raisebox{0.5ex}{\rule{1ex}{0.5pt}}}}1, -} - - diff --git a/src/main.rs b/src/main.rs index 614810d..50c1aa5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,7 @@ extern crate md2tex; extern crate tectonic; //use latex::*; -use md2tex::markdown_to_latex; +use md2tex::markdown_to_tex; use mdbook::book::BookItem; use mdbook::renderer::RenderContext; use std::error::Error; @@ -24,24 +24,19 @@ use std::path::Path; pub struct LatexConfig { // chapters that will not be exported. pub ignores: Vec, + // output latex file. pub latex: bool, + // output PDF. pub pdf: bool, + // output markdown file. pub markdown: bool, -} - -// TODO move these latex parts to seperate file. -pub const LATEX_BEGIN: &str = r#" -\begin{document} -\maketitle -\clearpage -\tableofcontents -\clearpage -"#; -pub const LATEX_FOOTER: &str = "\n\\end{document}\n"; + // TODO use user's LaTeX template file instead of default (template.tex). + // pub custom_template: bool, +} fn main() -> std::io::Result<()> { let mut stdin = io::stdin(); @@ -59,17 +54,10 @@ fn main() -> std::io::Result<()> { let title = ctx.config.book.title.unwrap(); let authors = ctx.config.book.authors.join(" \\and "); - let mut latex = String::new(); - - let latex_header = include_str!("header.tex"); - let latex_languages = include_str!("languages.tex"); + // copy template data into memory. + let mut template = include_str!("template.tex").to_string(); - latex.push_str(&latex_header); - latex.push_str(&latex_languages); - latex.push_str(&format!("\\title{{{title}}}", title = title)); - latex.push_str(&format!("\\author{{{authors}}}", authors = authors)); - - latex.push_str(&LATEX_BEGIN); + let mut latex = String::new(); // iterate through markdown source. let mut content = String::new(); @@ -84,54 +72,31 @@ fn main() -> std::io::Result<()> { } } - // output markdown file. if cfg.markdown { - let mut file_md = title.clone(); - file_md.push_str(".md"); - let path = Path::new(&file_md); - let display = path.display(); - let mut _file = match File::create(&file_md) { - Err(why) => panic!("couldn't create {}: {}", display, why.description()), - Ok(file) => file, - }; - - // write to file. - match _file.write_all(content.as_bytes()) { - Err(why) => panic!("couldn't write to {}: {}", display, why.description()), - Ok(_) => println!("successfully wrote to {}", display), - } + // output markdown file. + output(".md".to_string(), title.clone(), &latex, &ctx.destination); } - latex.push_str(&markdown_to_latex(content.to_string())); - latex.push_str(&LATEX_FOOTER); + if cfg.latex || cfg.pdf { + // convert markdown data to LaTeX + latex.push_str(&markdown_to_tex(content.to_string())); + + // insert new LaTeX data into template after "%% mdbook-latex begin". + let begin = "mdbook-latex begin"; + let pos = template.find(&begin).unwrap() + begin.len(); + template.insert_str(pos, &latex); + } - // output latex file. if cfg.latex { - let mut file_latex = title.clone(); - file_latex.push_str(".tex"); - let path = Path::new(&file_latex); - let display = path.display(); - - // create output directory/file. - let _ = fs::create_dir_all(&ctx.destination); - - let mut file = match File::create(&path) { - Err(why) => panic!("couldn't create {}: {}", display, why.description()), - Ok(file) => file, - }; - - // write to file. - match file.write_all(latex.as_bytes()) { - Err(why) => panic!("couldn't write to {}: {}", display, why.description()), - Ok(_) => println!("successfully wrote to {}", display), - } + // output latex file. + output(".tex".to_string(), title.clone(), &template, &ctx.destination); } // output PDF file. if cfg.pdf { // write PDF with tectonic. println!("Writing PDF with Tectonic..."); - let pdf_data: Vec = tectonic::latex_to_pdf(latex).expect("processing failed"); + let pdf_data: Vec = tectonic::latex_to_pdf(&template).expect("processing failed"); println!("Output PDF size is {} bytes", pdf_data.len()); let mut pos = 0; @@ -148,3 +113,26 @@ fn main() -> std::io::Result<()> { Ok(()) } + +/// Output plain text file. +/// +/// Used for writing markdown and latex data to files. +fn output>(extension: String, mut filename: String, data: &String, destination: P) { + filename.push_str(&extension); + let path = Path::new(&filename); + let display = path.display(); + + // create output directory/file. + let _ = fs::create_dir_all(destination); + + let mut file = match File::create(&path) { + Err(why) => panic!("Couldn't create {}: {}", display, why.description()), + Ok(file) => file, + }; + + // write to file. + match file.write_all(data.as_bytes()) { + Err(why) => panic!("Couldn't write to {}: {}", display, why.description()), + Ok(_) => println!("Successfully wrote to {}", display), + } +} diff --git a/src/languages.tex b/src/template.tex similarity index 68% rename from src/languages.tex rename to src/template.tex index b7777dd..1eebf8c 100644 --- a/src/languages.tex +++ b/src/template.tex @@ -1,5 +1,55 @@ +%% Packages and Settings +\UseRawInputEncoding +\documentclass{article} +\usepackage[english]{babel} +\usepackage{adjustbox} +\usepackage{colortbl} +\usepackage[T1]{fontenc} +\usepackage[margin=1in]{geometry} +\usepackage{graphicx} + +% https://tex.stackexchange.com/questions/219174/issue-with-page-breaks-before-section-and-toc-hyperlinks?rq=1 +\usepackage{titlesec} +\usepackage{hyperref} +\newcommand{\sectionbreak}{\clearpage} + +\usepackage[utf8]{inputenc} +\usepackage{listings} +\usepackage{longtable} +\usepackage{tabularx} +\usepackage{tabu} +\usepackage{textcomp} \usepackage{xcolor} +\usepackage{array} + +\newcommand{\PreserveBackslash}[1]{\let\temp=\\#1\let\\=\temp} +\newcolumntype{C}[1]{>{\PreserveBackslash\centering}m{#1}} +\newcolumntype{R}[1]{>{\PreserveBackslash\raggedleft}p{#1}} +\newcolumntype{L}[1]{>{\PreserveBackslash\raggedright}p{#1}} + +% https://tex.stackexchange.com/questions/143015/different-column-number-in-rows +\usepackage{booktabs,multirow,tabularx}% http://ctan.org/pkg/{booktabs,multirow,tabularx} +\newcommand{\makecell}[1]{\begin{tabular}{c}#1\end{tabular}} + +% https://tex.stackexchange.com/questions/823/remove-ugly-borders-around-clickable-cross-references-and-hyperlinks +\hypersetup{ + colorlinks, + linkcolor={red!50!black}, + citecolor={blue!50!black}, + urlcolor={blue!80!black} +} +%% Unicode rules. +% https://tex.stackexchange.com/questions/215520/output-from-tree-command-in-a-listing +\usepackage{newunicodechar} +\newunicodechar{└}{{\smash{\raisebox{0.5ex}{\rule{0.5pt}{\dimexpr\baselineskip-1.5ex}}}\raisebox{0.5ex}{\rule{1ex}{0.5pt}}}} +\newunicodechar{─}{{\raisebox{0.5ex}{\rule{1.5ex}{0.5pt}}}} +\newunicodechar{├}{{\smash{\raisebox{-1ex}{\rule{0.5pt}{\baselineskip}}}\raisebox{0.5ex}{\rule{1ex}{0.5pt}}}} +\newunicodechar{’}{{'}} +\newunicodechar{“}{{"}} +\newunicodechar{”}{{"}} + +%% Code highlighting. \definecolor{commentsColor}{rgb}{0.497495, 0.497587, 0.497464} \definecolor{keywordsColor}{rgb}{0.000000, 0.000000, 0.635294} \definecolor{stringColor}{rgb}{0.558215, 0.000000, 0.135316} @@ -27,10 +77,15 @@ showtabs=false, % show tabs within strings adding particular underscores stepnumber=1, % the step between two line-numbers. If it's 1, each line will be numbered stringstyle=\color{stringColor}, % string literal style + prebreak=\raisebox{0ex}[0ex][0ex]{\ensuremath{\hookrightarrow}}, tabsize=2, % sets default tabsize to 2 spaces title=\lstname, % show the filename of files included with \lstinputlisting; also try caption instead of title - columns=fixed % Using fixed column width (for e.g. nice alignment) + columns=fixed, % Using fixed column width (for e.g. nice alignment) + inputencoding=utf8, % https://tex.stackexchange.com/questions/24528/having-problems-with-listings-and-utf-8-can-it-be-fixed + literate={└}{{\smash{\raisebox{0.5ex}{\rule{0.5pt}{\dimexpr\baselineskip-1.5ex}}}\raisebox{0.5ex}{\rule{1ex}{0.5pt}}}}1 {─}{{\raisebox{0.5ex}{\rule{1.5ex}{0.5pt}}}}1 {├}{{\smash{\raisebox{-1ex}{\rule{0.5pt}{\baselineskip}}}\raisebox{0.5ex}{\rule{1ex}{0.5pt}}}}1, } + +%% Language definitions. \lstdefinelanguage{rust}{ keywords={typeof, new, true, false, catch, function, return, null, catch, switch, var, if, in, while, do, else, case, break}, ndkeywords={class, export, boolean, throw, implements, import, this}, @@ -51,17 +106,6 @@ morestring=[b]" } -\lstdefinelanguage{hbs}{ - keywords={typeof, new, true, false, catch, function, return, null, catch, switch, var, if, in, while, do, else, case, break}, - ndkeywords={class, export, boolean, throw, implements, import, this}, - sensitive=false, - comment=[l]{//}, - morecomment=[s]{/*}{*/}, - morestring=[b]', - morestring=[b]" -} - - \lstdefinelanguage{console}{ keywords={typeof, new, true, false, catch, function, return, null, catch, switch, var, if, in, while, do, else, case, break}, ndkeywords={class, export, boolean, throw, implements, import, this}, @@ -71,7 +115,6 @@ morestring=[b]" } - \lstdefinelanguage{handlebars}{ keywords={typeof, new, true, false, catch, function, return, null, catch, switch, var, if, in, while, do, else, case, break}, ndkeywords={class, export, boolean, throw, implements, import, this}, @@ -82,7 +125,6 @@ morestring=[b]" } - \lstdefinelanguage{shell}{ keywords={typeof, new, true, false, catch, function, return, null, catch, switch, var, if, in, while, do, else, case, break}, ndkeywords={class, export, boolean, throw, implements, import, this}, @@ -93,28 +135,6 @@ morestring=[b]" } - -\lstdefinelanguage{makefile}{ - keywords={typeof, new, true, false, catch, function, return, null, catch, switch, var, if, in, while, do, else, case, break}, - ndkeywords={class, export, boolean, throw, implements, import, this}, - sensitive=false, - comment=[l]{\#}, - morestring=[b]', - morestring=[b]" -} - - -\lstdefinelanguage{markdown}{ - keywords={typeof, new, true, false, catch, function, return, null, catch, switch, var, if, in, while, do, else, case, break}, - ndkeywords={class, export, boolean, throw, implements, import, this}, - sensitive=false, - comment=[l]{//}, - morecomment=[s]{/*}{*/}, - morestring=[b]', - morestring=[b]" -} - - \lstdefinelanguage{json}{ keywords={typeof, new, true, false, catch, function, return, null, catch, switch, var, if, in, while, do, else, case, break}, ndkeywords={class, export, boolean, throw, implements, import, this}, @@ -125,7 +145,6 @@ morestring=[b]" } - \lstdefinelanguage{yaml}{ keywords={typeof, new, true, false, catch, function, return, null, catch, switch, var, if, in, while, do, else, case, break}, ndkeywords={class, export, boolean, throw, implements, import, this}, @@ -136,7 +155,6 @@ morestring=[b]" } - \lstdefinelanguage{toml}{ keywords={typeof, new, true, false, catch, function, return, null, catch, switch, var, if, in, while, do, else, case, break}, ndkeywords={class, export, boolean, throw, implements, import, this}, @@ -147,10 +165,7 @@ morestring=[b]" } - \lstdefinelanguage{diff}{ - keywords={typeof, new, true, false, catch, function, return, null, catch, switch, var, if, in, while, do, else, case, break}, - ndkeywords={class, export, boolean, throw, implements, import, this}, sensitive=false, comment=[l]{//}, morecomment=[s]{/*}{*/}, @@ -158,7 +173,6 @@ morestring=[b]" } - \lstdefinelanguage{JavaScript}{ keywords={typeof, new, true, false, catch, function, return, null, catch, switch, var, if, in, while, do, else, case, break}, ndkeywords={class, export, boolean, throw, implements, import, this}, @@ -170,5 +184,23 @@ } \lstdefinelanguage{text}{} +\lstdefinelanguage{hbs}{} \lstdefinelanguage{cmd}{} \lstdefinelanguage{powershell}{} +\lstdefinelanguage{makefile}{} +\lstdefinelanguage{markdown}{} + +%% Title and Author (retreived from book.toml) +\title{} +\author{} + +%% Begin document. +\begin{document} +\maketitle +\clearpage +\tableofcontents +\clearpage + +%% mdbook-latex begin + +\end{document}