Skip to content

Commit

Permalink
feat: add text exporter
Browse files Browse the repository at this point in the history
  • Loading branch information
Myriad-Dreamin committed Nov 28, 2023
1 parent 4152027 commit d6154ff
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*.sir.in
*.pdf
*.rmp
*.txt
*.tsbuildinfo
/out.json

Expand Down
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ typst-ts-canvas-exporter = { version = "0.4.1-rc2", path = "exporter/canvas" }
typst-ts-raster-exporter = "0.4.1-rc1"
typst-ts-serde-exporter = "0.4.1-rc1"
typst-ts-svg-exporter = "0.4.1-rc1"
typst-ts-text-exporter = "0.4.1-rc1"

# project common components
typst-ts-dev-server = { version = "0.4.1-rc2", path = "server/dev" }
Expand All @@ -213,6 +214,7 @@ typst-ts-pdf-exporter = { path = "exporter/pdf" }
typst-ts-raster-exporter = { path = "exporter/raster" }
typst-ts-serde-exporter = { path = "exporter/serde" }
typst-ts-svg-exporter = { path = "exporter/svg" }
typst-ts-text-exporter = { path = "exporter/text" }

# typst = { git = "https://github.com/Myriad-Dreamin/typst.git", branch = "typst.ts-v0.9.0" }
# typst-library = { git = "https://github.com/Myriad-Dreamin/typst.git", branch = "typst.ts-v0.9.0" }
Expand Down
3 changes: 3 additions & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ typst-ts-pdf-exporter = { workspace = true, optional = true }
typst-ts-raster-exporter = { workspace = true, optional = true }
typst-ts-serde-exporter = { workspace = true, optional = true }
typst-ts-svg-exporter = { workspace = true, optional = true }
typst-ts-text-exporter = { workspace = true, optional = true }

[build-dependencies]
anyhow.workspace = true
Expand All @@ -70,12 +71,14 @@ svg = [
"typst-ts-svg-exporter",
"typst-ts-svg-exporter/experimental-ligature",
]
text = ["typst-ts-text-exporter"]
default = [
"pdf",
"raster",
"serde-json",
"serde-rmp",
"svg",
"text",
"gen-manual",
"embedded-fonts",
"embedded-cjk-fonts",
Expand Down
4 changes: 4 additions & 0 deletions cli/src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub static AVAILABLE_FORMATS: &[(/* format name */ &str, /* feature hint */ &str
("svg_html", "svg"),
("sir", "svg"),
("vector", "svg"),
("text", "text"),
];

/// Hint the user that the given format is not enable or not available.
Expand Down Expand Up @@ -93,6 +94,8 @@ fn prepare_exporters_impl(out: PathBuf, mut formats: Vec<String>) -> GroupDocExp
"sir" => sink_path!(WithSIR as _ as doc, out @@ "artifact.sir.in"),
#[cfg(feature = "svg")]
"vector" => sink_path!(WithSIR as _ as doc, out @@ "artifact.sir.in"),
#[cfg(feature = "text")]
"text" => sink_path!(WithText as _ as doc, out @@ "txt"),
_ => exit_by_unknown_format(f),
});
}
Expand All @@ -107,6 +110,7 @@ fn prepare_exporters_impl(out: PathBuf, mut formats: Vec<String>) -> GroupDocExp
type WithSvg = typst_ts_svg_exporter::PureSvgExporter;
type WithSvgHtml = typst_ts_svg_exporter::SvgExporter<DefaultExportFeature>;
type WithSIR = typst_ts_svg_exporter::SvgModuleExporter;
type WithText = typst_ts_text_exporter::TextExporter;

type ExporterVec<T> = Vec<Box<dyn typst_ts_core::Exporter<T> + Send>>;
}
Expand Down
14 changes: 14 additions & 0 deletions exporter/text/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "typst-ts-text-exporter"
description = "Export a frame of Typst document into plain text."
version.workspace = true
license.workspace = true
edition.workspace = true
homepage.workspace = true
repository.workspace = true

[dependencies]
typst.workspace = true
typst-ts-core.workspace = true

[features]
3 changes: 3 additions & 0 deletions exporter/text/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# typst-ts-text-exporter

See [Typst.ts](https://github.com/Myriad-Dreamin/typst.ts)
2 changes: 2 additions & 0 deletions exporter/text/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub(crate) mod text;
pub use text::TextExporter;
62 changes: 62 additions & 0 deletions exporter/text/src/text.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use core::fmt;
use std::io::Write;
use std::sync::Arc;

use typst_ts_core::exporter_utils::map_err;
use typst_ts_core::{Transformer, TypstDocument};

#[derive(Debug, Clone, Default)]
pub struct TextExporter {}

impl<W> Transformer<(Arc<TypstDocument>, W)> for TextExporter
where
W: std::io::Write,
{
fn export(
&self,
_world: &dyn typst::World,
(output, writer): (Arc<TypstDocument>, W),
) -> typst::diag::SourceResult<()> {
let mut w = std::io::BufWriter::new(writer);

write!(w, "{}", FullTextDigest(output)).map_err(map_err)?;

w.flush().unwrap();
Ok(())
}
}

struct FullTextDigest(Arc<TypstDocument>);

impl FullTextDigest {
fn export_frame(f: &mut fmt::Formatter<'_>, doc: &typst::doc::Frame) -> fmt::Result {
for (_, item) in doc.items() {
Self::export_item(f, item)?;
}

Ok(())
}

fn export_item(f: &mut fmt::Formatter<'_>, item: &typst::doc::FrameItem) -> fmt::Result {
use std::fmt::Write;
use typst::doc::FrameItem::*;
use typst::doc::Meta::*;
match item {
Group(g) => Self::export_frame(f, &g.frame),
Text(t) => f.write_str(t.text.as_str()),
Meta(ContentHint(c), _) => f.write_char(*c),
Meta(Link(..) | Elem(..) | PageNumbering(..) | PdfPageLabel(..) | Hide, _)
| Shape(..)
| Image(..) => Ok(()),
}
}
}

impl fmt::Display for FullTextDigest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for frame in self.0.pages.iter() {
Self::export_frame(f, &frame)?;
}
Ok(())
}
}

0 comments on commit d6154ff

Please sign in to comment.