Skip to content

Commit 4e0c6bf

Browse files
committed
Move the module definitions and handling into a separate file
1 parent e71b6f4 commit 4e0c6bf

File tree

2 files changed

+220
-215
lines changed

2 files changed

+220
-215
lines changed

src/main.rs

Lines changed: 4 additions & 215 deletions
Original file line numberDiff line numberDiff line change
@@ -5,61 +5,14 @@ use std::path::PathBuf;
55
use colored::*;
66

77
mod cmd_line;
8+
mod module;
89

9-
// Load the AsciiDoc templates at build time
10-
const ASSEMBLY_TEMPLATE: &str = include_str!("../templates/assembly.adoc");
11-
const CONCEPT_TEMPLATE: &str = include_str!("../templates/concept.adoc");
12-
const PROCEDURE_TEMPLATE: &str = include_str!("../templates/procedure.adoc");
13-
const REFERENCE_TEMPLATE: &str = include_str!("../templates/reference.adoc");
10+
use module::{Module, ModuleType};
1411

15-
/// All possible types of the AsciiDoc module
16-
#[derive(Debug)]
17-
enum ModuleType {
18-
Assembly,
19-
Concept,
20-
Procedure,
21-
Reference,
22-
}
23-
24-
/// A representation of the module with all its metadata and the generated AsciiDoc content
25-
#[derive(Debug)]
26-
struct Module {
27-
mod_type: ModuleType,
28-
title: String,
29-
id: String,
30-
file_name: String,
31-
include_statement: String,
32-
text: String,
33-
}
34-
35-
impl Module {
36-
/// The constructor for the Module struct
37-
pub fn new(
38-
mod_type: ModuleType,
39-
title: &str,
40-
includes: Option<&[String]>,
41-
options: &Options,
42-
) -> Module {
43-
let title = String::from(title);
44-
let id = Module::convert_title_to_id(&title);
45-
let file_name = Module::compose_file_name(&id, &mod_type, &options);
46-
let include_statement = Module::compose_include_statement(&file_name);
47-
let text = Module::compose_text(&title, &id, &mod_type, includes, &options);
48-
49-
Module {
50-
mod_type,
51-
title,
52-
id,
53-
file_name,
54-
include_statement,
55-
text,
56-
}
57-
}
58-
}
5912

