Skip to content

Commit

Permalink
Added single file compilation
Browse files Browse the repository at this point in the history
  • Loading branch information
nricciardi committed Jul 11, 2024
1 parent e11f1f7 commit 9c02cfd
Show file tree
Hide file tree
Showing 16 changed files with 253 additions and 137 deletions.
4 changes: 2 additions & 2 deletions DEVELOP.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@
- [ ] Linkify (convert URL-like strings in links)
- [x] Fast draft (prevent to parse time consuming parts)
- [ ] Dynamics addons (e.g. katex iff math is used)
- [x] Watcher mode
- [ ] Watcher mode for single file compilation
- [ ] Split CLI lib from compiler
- [ ] Compile only modified chapters in watcher mode
- [x] Compile only a subset of documents
- [ ] Paper format support (A3, A5, ...)
- [x] MD to NMD converter
- [x] Include all .nmd file in running directory as default option in dossier configuration
- [ ] Compile single files
- [x] Compile single files
- [ ] Table of contents with page numbers
- [ ] Cover page
- [ ] VS Code extension (https://dev.to/salesforceeng/how-to-build-a-vs-code-extension-for-markdown-preview-using-remark-processor-1169)
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ nmd dossier -p dossier/input/path reset [ -p ]
Compile a dossier in `html`:

```shell
nmd compile dossier -f html -i dossier/input/path -o artifact/output/path
nmd compile -f html dossier -i dossier/input/path -o artifact/output/path
```

If you watch dossier files and compile them if anything changes, you should use watcher mode (`-w` option).
Expand Down
20 changes: 19 additions & 1 deletion src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ impl NmdCli {
.num_args(1)
.default_value("html")
)
.arg(
Arg::new("force-output")
.long("force")
.help("force output if destination not exists")
.action(ArgAction::SetTrue)
)
.arg(
Arg::new("theme")
.short('m')
Expand Down Expand Up @@ -110,6 +116,12 @@ impl NmdCli {
.help("fast draft instead of complete compilation")
.action(ArgAction::SetTrue)
)
.arg(
Arg::new("style-file")
.long("style-file")
.help("add style file")
.action(ArgAction::Append)
)
.subcommand(
Command::new("dossier")
.about("Compile NMD dossier")
Expand Down Expand Up @@ -333,6 +345,12 @@ impl NmdCli {

compilation_configuration.set_fast_draft(fast_draft);

compilation_configuration.set_force_output(matches.get_flag("force-output"));

if let Some(styles) = matches.get_many::<String>("style-file") {
compilation_configuration.set_styles_raw_path(styles.map(|s| s.clone()).collect());
}

match matches.subcommand() {
Some(("dossier", compile_dossier_matches)) => {

Expand Down Expand Up @@ -393,7 +411,7 @@ impl NmdCli {

} else {

compilation_configuration.set_output_location(compilation_configuration.input_location().clone());
compilation_configuration.set_output_location(compilation_configuration.input_location().parent().unwrap().to_path_buf());
}

if watch {
Expand Down
36 changes: 29 additions & 7 deletions src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ pub mod bibliography;
use std::{sync::{mpsc::{channel, RecvError}, Arc, RwLock}, thread, time::{Instant, SystemTime}};

use dossier::{dossier_configuration::DossierConfiguration, Document, Dossier};
use dumpable::DumpConfiguration;
use notify::{RecursiveMode, Watcher};
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use theme::Theme;
use thiserror::Error;
use crate::{compiler::{dumpable::{DumpError, Dumpable}, loader::Loader, parsable::Parsable}, constants::{DOSSIER_CONFIGURATION_JSON_FILE_NAME, DOSSIER_CONFIGURATION_YAML_FILE_NAME}};
use crate::{compiler::{dumpable::{DumpError, Dumpable}, loader::Loader, parsable::Parsable}, constants::{DOSSIER_CONFIGURATION_JSON_FILE_NAME, DOSSIER_CONFIGURATION_YAML_FILE_NAME}, utility::file_utility};
use self::{assembler::{assembler_configuration::AssemblerConfiguration, AssemblerError}, compilation_configuration::CompilationConfiguration, loader::LoadError, parsing::parsing_error::ParsingError};


Expand Down Expand Up @@ -110,7 +111,6 @@ impl Compiler {

dossier.parse(compilation_configuration.format(), Arc::clone(&codex), Arc::new(RwLock::new(parsing_configuration)), Arc::new(None))?;

assembler_configuration.set_output_location(compilation_configuration.output_location().clone());
assembler_configuration.set_theme(dossier_theme);

log::info!("assembling...");
Expand All @@ -123,7 +123,18 @@ impl Compiler {

log::info!("end to assembly (assembly time {} ms)", assembly_time.elapsed().as_millis());

artifact.dump()?;
let mut output_location = compilation_configuration.output_location().clone();

if output_location.is_dir() {
output_location = output_location.join(file_utility::build_output_file_name(
&dossier.name(),
Some(&compilation_configuration.format().get_extension())
));
}

let dump_configuration = DumpConfiguration::new(output_location, compilation_configuration.force_output());

artifact.dump(&dump_configuration)?;

log::info!("end to compile dossier (compile time: {} ms)", compile_start.elapsed().as_millis());

Expand Down Expand Up @@ -285,28 +296,39 @@ impl Compiler {

document.parse(compilation_configuration.format(), Arc::clone(&codex), Arc::new(RwLock::new(parsing_configuration)), Arc::new(None))?;

assembler_configuration.set_output_location(compilation_configuration.output_location().clone());
assembler_configuration.set_theme(compilation_configuration.theme().clone().unwrap_or(Theme::default()));

log::info!("assembling...");


let mut output_location = compilation_configuration.output_location().clone();

if output_location.is_dir() {
output_location = output_location.join(file_utility::build_output_file_name(
compilation_configuration.input_location().file_stem().unwrap().to_string_lossy().to_string().as_str(),
Some(&compilation_configuration.format().get_extension())
));
}

let assembly_time = Instant::now();

let assembler = assembler::from(compilation_configuration.format().clone(), assembler_configuration);

let mut artifact = assembler.assemble_document(compilation_configuration.output_location().clone(), &document)?;
let mut artifact = assembler.assemble_document_standalone(&output_location.file_name().unwrap().to_string_lossy().to_string(), Some(compilation_configuration.styles_raw_path()), None, None, &document)?;

log::info!("end to assembly (assembly time {} ms)", assembly_time.elapsed().as_millis());

artifact.dump()?;
let dump_configuration = DumpConfiguration::new(output_location, compilation_configuration.force_output());

artifact.dump(&dump_configuration)?;

log::info!("end to compile dossier (compile time: {} ms)", compile_start.elapsed().as_millis());

Ok(())
}

pub fn watch_compile_file(compilation_configuration: CompilationConfiguration, min_elapsed_time_between_events_in_secs: u64) -> Result<(), CompilationError> {
todo!()
unimplemented!("watch compile file will be added in a next version")
}

}
Expand Down
53 changes: 32 additions & 21 deletions src/compiler/artifact.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
pub mod artifact_assets;
pub mod artifacts_collection;

use std::path::PathBuf;
use std::fmt::Display;

use getset::{Getters, MutGetters, Setters};
use rayon::iter::{IntoParallelRefMutIterator, ParallelIterator};
use getset::{CopyGetters, Getters, MutGetters, Setters};
use thiserror::Error;


use crate::resource::{cached_disk_resource::CachedDiskResource, Resource, ResourceError};
use crate::resource::{disk_resource::DiskResource, Resource, ResourceError};

use self::artifact_assets::ArtifactAssets;

use super::dumpable::{Dumpable, DumpError};
use super::dumpable::{DumpConfiguration, DumpError, Dumpable};


#[derive(Error, Debug)]
Expand All @@ -25,35 +22,49 @@ pub enum ArtifactError {
ResourceError(#[from] ResourceError)
}

pub type ArtifactContent = String;


#[derive(Debug, Clone, Getters, MutGetters, Setters)]
#[derive(Debug, Clone, Getters, MutGetters, CopyGetters, Setters)]
pub struct Artifact {

#[getset(get = "pub", set = "pub")]
output_path: PathBuf,

#[getset(get = "pub", get_mut = "pub", set = "pub")]
content: CachedDiskResource,
content: ArtifactContent,
}

impl Artifact {
pub fn new(output_path: PathBuf) -> Result<Self, ArtifactError> {
pub fn new(content: ArtifactContent) -> Self {

Self {
content
}
}
}

Ok(Self {
content: CachedDiskResource::try_from(output_path.clone())?,
output_path
})
impl Display for Artifact {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.content)
}
}

impl Dumpable for Artifact {
fn dump(&mut self) -> Result<(), DumpError> {
fn dump(&mut self, configuration: &DumpConfiguration) -> Result<(), DumpError> {

log::info!("dump artifact...",);
log::info!("dump artifact in {:?}", configuration.output_path());

self.content.dump_cached_content();
let mut disk_resource = DiskResource::try_from(configuration.output_path().clone())?;

if configuration.force_dump() {
disk_resource.create_parents_dir()?;
}

disk_resource.write(&self.content)?;

Ok(())
}
}

impl Into<String> for Artifact {
fn into(self) -> String {
self.content
}
}
28 changes: 14 additions & 14 deletions src/compiler/artifact/artifacts_collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,23 @@ impl ArtifactsCollection {
// }
}

impl Dumpable for ArtifactsCollection {
fn dump(&mut self) -> Result<(), DumpError> {
// impl Dumpable for ArtifactsCollection {
// fn dump(&mut self) -> Result<(), DumpError> {

log::info!("dump artifacts collection...",);
// log::info!("dump artifacts collection...",);

let error = self.artifacts.par_iter_mut().map(|artifact| {
// let error = self.artifacts.par_iter_mut().map(|artifact| {

log::info!("dumping artifact in {:?}", artifact.output_path());
// log::info!("dumping artifact in {:?}", artifact.output_path());

artifact.dump()
})
.find_any(|result| result.is_err());
// artifact.dump()
// })
// .find_any(|result| result.is_err());

if let Some(error) = error {
return Err(error.err().unwrap());
}
// if let Some(error) = error {
// return Err(error.err().unwrap());
// }

Ok(())
}
}
// Ok(())
// }
// }
18 changes: 6 additions & 12 deletions src/compiler/assembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::resource::{Resource, ResourceError};

use self::{html_assembler::HtmlAssembler, assembler_configuration::AssemblerConfiguration};

use super::{artifact::{Artifact, ArtifactError}, dossier::{Document, Dossier}, output_format::OutputFormat, parsing::parsing_error::ParsingError};
use super::{artifact::{Artifact, ArtifactError}, bibliography::Bibliography, dossier::{Document, Dossier}, output_format::OutputFormat, parsing::parsing_error::ParsingError, table_of_contents::TableOfContents};

pub mod html_assembler;
pub mod assembler_configuration;
Expand Down Expand Up @@ -36,10 +36,9 @@ pub trait Assembler {

fn set_configuration(&mut self, configuration: AssemblerConfiguration);

fn assemble_dossier(&self, /*codex: &Codex,*/ dossier: &Dossier) -> Result<Artifact, AssemblerError>;
fn assemble_dossier(&self, dossier: &Dossier) -> Result<Artifact, AssemblerError>;

/// Assemble document in only one `String`
fn assemble_document_into_string(&self, document: &Document) -> Result<String, AssemblerError> {
fn assemble_document(&self, document: &Document) -> Result<Artifact, AssemblerError> {

let mut result = String::new();

Expand Down Expand Up @@ -78,17 +77,12 @@ pub trait Assembler {
}
}

Ok(result)
Ok(Artifact::new(result))

}

fn assemble_document(&self, output_path: PathBuf, document: &Document) -> Result<Artifact, AssemblerError> {

let mut artifact = Artifact::new(output_path)?;

artifact.content_mut().write(&self.assemble_document_into_string(document)?)?;

Ok(artifact)
fn assemble_document_standalone(&self, page_title: &String, styles_references: Option<&Vec<String>>, toc: Option<&TableOfContents>, bibliography: Option<&Bibliography>, document: &Document) -> Result<Artifact, AssemblerError> {
self.assemble_document(document)
}
}

Expand Down
19 changes: 8 additions & 11 deletions src/compiler/assembler/assembler_configuration.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
use std::{ffi::OsStr, path::PathBuf};

use getset::{CopyGetters, Getters, Setters};

use crate::compiler::{dossier::dossier_configuration::{self, DossierConfiguration}, theme::Theme};
use crate::compiler::{dossier::dossier_configuration::DossierConfiguration, theme::Theme};

#[derive(Debug, Getters, CopyGetters, Setters)]
pub struct AssemblerConfiguration {

#[getset(get = "pub", set = "pub")]
output_location: PathBuf,

#[getset(get = "pub", set = "pub")]
theme: Theme,

Expand All @@ -19,27 +14,29 @@ pub struct AssemblerConfiguration {
#[getset(get_copy = "pub", set = "pub")]
parallelization: bool,

#[getset(get = "pub", set = "pub")]
styles_raw_path: Vec<String>,
}

impl AssemblerConfiguration {

pub fn new(output_location: PathBuf, theme: Theme, use_remote_addons: bool, parallelization: bool) -> Self {
pub fn new(theme: Theme, use_remote_addons: bool, parallelization: bool) -> Self {
Self {
output_location,
theme,
use_remote_addons,
parallelization
parallelization,
styles_raw_path: Vec::new(),
}
}
}

impl Default for AssemblerConfiguration {
fn default() -> Self {
Self {
output_location: Default::default(),
theme: Theme::default(),
use_remote_addons: false,
parallelization: false
parallelization: false,
styles_raw_path: Vec::new(),
}
}
}
Expand Down
Loading

0 comments on commit 9c02cfd

Please sign in to comment.