summaryrefslogtreecommitdiff
path: root/src/typeset.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/typeset.rs')
-rw-r--r--src/typeset.rs229
1 files changed, 0 insertions, 229 deletions
diff --git a/src/typeset.rs b/src/typeset.rs
deleted file mode 100644
index f63206a..0000000
--- a/src/typeset.rs
+++ /dev/null
@@ -1,229 +0,0 @@
-use crate::parser::parse_scenario_snippet;
-use crate::Bindings;
-use crate::PartialStep;
-use crate::ScenarioStep;
-use crate::StepKind;
-use crate::SubplotError;
-use crate::{DiagramMarkup, DotMarkup, PikchrMarkup, PlantumlMarkup, Svg};
-use crate::{Warning, Warnings};
-
-use pandoc_ast::Attr;
-use pandoc_ast::Block;
-use pandoc_ast::Inline;
-use pandoc_ast::Target;
-
-/// Typeset an error as a Pandoc AST Block element.
-pub fn error(err: SubplotError) -> Block {
- let msg = format!("ERROR: {}", err);
- Block::Para(error_msg(&msg))
-}
-
-/// Typeset an error message a vector of inlines.
-pub fn error_msg(msg: &str) -> Vec<Inline> {
- vec![Inline::Strong(vec![inlinestr(msg)])]
-}
-
-/// Typeset a string as an inline element.
-pub fn inlinestr(s: &str) -> Inline {
- Inline::Str(String::from(s))
-}
-
-/// Typeset a code block tagged as a file.
-pub fn file_block(attr: &Attr, text: &str) -> Block {
- let filename = inlinestr(&attr.0);
- let filename = Inline::Strong(vec![filename]);
- let intro = Block::Para(vec![inlinestr("File:"), space(), filename]);
- let mut cbattrs = attr.clone();
- if cbattrs.1.iter().any(|s| s == "noNumberLines") {
- // If the block says "noNumberLines" we remove that class
- cbattrs.1.retain(|s| s != "noNumberLines");
- } else if cbattrs.1.iter().all(|s| s != "numberLines") {
- // Otherwise if it doesn't say numberLines we add that in.
- cbattrs.1.push("numberLines".to_string());
- }
- // If this was an `example`, convert that class to `file`
- if cbattrs.1.iter().any(|s| s == "example") {
- cbattrs.1.retain(|s| s != "example");
- cbattrs.1.push("file".into());
- }
- let codeblock = Block::CodeBlock(cbattrs, text.to_string());
- let noattr = ("".to_string(), vec![], vec![]);
- Block::Div(noattr, vec![intro, codeblock])
-}
-
-/// Typeset a scenario snippet as a Pandoc AST Block.
-///
-/// Typesetting here means producing the Pandoc abstract syntax tree
-/// nodes that result in the desired output, when Pandoc processes
-/// them.
-///
-/// The snippet is given as a text string, which is parsed. It need
-/// not be a complete scenario, but it should consist of complete steps.
-pub fn scenario_snippet(bindings: &Bindings, snippet: &str, warnings: &mut Warnings) -> Block {
- let lines = parse_scenario_snippet(snippet);
- let mut steps = vec![];
- let mut prevkind: Option<StepKind> = None;
-
- for line in lines {
- let (this, thiskind) = step(bindings, line, prevkind, warnings);
- steps.push(this);
- prevkind = thiskind;
- }
- Block::LineBlock(steps)
-}
-
-// Typeset a single scenario step as a sequence of Pandoc AST Inlines.
-fn step(
- bindings: &Bindings,
- text: &str,
- prevkind: Option<StepKind>,
- warnings: &mut Warnings,
-) -> (Vec<Inline>, Option<StepKind>) {
- let step = ScenarioStep::new_from_str(text, prevkind);
- if step.is_err() {
- return (
- error_msg(&format!("Could not parse step: {}", text)),
- prevkind,
- );
- }
- let step = step.unwrap();
-
- let m = match bindings.find("", &step) {
- Ok(m) => m,
- Err(e) => {
- let w = Warning::UnknownBinding(format!("{}", e));
- warnings.push(w.clone());
- return (error_msg(&format!("{}", w)), prevkind);
- }
- };
-
- let mut inlines = vec![keyword(&step, prevkind), space()];
-
- for part in m.parts() {
- match part {
- PartialStep::UncapturedText(s) => inlines.push(uncaptured(s.text())),
- PartialStep::CapturedText { text, .. } => inlines.push(captured(text)),
- }
- }
-
- (inlines, Some(step.kind()))
-}
-
-// Typeset first word, which is assumed to be a keyword, of a scenario
-// step.
-fn keyword(step: &ScenarioStep, prevkind: Option<StepKind>) -> Inline {
- let actual = inlinestr(&format!("{}", step.kind()));
- let and = inlinestr("and");
- let keyword = if let Some(prevkind) = prevkind {
- if prevkind == step.kind() {
- and
- } else {
- actual
- }
- } else {
- actual
- };
- Inline::Emph(vec![keyword])
-}
-
-// Typeset a space between words.
-fn space() -> Inline {
- Inline::Space
-}
-
-// Typeset an uncaptured part of a step.
-fn uncaptured(s: &str) -> Inline {
- inlinestr(s)
-}
-
-// Typeset a captured part of a step.
-fn captured(s: &str) -> Inline {
- Inline::Strong(vec![inlinestr(s)])
-}
-
-/// Typeset a link as a note.
-pub fn link_as_note(attr: Attr, text: Vec<Inline>, target: Target) -> Inline {
- let (url, _) = target.clone();
- let url = Inline::Code(attr.clone(), url);
- let link = Inline::Link(attr.clone(), vec![url], target);
- let note = Inline::Note(vec![Block::Para(vec![link])]);
- let mut text = text;
- text.push(note);
- Inline::Span(attr, text)
-}
-
-/// Take a pikchr diagram, render it as SVG, and return an AST block element.
-///
-/// The `Block` will contain the SVG data. This allows the diagram to
-/// be rendered without referencing external entities.
-///
-/// If the code block which contained the pikchr contains other classes, they
-/// can be added to the SVG for use in later typesetting etc.
-pub fn pikchr_to_block(pikchr: &str, class: Option<&str>, warnings: &mut Warnings) -> Block {
- match PikchrMarkup::new(pikchr, class).as_svg() {
- Ok(svg) => typeset_svg(svg),
- Err(err) => {
- warnings.push(Warning::Pikchr(format!("{}", err)));
- error(err)
- }
- }
-}
-
-// Take a dot diagram, render it as SVG, and return an AST Block
-// element. The Block will contain the SVG data. This allows the
-// diagram to be rendered without referending external entities.
-pub fn dot_to_block(dot: &str, warnings: &mut Warnings) -> Block {
- match DotMarkup::new(dot).as_svg() {
- Ok(svg) => typeset_svg(svg),
- Err(err) => {
- warnings.push(Warning::Dot(format!("{}", err)));
- error(err)
- }
- }
-}
-
-// Take a PlantUML diagram, render it as SVG, and return an AST Block
-// element. The Block will contain the SVG data. This allows the
-// diagram to be rendered without referending external entities.
-pub fn plantuml_to_block(markup: &str, warnings: &mut Warnings) -> Block {
- match PlantumlMarkup::new(markup).as_svg() {
- Ok(svg) => typeset_svg(svg),
- Err(err) => {
- warnings.push(Warning::Plantuml(format!("{}", err)));
- error(err)
- }
- }
-}
-
-/// Typeset a project roadmap expressed as textual YAML, and render it
-/// as an SVG image.
-pub fn roadmap_to_block(yaml: &str, warnings: &mut Warnings) -> Block {
- match roadmap::from_yaml(yaml) {
- Ok(ref mut roadmap) => {
- roadmap.set_missing_statuses();
- let width = 50;
- match roadmap.format_as_dot(width) {
- Ok(dot) => dot_to_block(&dot, warnings),
- Err(e) => Block::Para(vec![inlinestr(&e.to_string())]),
- }
- }
- Err(e) => Block::Para(vec![inlinestr(&e.to_string())]),
- }
-}
-
-// Typeset an SVG, represented as a byte vector, as a Pandoc AST Block
-// element.
-fn typeset_svg(svg: Svg) -> Block {
- let url = svg_as_data_url(svg);
- let attr = ("".to_string(), vec![], vec![]);
- let img = Inline::Image(attr, vec![], (url, "".to_string()));
- Block::Para(vec![img])
-}
-
-// Convert an SVG, represented as a byte vector, into a data: URL,
-// which can be inlined so the image can be rendered without
-// referencing external files.
-fn svg_as_data_url(svg: Svg) -> String {
- let svg = base64::encode(svg.data());
- format!("data:image/svg+xml;base64,{}", svg)
-}