6013
/// This struct stores options based on the command-line arguments,
6114
/// and is passed to various functions across the program.
62-
struct Options {
15+
pub struct Options {
6316
comments: bool,
6417
prefixes: bool,
6518
target_dir: String,
@@ -149,171 +102,6 @@ fn process_module_type(titles: clap::Values, module_type_str: &str, options: &Op
149102
modules_from_type
150103
}
151104

152-
impl Module {
153-
/// Create an ID string that is derived from the human-readable title. The ID is usable as:
154-
///
155-
/// * An AsciiDoc section ID
156-
/// * A DocBook section ID
157-
/// * A file name
158-
///
159-
/// ## Examples
160-
///
161-
/// ```
162-
/// let title = "Testing newdoc";
163-
/// assert_eq!(String::from("testing-newdoc"), Module::convert_title_to_id(title));
164-
/// ```
165-
fn convert_title_to_id(title: &str) -> String {
166-
// The ID is all lower-case
167-
let mut title_with_replacements = String::from(title).to_lowercase();
168-
169-
// Replace characters that aren't allowed in the ID, usually with a dash or an empty string
170-
let substitutions = [
171-
(" ", "-"),
172-
("(", ""),
173-
(")", ""),
174-
("?", ""),
175-
("!", ""),
176-
("'", ""),
177-
("\"", ""),
178-
("#", ""),
179-
("%", ""),
180-
("&", ""),
181-
("*", ""),
182-
(",", ""),
183-
(".", "-"),
184-
("/", "-"),
185-
(":", "-"),
186-
(";", ""),
187-
("@", "-at-"),
188-
("\\", ""),
189-
("`", ""),
190-
("$", ""),
191-
("^", ""),
192-
("|", ""),
193-
// Remove known semantic markup from the ID:
194-
("[package]", ""),
195-
("[option]", ""),
196-
("[parameter]", ""),
197-
("[variable]", ""),
198-
("[command]", ""),
199-
("[replaceable]", ""),
200-
("[filename]", ""),
201-
("[literal]", ""),
202-
("[systemitem]", ""),
203-
("[application]", ""),
204-
("[function]", ""),
205-
("[gui]", ""),
206-
// Remove square brackets only after semantic markup:
207-
("[", ""),
208-
("]", ""),
209-
// TODO: Curly braces shouldn't appear in the title in the first place.
210-
// They'd be interpreted as attributes there.
211-
// Print an error in that case? Escape them with AciiDoc escapes?
212-
("{", ""),
213-
("}", ""),
214-
];
215-
216-
// Perform all the defined replacements on the title
217-
for (old, new) in substitutions.iter() {
218-
title_with_replacements = title_with_replacements.replace(old, new);
219-
}
220-
221-
// Make sure the converted ID doesn't contain double dashes ("--"), because
222-
// that breaks references to the ID
223-
while title_with_replacements.contains("--") {
224-
title_with_replacements = title_with_replacements.replace("--", "-");
225-
}
226-
227-
title_with_replacements
228-
}
229-
230-
/// Perform string replacements in the modular template that matches the `ModuleType`.
231-
/// Return the template text with all replacements.
232-
fn compose_text(
233-
title: &str,
234-
module_id: &str,
235-
module_type: &ModuleType,
236-
includes: Option<&[String]>,
237-
options: &Options,
238-
) -> String {
239-
// TODO: Add a comment in the generated file with a pre-filled include statement
240-
241-
// Pick the right template
242-
let current_template = match module_type {
243-
ModuleType::Assembly => ASSEMBLY_TEMPLATE,
244-
ModuleType::Concept => CONCEPT_TEMPLATE,
245-
ModuleType::Procedure => PROCEDURE_TEMPLATE,
246-
ModuleType::Reference => REFERENCE_TEMPLATE,
247-
};
248-
249-
// Define the strings that will be replaced in the template
250-
let replacements = [("${module_title}", title), ("${module_id}", module_id)];
251-
252-
// Perform substitutions in the template
253-
// TODO: Create a separate function to perform a replacement
254-
let mut template_with_replacements = String::from(current_template);
255-
256-
for (old, new) in replacements.iter() {
257-
template_with_replacements = template_with_replacements.replace(old, new);
258-
}
259-
260-
if let Some(includes) = includes {
261-
// The includes should never be empty thanks to the required group in clap
262-
assert!(!includes.is_empty());
263-
// Join the includes into a block of text, with blank lines in between to prevent
264-
// the AsciiDoc syntax to blend between modules
265-
let includes_text = includes.join("\n\n");
266-
267-
template_with_replacements =
268-
template_with_replacements.replace("${include_statements}", &includes_text);
269-
} else {
270-
template_with_replacements = template_with_replacements
271-
.replace("${include_statements}", "Include modules here.");
272-
}
273-
274-
// If comments are disabled via an option, delete comment lines from the content
275-
// TODO: This doesn't handle AsciiDoc comment blocks at all
276-
if !options.comments {
277-
// Filter out comment lines in an iterator
278-
let lines = template_with_replacements
279-
.lines()
280-
.filter(|line| !line.starts_with("//"));
281-
// Connect the iterator back into a String, connecting with newlines
282-
template_with_replacements = lines.collect::<Vec<&str>>().join("\n");
283-
// Add a final newline at the end of the file
284-
template_with_replacements.push('\n');
285-
}
286-
287-
template_with_replacements
288-
}
289-
290-
/// Prepare the file name for the generated file.
291-
///
292-
/// The file name is based on the module ID, with the `.adoc` extension and an optional prefix.
293-
fn compose_file_name(module_id: &str, module_type: &ModuleType, options: &Options) -> String {
294-
let prefix = if options.prefixes {
295-
// If prefixes are enabled, pick the right file prefix
296-
match module_type {
297-
ModuleType::Assembly => "assembly_",
298-
ModuleType::Concept => "con_",
299-
ModuleType::Procedure => "proc_",
300-
ModuleType::Reference => "ref_",
301-
}
302-
} else {
303-
// If prefixes are disabled, use an empty string for the prefix
304-
""
305-
};
306-
307-
let suffix = ".adoc";
308-
309-
[prefix, module_id, suffix].join("")
310-
}
311-
312-
/// Prepare an include statement that can be used to include the generated file from elsewhere.
313-
fn compose_include_statement(file_name: &str) -> String {
314-
format!("include::<path>/{}[leveloffset=+1]", file_name)
315-
}
316-
}
317105

318106
/// Write the generated module content to the path specified in `options` with the set file name.
319107
// fn write_module(file_name: &str, content: &str, options: &Options) {
@@ -367,3 +155,4 @@ fn write_module(module: &Module, options: &Options) {
367155
}
368156
}
369157
}
158+

0 commit comments

Comments
 (0)