diff --git a/Cargo.lock b/Cargo.lock
index c6be5de..1e3034e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -554,29 +554,6 @@ dependencies = [
"syn",
]
-[[package]]
-name = "env_filter"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef"
-dependencies = [
- "log",
- "regex",
-]
-
-[[package]]
-name = "env_logger"
-version = "0.11.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a"
-dependencies = [
- "anstream",
- "anstyle",
- "env_filter",
- "jiff",
- "log",
-]
-
[[package]]
name = "equivalent"
version = "1.0.2"
@@ -1173,25 +1150,6 @@ version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09e54e57b4c48b40f7aec75635392b12b3421fa26fe8b4332e63138ed278459c"
-[[package]]
-name = "include_dir"
-version = "0.7.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd"
-dependencies = [
- "include_dir_macros",
-]
-
-[[package]]
-name = "include_dir_macros"
-version = "0.7.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75"
-dependencies = [
- "proc-macro2",
- "quote",
-]
-
[[package]]
name = "indexmap"
version = "2.14.0"
@@ -1222,30 +1180,6 @@ version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
-[[package]]
-name = "jiff"
-version = "0.2.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f00b5dbd620d61dfdcb6007c9c1f6054ebd75319f163d886a9055cec1155073d"
-dependencies = [
- "jiff-static",
- "log",
- "portable-atomic",
- "portable-atomic-util",
- "serde_core",
-]
-
-[[package]]
-name = "jiff-static"
-version = "0.2.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e000de030ff8022ea1da3f466fbb0f3a809f5e51ed31f6dd931c35181ad8e6d7"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
[[package]]
name = "js-sys"
version = "0.3.77"
@@ -1407,9 +1341,9 @@ dependencies = [
[[package]]
name = "log"
-version = "0.4.29"
+version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
+checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "memchr"
@@ -1656,15 +1590,6 @@ version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
-[[package]]
-name = "portable-atomic-util"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618"
-dependencies = [
- "portable-atomic",
-]
-
[[package]]
name = "postcard"
version = "1.1.1"
@@ -1848,9 +1773,9 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.12.3"
+version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
@@ -1860,9 +1785,9 @@ dependencies = [
[[package]]
name = "regex-automata"
-version = "0.4.14"
+version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
+checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
@@ -2413,9 +2338,6 @@ name = "typssg"
version = "0.1.0"
dependencies = [
"clap",
- "env_logger",
- "include_dir",
- "log",
"typst",
"typst-as-lib",
"typst-html",
diff --git a/Cargo.toml b/Cargo.toml
index 28eeeb5..fd7f150 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,10 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-include_dir = "0.7.4"
clap = { version = "4.6.1", features = ["derive"] }
-env_logger = "0.11.10"
-log = "0.4.29"
typst = "0.14.2"
typst-as-lib = { version = "0.15.4", features = ["typst-html", "typst-kit-fonts", "typst-kit-embed-fonts"] }
typst-html = "0.14.2"
diff --git a/build.rs b/build.rs
deleted file mode 100644
index e5458ff..0000000
--- a/build.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-fn main() {
- println!("cargo:rerun-if-changed=prepends/");
-}
diff --git a/common.typ b/common.typ
new file mode 100644
index 0000000..eabfd0a
--- /dev/null
+++ b/common.typ
@@ -0,0 +1,8 @@
+#let image(source, width: "400px") = {
+ html.elem("img", attrs: (
+ src: "/static/articles/" + source,
+ alt: source,
+ width: str(width),
+ ))
+}
+
diff --git a/prepends/bibliography.typ b/prepends/bibliography.typ
deleted file mode 100644
index f72b036..0000000
--- a/prepends/bibliography.typ
+++ /dev/null
@@ -1,17 +0,0 @@
-// By default, bibliography titles render with a level 1 heading. Typssg
-// rather assumes that lvl 1 headings are just for page titles, and that
-// section titles are denoted with lvl 2 headings.
-#let _bibliography = bibliography
-#let refs(content) = {
- heading(level: 2, "References")
- _bibliography(bytes(content.text), style: "ieee", title: none)
-}
-
-// Override default bibliography so that users don't accidentally use it
-#let bibliography = (path, ..args) => {
- text[This project has enabled the bibliography extension which provides the `#refs()` funciton for convenient in-file bibliographies. If you _did_ intend to use the default bibliography function, call it instead with `#_bibliography().`]
-}
-
-// Have in-text citations appear as just numbers, instead of the IEEE default
-// style of [#] with brackets.
-#set cite(style: "vancouver-superscript")
diff --git a/prepends/card.typ b/prepends/card.typ
deleted file mode 100644
index 25cc3e0..0000000
--- a/prepends/card.typ
+++ /dev/null
@@ -1,22 +0,0 @@
-#let card(
- caption: "",
- media: (),
- score: 0,
- defense: "",
- offense: "",
-) = {
- text[= #caption (Card)
-
- #html.elem("div", attrs: (class: "card"))[
- #media.at(0)
- ]
-
- score: #score
-
- == Defense
- #defense
-
- == Offense
- #offense
- ]
-}
diff --git a/prepends/figure.typ b/prepends/figure.typ
deleted file mode 100644
index 73ec4c8..0000000
--- a/prepends/figure.typ
+++ /dev/null
@@ -1,19 +0,0 @@
-// Given a figure with an image, this show rule will wrap the image in a link
-// that goes to the full version of the pic. For example, image("bird.jpg")
-// will get wrapped in a #link("bird_full.jpg"). This, of course, assumes
-// bird_full.jpg also exists in the directory.
-#show figure: it => {
- if it.body.func() == image {
- let src = it.body.source
- let dot-pos = src.rev().position(".")
- let full-src = if dot-pos != none {
- src.slice(0, src.len() - dot-pos - 1) + "_full" + src.slice(src.len() - dot-pos - 1)
- } else {
- src + "_full"
- }
- show image: img => link(full-src, img)
- it
- } else {
- it
- }
-}
diff --git a/prepends/link.typ b/prepends/link.typ
deleted file mode 100644
index ad107f9..0000000
--- a/prepends/link.typ
+++ /dev/null
@@ -1,15 +0,0 @@
-// Adds an "internal" class to links that stay within the application,
-// allowing them to be styled differently from external links.
-#show link: it => {
- let dest = it.dest
- if type(dest) == str {
- let is-internal = dest.starts-with("/") or dest.starts-with(".")
- let attrs = (href: dest)
- if is-internal {
- attrs = (href: dest, class: "internal")
- }
- html.elem("a", attrs: attrs, it.body)
- } else {
- it
- }
-}
diff --git a/prepends/quote.typ b/prepends/quote.typ
deleted file mode 100644
index bba122d..0000000
--- a/prepends/quote.typ
+++ /dev/null
@@ -1,15 +0,0 @@
-// Typst version 14.0.2 outputs a block quote as a
followed by
-// a
for the attribution. This makes it difficult to target the
-// attribution for styling. This snippet instead uses a
and
-// a wrapped in a block.
-#show quote.where(block: true): it => {
- let inner = html.elem("blockquote", it.body)
- if it.attribution != none {
- html.elem("figure", {
- inner
- html.elem("figcaption", it.attribution)
- })
- } else {
- inner
- }
-}
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
deleted file mode 100644
index 9cab269..0000000
--- a/rust-toolchain.toml
+++ /dev/null
@@ -1,3 +0,0 @@
-[toolchain]
-channel = "stable"
-
diff --git a/shell.nix b/shell.nix
new file mode 100644
index 0000000..afd09a7
--- /dev/null
+++ b/shell.nix
@@ -0,0 +1,10 @@
+{ pkgs ? import {} }:
+
+pkgs.mkShell {
+ buildInputs = with pkgs; [
+ cargo
+ rustc
+ rust-analyzer
+ ];
+}
+
diff --git a/src/lib.rs b/src/lib.rs
index 34bc866..a03e23d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,87 +1,21 @@
-mod plugin;
-
-use std::fmt::Write;
use std::fs;
use std::path::PathBuf;
-pub use plugin::{concat_plugin_sources, embedded_prepend_source, list_embedded_plugin_ids};
-
use typst::ecow::EcoString;
-use typst::syntax::Source;
-use typst_as_lib::{typst_kit_options::TypstKitFontOptions, TypstAsLibError, TypstEngine};
+use typst_as_lib::{typst_kit_options::TypstKitFontOptions, TypstEngine};
use typst_html::{HtmlAttr, HtmlDocument, HtmlElement, HtmlNode};
-use log::info;
-
-fn format_typst_compile_error(
- err: TypstAsLibError,
- full_source: &str,
- index_byte_start: usize,
- index_source: &str,
-) -> std::io::Error {
- let report = match err {
- TypstAsLibError::TypstSource(diagnostics) if !diagnostics.is_empty() => {
- let combined = Source::detached(full_source);
- let index_only = Source::detached(index_source);
- let index_end = index_byte_start.saturating_add(index_source.len());
- let mut out = String::from("Typst compile failed:\n");
- for d in diagnostics.iter() {
- let msg = d.message.as_str();
- if let Some(range) = combined.range(d.span) {
- let byte = range.start;
- if byte >= index_byte_start && byte < index_end {
- let rel = byte - index_byte_start;
- if let Some((line, col)) = index_only.lines().byte_to_line_column(rel) {
- let _ = writeln!(
- &mut out,
- " index.typ:{}:{}: {}",
- line + 1,
- col + 1,
- msg
- );
- } else {
- let _ = writeln!(&mut out, " {msg}");
- }
- } else if let Some((line, col)) = combined.lines().byte_to_line_column(byte) {
- let _ = writeln!(
- &mut out,
- " (preamble) line {}:{}: {}",
- line + 1,
- col + 1,
- msg
- );
- } else {
- let _ = writeln!(&mut out, " {msg}");
- }
- } else {
- let _ = writeln!(&mut out, " {msg}");
- }
- for hint in d.hints.iter() {
- let _ = writeln!(&mut out, " hint: {}", hint.as_str());
- }
- }
- out
- }
- other => format!("typst compile failed: {other}"),
- };
- std::io::Error::new(std::io::ErrorKind::Other, report)
-}
pub fn compile_article(
article_dir: &PathBuf,
prepend: &Option,
- plugins: &[impl AsRef],
- include_title: bool,
) -> Result<(), Box> {
- info!("compiling {} ...", article_dir.display());
let template_file = article_dir.join("index.typ");
let output = article_dir.join("index.html");
let outline_file = article_dir.join("outline.html");
- let plugin_block = concat_plugin_sources(plugins)?;
-
- let user_prepend = if let Some(prepend_file) = prepend {
+ let prepend_content = if let Some(prepend_file) = prepend {
fs::read_to_string(&prepend_file).map_err(|e| {
format!(
"could not read prepend file {}: {e}",
@@ -92,26 +26,19 @@ pub fn compile_article(
fs::read_to_string(article_dir.join("prepend.typ")).unwrap_or_default()
};
- let index_source = fs::read_to_string(&template_file).map_err(|e| {
- format!(
- "could not read template {}: {e}",
- template_file.display()
- )
- })?;
-
let mut template: EcoString = EcoString::new();
- template.push_str(&plugin_block);
- if !plugin_block.is_empty() && !user_prepend.is_empty() {
- template.push('\n');
- }
- template.push_str(&user_prepend);
- let index_byte_start = template.len();
- template.push_str(&index_source);
-
- let full_source_str = template.to_string();
+ template.push_str(&prepend_content);
+ template.push_str(
+ &fs::read_to_string(&template_file).map_err(|e| {
+ format!(
+ "could not read template {}: {e}",
+ template_file.display()
+ )
+ })?,
+ );
let engine = TypstEngine::builder()
- .main_file(full_source_str.clone())
+ .main_file(template.to_string())
.search_fonts_with(
TypstKitFontOptions::default()
.include_system_fonts(false)
@@ -123,27 +50,13 @@ pub fn compile_article(
let mut doc: HtmlDocument = engine
.compile()
.output
- .map_err(|e| format_typst_compile_error(e, &full_source_str, index_byte_start, &index_source))?;
+ .map_err(|e| format!("typst compile failed: {e}"))?;
let mut outline = EcoString::new();
- let mut curr_level = 1u32;
- let mut ul_depth = 0u32;
- let mut title_h2_pending = !include_title;
- let mut first_outline_heading = true;
- parse_outline(
- &mut doc.root,
- &mut outline,
- &mut curr_level,
- &mut ul_depth,
- include_title,
- &mut title_h2_pending,
- &mut first_outline_heading,
- );
- // `ul_depth` counts open `
` tags; it can diverge from `curr_level - 1` when the first
- // outline heading uses lazy depth (skip title). Always drain by `ul_depth`, not `curr_level`.
- while ul_depth > 0 {
- ul_depth -= 1;
- outline.push_str(" ".repeat(ul_depth as usize).as_str());
+ let mut curr_level = 1;
+ parse_outline(&mut doc.root, &mut outline, &mut curr_level);
+ for i in (1..curr_level).rev() {
+ outline.push_str(" ".repeat(i as usize - 1).as_str());
outline.push_str("