mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-11-26 22:04:56 +00:00
refactor: tidy up main and let converter know the target (#1729)
This commit is contained in:
parent
d85bd7428a
commit
e4ed9defb1
4 changed files with 48 additions and 111 deletions
|
|
@ -15,8 +15,9 @@ pub enum ListState {
|
|||
}
|
||||
|
||||
/// Valid formats for the conversion.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Format {
|
||||
#[default]
|
||||
Md,
|
||||
LaTeX,
|
||||
#[cfg(feature = "docx")]
|
||||
|
|
|
|||
|
|
@ -127,6 +127,8 @@ pub struct TypliteFeat {
|
|||
pub soft_error: bool,
|
||||
/// Remove HTML tags from the output.
|
||||
pub remove_html: bool,
|
||||
/// The target to convert
|
||||
pub target: Format,
|
||||
}
|
||||
|
||||
/// Task builder for converting a typst document to Markdown.
|
||||
|
|
@ -166,8 +168,8 @@ impl Typlite {
|
|||
/// Convert the content to a markdown string.
|
||||
pub fn convert(self) -> Result<ecow::EcoString> {
|
||||
match self.format {
|
||||
Format::Md => self.convert_doc()?.to_md_string(),
|
||||
Format::LaTeX => self.convert_doc()?.to_tex_string(true),
|
||||
Format::Md => self.convert_doc(Format::Md)?.to_md_string(),
|
||||
Format::LaTeX => self.convert_doc(Format::LaTeX)?.to_tex_string(true),
|
||||
#[cfg(feature = "docx")]
|
||||
Format::Docx => Err("docx format is not supported".into()),
|
||||
}
|
||||
|
|
@ -179,11 +181,11 @@ impl Typlite {
|
|||
if self.format != Format::Docx {
|
||||
return Err("format is not DOCX".into());
|
||||
}
|
||||
self.convert_doc()?.to_docx()
|
||||
self.convert_doc(Format::Docx)?.to_docx()
|
||||
}
|
||||
|
||||
/// Convert the content to a markdown document.
|
||||
pub fn convert_doc(self) -> Result<MarkdownDocument> {
|
||||
pub fn convert_doc(self, format: Format) -> Result<MarkdownDocument> {
|
||||
let entry = self.world.entry_state();
|
||||
let main = entry.main();
|
||||
let current = main.ok_or("no main file in workspace")?;
|
||||
|
|
@ -236,7 +238,9 @@ impl Typlite {
|
|||
let base = typst::compile(&world)
|
||||
.output
|
||||
.map_err(|err| format!("convert source for main file: {err:?}"))?;
|
||||
Ok(MarkdownDocument::new(base, self.feat))
|
||||
let mut feat = self.feat;
|
||||
feat.target = format;
|
||||
Ok(MarkdownDocument::new(base, feat))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use clap::Parser;
|
|||
use tinymist_project::WorldProvider;
|
||||
use typlite::{common::Format, TypliteFeat};
|
||||
use typlite::{CompileOnceArgs, Typlite};
|
||||
use typst::foundations::Bytes;
|
||||
|
||||
/// Common arguments of compile, watch, and query.
|
||||
#[derive(Debug, Clone, Parser, Default)]
|
||||
|
|
@ -17,9 +18,9 @@ pub struct CompileArgs {
|
|||
#[clap(flatten)]
|
||||
pub compile: CompileOnceArgs,
|
||||
|
||||
/// Path to output file(s)
|
||||
#[clap(value_name = "OUTPUT", action = clap::ArgAction::Append)]
|
||||
pub outputs: Vec<String>,
|
||||
/// Path to output file
|
||||
#[clap(value_name = "OUTPUT", default_value = None)]
|
||||
pub output: Option<String>,
|
||||
|
||||
/// Configures the path of assets directory
|
||||
#[clap(long, default_value = None, value_name = "ASSETS_PATH")]
|
||||
|
|
@ -36,13 +37,17 @@ fn main() -> typlite::Result<()> {
|
|||
.as_ref()
|
||||
.ok_or("Missing required argument: INPUT")?;
|
||||
|
||||
let outputs = if args.outputs.is_empty() {
|
||||
vec![Path::new(input)
|
||||
.with_extension("md")
|
||||
.to_string_lossy()
|
||||
.to_string()]
|
||||
} else {
|
||||
args.outputs.clone()
|
||||
let is_stdout = args.output.as_deref() == Some("-");
|
||||
let output_path = args
|
||||
.output
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|| Path::new(input).with_extension("md"));
|
||||
|
||||
let output_format = match output_path.extension() {
|
||||
Some(ext) if ext == std::ffi::OsStr::new("tex") => Format::LaTeX,
|
||||
#[cfg(feature = "docx")]
|
||||
Some(ext) if ext == std::ffi::OsStr::new("docx") => Format::Docx,
|
||||
_ => Format::Md,
|
||||
};
|
||||
|
||||
let assets_path = match args.assets_path {
|
||||
|
|
@ -65,102 +70,22 @@ fn main() -> typlite::Result<()> {
|
|||
assets_path: assets_path.clone(),
|
||||
..Default::default()
|
||||
});
|
||||
let doc = match converter.convert_doc() {
|
||||
Ok(doc) => doc,
|
||||
Err(err) => return Err(format!("failed to convert document: {err}").into()),
|
||||
};
|
||||
let doc = converter.convert_doc(output_format)?;
|
||||
|
||||
for output_path in &outputs {
|
||||
let is_stdout = output_path == "-";
|
||||
let output = if is_stdout {
|
||||
None
|
||||
} else {
|
||||
Some(PathBuf::from(output_path))
|
||||
};
|
||||
|
||||
let format = match &output {
|
||||
Some(output) if output.extension() == Some(std::ffi::OsStr::new("tex")) => {
|
||||
Format::LaTeX
|
||||
}
|
||||
let result = match output_format {
|
||||
Format::Md => Bytes::from_string(doc.to_md_string()?),
|
||||
Format::LaTeX => Bytes::from_string(doc.to_tex_string(true)?),
|
||||
#[cfg(feature = "docx")]
|
||||
Some(output) if output.extension() == Some(std::ffi::OsStr::new("docx")) => {
|
||||
Format::Docx
|
||||
}
|
||||
_ => Format::Md,
|
||||
Format::Docx => Bytes::new(doc.to_docx()?),
|
||||
};
|
||||
|
||||
match format {
|
||||
#[cfg(feature = "docx")]
|
||||
Format::Docx => {
|
||||
let docx_data = match doc.to_docx() {
|
||||
Ok(data) => data,
|
||||
Err(err) => {
|
||||
eprintln!("Error generating DOCX for {}: {}", output_path, err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
match output {
|
||||
None => {
|
||||
eprintln!("output file is required for DOCX format");
|
||||
continue;
|
||||
}
|
||||
Some(output) => {
|
||||
if let Err(err) = std::fs::write(&output, docx_data) {
|
||||
eprintln!("failed to write DOCX file {}: {}", output.display(), err);
|
||||
continue;
|
||||
}
|
||||
println!("Generated DOCX file: {}", output.display());
|
||||
}
|
||||
}
|
||||
}
|
||||
Format::LaTeX => {
|
||||
let result = doc.to_tex_string(true);
|
||||
match (result, output) {
|
||||
(Ok(content), None) => {
|
||||
std::io::stdout()
|
||||
.write_all(content.as_str().as_bytes())
|
||||
.unwrap();
|
||||
}
|
||||
(Ok(content), Some(output)) => {
|
||||
if let Err(err) = std::fs::write(&output, content.as_str()) {
|
||||
eprintln!("failed to write LaTeX file {}: {}", output.display(), err);
|
||||
continue;
|
||||
}
|
||||
println!("Generated LaTeX file: {}", output.display());
|
||||
}
|
||||
(Err(err), _) => {
|
||||
eprintln!("Error converting to LaTeX for {}: {}", output_path, err);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
Format::Md => {
|
||||
let result = doc.to_md_string();
|
||||
match (result, output) {
|
||||
(Ok(content), None) => {
|
||||
std::io::stdout()
|
||||
.write_all(content.as_str().as_bytes())
|
||||
.unwrap();
|
||||
}
|
||||
(Ok(content), Some(output)) => {
|
||||
if let Err(err) = std::fs::write(&output, content.as_str()) {
|
||||
eprintln!(
|
||||
"failed to write Markdown file {}: {}",
|
||||
output.display(),
|
||||
err
|
||||
);
|
||||
continue;
|
||||
}
|
||||
println!("Generated Markdown file: {}", output.display());
|
||||
}
|
||||
(Err(err), _) => {
|
||||
eprintln!("Error converting to Markdown for {}: {}", output_path, err);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if is_stdout {
|
||||
std::io::stdout().write_all(result.as_slice()).unwrap();
|
||||
} else if let Err(err) = std::fs::write(&output_path, result.as_slice()) {
|
||||
Err(format!(
|
||||
"failed to write file {}: {err}",
|
||||
output_path.display()
|
||||
))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -81,6 +81,13 @@ impl ConvKind {
|
|||
ConvKind::LaTeX => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn kind(&self) -> Format {
|
||||
match self {
|
||||
ConvKind::Md { .. } => Format::Md,
|
||||
ConvKind::LaTeX => Format::LaTeX,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn conv(world: LspWorld, kind: ConvKind) -> String {
|
||||
|
|
@ -88,7 +95,7 @@ fn conv(world: LspWorld, kind: ConvKind) -> String {
|
|||
annotate_elem: kind.for_docs(),
|
||||
..Default::default()
|
||||
});
|
||||
let doc = match converter.convert_doc() {
|
||||
let doc = match converter.convert_doc(kind.kind()) {
|
||||
Ok(doc) => doc,
|
||||
Err(err) => return format!("failed to convert to markdown: {err}"),
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue