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
90
91
92
93
94
95
96
97
98
#![recursion_limit = "1000"]
#[macro_use]
extern crate log;
extern crate codeviz_common;
extern crate reproto_backend;
extern crate pulldown_cmark;

#[macro_use]
mod macros;
mod doc_backend;
mod doc_builder;
mod doc_collector;
mod doc_compiler;
mod doc_listeners;
mod doc_options;
mod doc_writer;
mod escape;

pub(crate) use reproto_backend::errors::*;
pub(crate) use reproto_backend::imports::*;
pub(crate) use self::doc_backend::*;
pub(crate) use self::doc_builder::*;
pub(crate) use self::doc_collector::*;
pub(crate) use self::doc_compiler::*;
pub(crate) use self::doc_listeners::*;
pub(crate) use self::doc_options::*;
pub(crate) use self::doc_writer::*;
pub(crate) use self::escape::*;

pub(crate) const NORMALIZE_CSS_NAME: &str = "normalize.css";
pub(crate) const DOC_CSS_NAME: &str = "doc.css";
pub(crate) const EXT: &str = "html";
pub(crate) const INDEX: &str = "index";
pub(crate) const DEFAULT_THEME: &str = "light";

fn setup_module(module: &str) -> Result<Box<DocListeners>> {
    let _module: Box<DocListeners> = match module {
        _ => return Err(format!("No such module: {}", module).into()),
    };
}

pub fn setup_listeners(options: Options) -> Result<(DocOptions, Box<DocListeners>)> {
    let mut listeners: Vec<Box<DocListeners>> = Vec::new();

    for module in &options.modules {
        listeners.push(setup_module(module)?);
    }

    let mut options = DocOptions::new();

    for listener in &listeners {
        listener.configure(&mut options)?;
    }

    Ok((options, Box::new(listeners)))
}

pub fn shared_options<'a, 'b>(out: App<'a, 'b>) -> App<'a, 'b> {
    let out = out.arg(Arg::with_name("theme")
        .long("theme")
        .takes_value(true)
        .help("Theme to use"));

    let out = out.arg(Arg::with_name("skip_static")
        .long("skip-static")
        .help("Skip building with static files"));

    out
}

pub fn compile_options<'a, 'b>(out: App<'a, 'b>) -> App<'a, 'b> {
    shared_options(out).about("Compile Documentation")
}

pub fn verify_options<'a, 'b>(out: App<'a, 'b>) -> App<'a, 'b> {
    shared_options(out).about("Verify for Documentation")
}

pub fn compile(env: Environment,
               options: Options,
               compiler_options: CompilerOptions,
               matches: &ArgMatches)
               -> Result<()> {
    let theme = matches.value_of("theme").unwrap_or(DEFAULT_THEME).to_owned();
    let skip_static = matches.is_present("skip_static");

    let (options, listeners) = setup_listeners(options)?;
    let backend = DocBackend::new(env, options, listeners, theme);
    let compiler = DocCompiler::new(&backend, compiler_options.out_path, skip_static);
    compiler.compile()
}

pub fn verify(env: Environment, options: Options, _matches: &ArgMatches) -> Result<()> {
    let theme = String::from("light");
    let (options, listeners) = setup_listeners(options)?;
    let backend = DocBackend::new(env, options, listeners, theme);
    backend.verify()
}