Created
March 29, 2023 10:05
-
-
Save bombless/3780e177acd24504d75ba78fff3e89ee to your computer and use it in GitHub Desktop.
Compile moderncv to typst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[derive(Debug)] | |
enum Value { | |
Plain(String), | |
Section(String), | |
CvEntry(Vec<String>), | |
CvItem(Vec<String>), | |
} | |
fn parse(input: &str) { | |
use std::mem::replace; | |
let mut quoting_buffer = String::new(); | |
let mut quoting_depth = 0; | |
let mut stream = Vec::new(); | |
let mut context = String::new(); | |
let mut blocks = Vec::new(); | |
let mut commenting = false; | |
let mut in_bracket = false; | |
for c in input.chars() { | |
if c == '%' { | |
commenting = true; | |
} | |
else if commenting && c != '\n' { | |
continue; | |
} | |
else if c == ']' { | |
in_bracket = false; | |
} | |
else if c == '[' { | |
in_bracket = true; | |
} | |
else if in_bracket { | |
continue; | |
} | |
else if c == '}' { | |
quoting_depth -= 1; | |
if quoting_depth == 0 { | |
blocks.push(replace(&mut quoting_buffer, String::new())); | |
} | |
} | |
else if c == '\n' { | |
commenting = false; | |
if context.len() == 0 { continue } | |
match replace(&mut context, String::new()).as_str() { | |
"\\section" => { | |
if blocks.len() < 1 { continue } | |
stream.push(Value::Section(replace(&mut blocks, Vec::new()).pop().unwrap())); | |
} | |
"\\cventry" => { | |
if blocks.len() < 6 { continue } | |
stream.push(Value::CvEntry(replace(&mut blocks, Vec::new()))); | |
} | |
"\\cvitem" => { | |
if blocks.len() < 2 { continue } | |
stream.push(Value::CvItem(replace(&mut blocks, Vec::new()))); | |
}, | |
"\\firstname" => (), | |
"\\familyname" => (), | |
"\\title" => (), | |
"\\mobile" => (), | |
"\\email" => (), | |
"\\address" => (), | |
"\\photo" => (), | |
"\\makecvtitle" => (), | |
"\\begin" => (), | |
"\\end" => (), | |
"\\documentclass" => (), | |
"\\moderncvstyle" => (), | |
"\\moderncvcolor" => (), | |
"\\usepackage" => (), | |
"\\setlength" => (), | |
x => { | |
if x.starts_with("\\") { | |
println!(":{}", x); | |
unreachable!() | |
} | |
stream.push(Value::Plain(x.to_string())); | |
} | |
} | |
} | |
else if c == '{' { | |
if quoting_depth > 0 { | |
quoting_buffer.clear(); | |
} | |
quoting_depth += 1; | |
} | |
else if quoting_depth > 0 { | |
quoting_buffer.push(c); | |
} | |
else if !c.is_whitespace() { | |
context.push(c) | |
} | |
} | |
for item in stream { | |
match item { | |
Value::Plain(val) => { | |
println!("{}", val); | |
}, | |
Value::Section(val) => { | |
println!("\n= {}\n#line(length: 100%)", val); | |
}, | |
Value::CvEntry(parts) => { | |
println!("#v(.2em)"); | |
if parts[2].len() > 0 { | |
println!("== {}", parts[2]); | |
} | |
println!("*{}* #h(1fr) {}#v(.1em)\n{}", parts[1], parts[0], parts[5]); | |
}, | |
Value::CvItem(parts) => { | |
println!("/ {}:`{}`", parts[0], parts[1]); | |
}, | |
} | |
} | |
} | |
fn main() { | |
parse(r" | |
\firstname{Jane} | |
\familyname{Doe} | |
\title{Curriculum Vitae} | |
\address{Street}{City}{} | |
\mobile{Number} | |
\email{email} | |
\begin{document} | |
\makecvtitle | |
\section{Education} | |
\cventry | |
{2020--2025} | |
{Degree} | |
{University} | |
{Location} | |
{\textit{Grade}}% Missing this | |
{Some info including a link in my real document. The automatic linebreak works here, but not below} | |
\setlength{\hintscolumnwidth}{4cm} | |
\setlength{\maincolumnwidth}{\dimexpr\linewidth-\hintscolumnwidth-\separatorcolumnwidth} | |
\cvitem{Item 1}{This is the description of item 1 and it is very long so I need an automatic linebreak here so the text doesn't go beyond the linewidth.} | |
\cvitem{Item 2}{This is the description of item 2 and it is very long so I need an automatic linebreak here which I don't know how to create.} | |
\cvitem{Item 3}{This is the description of item 3 and it is even longer and spans across multiple lines so I need an automatic linebreak so the text doesn't go beyond the linewidth, but I don't know how to create this.} | |
\end{document} | |
") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment