summaryrefslogtreecommitdiff
path: root/subplot/riki.rs
blob: 9575b555db42c4af85697121b657884a465a9e85 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use pandoc_ast::{Inline, MutVisitor, Pandoc};
use std::path::Path;
use subplotlib::steplibrary::runcmd::Runcmd;
use subplotlib::steplibrary::datadir::Datadir;

#[step]
#[context(Runcmd)]
fn install_riki(context: &ScenarioContext) {
    // The RIKI_DIR variable can be set to test an installed riki
    // rather than the one built from the source tree.
    if let Some(bindir) = std::env::var_os("RIKI_DIR") {
        println!("Found RIKI_DIR environment variable, using that");
        context.with_mut(
            |rc: &mut Runcmd| {
                rc.prepend_to_path(bindir);
                Ok(())
            },
            false,
        )?;
    } else {
        let target_exe = env!("CARGO_BIN_EXE_riki");
        let target_path = Path::new(target_exe);
        let target_path = target_path.parent().ok_or("No parent?")?;

        context.with_mut(
            |context: &mut Runcmd| {
                context.prepend_to_path(target_path);
                Ok(())
            },
            false,
        )?;
    }
}

#[step]
#[context(Datadir)]
fn asts_match(context: &Datadir, first: &str, second: &str) {
    let first = context.canonicalise_filename(first).unwrap();
    let second = context.canonicalise_filename(second).unwrap();
    let first = ast(first);
    let second = ast(second);
    println!();
    println!("first:  {:#?}", first);
    println!("second: {:#?}", second);
    println!("first:  {:?}", first);
    println!("second: {:?}", second);
    assert!(first == second);
}

fn ast<P: AsRef<Path>>(filename: P) -> Pandoc {
    let filename = filename.as_ref();
    assert!(filename.exists());

    let data = std::fs::read(filename).unwrap();
    let data = String::from_utf8_lossy(&data);
    println!("{}: {:?}", filename.display(), data);

    let mut pandoc = pandoc::new();
    pandoc.add_input(&filename);
    pandoc.set_output_format(pandoc::OutputFormat::Json, vec![]);
    pandoc.set_output(pandoc::OutputKind::Pipe);
    let pandoc = pandoc.execute().unwrap();
    let json = match pandoc {
        pandoc::PandocOutput::ToFile(x) => panic!("to file: {:?}", x),
        pandoc::PandocOutput::ToBuffer(x) => x,
        pandoc::PandocOutput::ToBufferRaw(x) => panic!("to raw buffer: {:?}", x),
    };
    let mut json = serde_json::from_str(&json).unwrap();
    let mut fix = DropImageFigTitle {};
    fix.walk_pandoc(&mut json);
    json
}

// For some reason, Pandoc adds to an Inline::Image element a spurious
// "fig:" as the second half of the 'target' tuple, when parsing
// Markdown, but when parsing HTML. This makes tests fail. Avoid that.
struct DropImageFigTitle {}

impl MutVisitor for DropImageFigTitle {
    fn visit_inline(&mut self, inline: &mut Inline) {
        if let Inline::Image(attr, alt, target) = inline {
            if target.1 == "fig:" {
                *inline = Inline::Image(attr.clone(), alt.to_vec(), (target.0.clone(), "".into()));
            } else if let Some(rest) = target.1.strip_prefix("fig:") {
                *inline = Inline::Image(attr.clone(), alt.to_vec(), (target.0.clone(), rest.into()));
            }
        }
    }
}