feat: add processor flag and finish sample to convert into tex paper (#1824)

* feat: add processor flag and finish sample to convert into tex paper

* test: update snapshot remove tex {document} env wrapping
This commit is contained in:
Myriad-Dreamin 2025-06-19 09:57:11 +08:00 committed by GitHub
parent ee528810fb
commit bc15eb55ce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 705 additions and 197 deletions

View file

@ -1 +1,4 @@
files.extend-exclude = ["locales/**/*"]
files.extend-exclude = [
"locales/**/*",
"editors/vscode/e2e-workspaces/ieee-paper/ieee-tex.typ",
]

View file

@ -213,6 +213,21 @@ impl InlineNode {
}
}
/// Verbatim node for raw text output
#[derive(Debug, PartialEq, Clone)]
#[custom_node(block = true, html_impl = false)]
pub struct VerbatimNode {
/// The content to directly output
pub content: EcoString,
}
impl VerbatimNode {
fn write_custom(&self, writer: &mut CommonMarkWriter) -> WriteResult<()> {
writer.write_str(&self.content)?;
Ok(())
}
}
/// Alert node for alert messages
#[derive(Debug, PartialEq, Clone)]
#[custom_node(block = true, html_impl = false)]

View file

@ -13,11 +13,6 @@ input_file: crates/typlite/src/fixtures/integration/base.typ
</html>
=====
\begin{document}
\section{Hello, World!}
This is a typst document.
\end{document}

View file

@ -13,12 +13,7 @@ input_file: crates/typlite/src/fixtures/integration/enum.typ
</html>
=====
\begin{document}
\begin{enumerate}
\item A
\item B
\end{enumerate}
\end{document}

View file

@ -13,12 +13,7 @@ input_file: crates/typlite/src/fixtures/integration/enum2.typ
</html>
=====
\begin{document}
\begin{enumerate}
\item A
\item B
\end{enumerate}
\end{document}

View file

@ -13,8 +13,6 @@ input_file: crates/typlite/src/fixtures/integration/figure_caption.typ
</html>
=====
\begin{document}
\begin{center}
\begin{figure}[htbp]
\centering
@ -23,6 +21,3 @@ input_file: crates/typlite/src/fixtures/integration/figure_caption.typ
\end{figure}
\end{center}
\end{document}

View file

@ -13,8 +13,6 @@ input_file: crates/typlite/src/fixtures/integration/figure_image.typ
</html>
=====
\begin{document}
\begin{center}
\begin{figure}[htbp]
\centering
@ -22,6 +20,3 @@ input_file: crates/typlite/src/fixtures/integration/figure_image.typ
\end{figure}
\end{center}
\end{document}

View file

@ -13,8 +13,6 @@ input_file: crates/typlite/src/fixtures/integration/figure_image_alt.typ
</html>
=====
\begin{document}
\begin{center}
\begin{figure}[htbp]
\centering
@ -22,6 +20,3 @@ input_file: crates/typlite/src/fixtures/integration/figure_image_alt.typ
\end{figure}
\end{center}
\end{document}

View file

@ -2,7 +2,6 @@
source: crates/typlite/src/tests.rs
expression: "conv(world, ConvKind::LaTeX)"
input_file: crates/typlite/src/fixtures/integration/highlight.typ
snapshot_kind: text
---
<!DOCTYPE html>
<html>
@ -14,9 +13,4 @@ snapshot_kind: text
</html>
=====
\begin{document}
\colorbox{yellow}{highlight}
\end{document}

View file

@ -2,7 +2,6 @@
source: crates/typlite/src/tests.rs
expression: "conv(world, ConvKind::LaTeX)"
input_file: crates/typlite/src/fixtures/integration/ieee.typ
snapshot_kind: text
---
<!DOCTYPE html>
<html>
@ -14,8 +13,6 @@ snapshot_kind: text
</html>
=====
\begin{document}
\section{Introduction}
Scientific writing is a crucial part of the research process, allowing researchers to share their findings with the wider scientific community. However, the process of typesetting scientific documents can often be a frustrating and time-consuming affair, particularly when using outdated tools such as LaTeX. Despite being over 30 years old, it remains a popular choice for scientific writing due to its power and flexibility. However, it also comes with a steep learning curve, complex syntax, and long compile times, leading to frustration and despair for many researchers [1] [2].
@ -95,6 +92,3 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
\hline
\end{tabular}
\end{table}
\end{document}

View file

@ -13,14 +13,7 @@ input_file: crates/typlite/src/fixtures/integration/image.typ
</html>
=====
\begin{document}
\begin{figure}
\centering
\includegraphics[width=0.8\textwidth]{fig.svg}
\end{figure}
\end{document}

View file

@ -13,15 +13,8 @@ input_file: crates/typlite/src/fixtures/integration/image_alt.typ
</html>
=====
\begin{document}
\begin{figure}
\centering
\includegraphics[width=0.8\textwidth]{fig.svg}
\caption{Content}
\end{figure}
\end{document}

View file

@ -2,7 +2,6 @@
source: crates/typlite/src/tests.rs
expression: "conv(world, ConvKind::LaTeX)"
input_file: crates/typlite/src/fixtures/integration/linebreak.typ
snapshot_kind: text
---
<!DOCTYPE html>
<html>
@ -14,13 +13,8 @@ snapshot_kind: text
</html>
=====
\begin{document}
Text2\\
Text1\\
\subsection{H1}
\end{document}

View file

@ -13,9 +13,4 @@ input_file: crates/typlite/src/fixtures/integration/link.typ
</html>
=====
\begin{document}
\href{https://example.com}{https://example.com}
\end{document}

View file

@ -13,9 +13,4 @@ input_file: crates/typlite/src/fixtures/integration/link2.typ
</html>
=====
\begin{document}
\href{https://example.com}{Content}
\end{document}

View file

@ -13,9 +13,4 @@ input_file: crates/typlite/src/fixtures/integration/link3.typ
</html>
=====
\begin{document}
\href{https://example.com}{Reverse \textbf{the World}}
\end{document}

View file

@ -13,12 +13,7 @@ input_file: crates/typlite/src/fixtures/integration/list.typ
</html>
=====
\begin{document}
\begin{itemize}
\item Some \textbf{item}
\item Another \textit{item}
\end{itemize}
\end{document}

View file

@ -13,10 +13,5 @@ input_file: crates/typlite/src/fixtures/integration/math_block.typ
</html>
=====
\begin{document}
\begin{center}
\end{center}
\end{document}

View file

@ -13,10 +13,5 @@ input_file: crates/typlite/src/fixtures/integration/math_block2.typ
</html>
=====
\begin{document}
\begin{center}
\end{center}
\end{document}

View file

@ -13,9 +13,3 @@ input_file: crates/typlite/src/fixtures/integration/math_inline.typ
</html>
=====
\begin{document}
\end{document}

View file

@ -28,8 +28,6 @@ namespace MyApplication
</html>
=====
\begin{document}
\section{Contents}
\subsection{Heading 1}
@ -97,6 +95,3 @@ First termFirst definition
\hline
\end{tabular}
\end{table}
\end{document}

View file

@ -13,9 +13,4 @@ input_file: crates/typlite/src/fixtures/integration/raw_inline.typ
</html>
=====
\begin{document}
Some inlined raw \texttt{a}, \texttt{b}
\end{document}

View file

@ -2,7 +2,6 @@
source: crates/typlite/src/tests.rs
expression: "conv(world, ConvKind::LaTeX)"
input_file: crates/typlite/src/fixtures/integration/table.typ
snapshot_kind: text
---
<!DOCTYPE html>
<html>
@ -14,8 +13,6 @@ snapshot_kind: text
</html>
=====
\begin{document}
\begin{table}[htbp]
\centering
\begin{tabular}{cccccccccccccccccccc}
@ -40,4 +37,3 @@ snapshot_kind: text
\end{table}
012345678910111213141516171819012345678910111213141516171819
\end{document}

View file

@ -23,7 +23,6 @@ use typst::foundations::Bytes;
use typst::html::HtmlDocument;
use typst::World;
use typst_syntax::VirtualPath;
use writer::LaTeXWriter;
use crate::common::Format;
use crate::parser::HtmlToAstParser;
@ -110,14 +109,11 @@ impl MarkdownDocument {
}
/// Convert the content to a LaTeX string.
pub fn to_tex_string(&self, prelude: bool) -> tinymist_std::Result<ecow::EcoString> {
pub fn to_tex_string(&self) -> tinymist_std::Result<ecow::EcoString> {
let mut output = ecow::EcoString::new();
let ast = self.parse()?;
let mut writer = WriterFactory::create(Format::LaTeX);
if prelude {
LaTeXWriter::default_prelude(&mut output);
}
writer
.write_eco(&ast, &mut output)
.context_ut("failed to write")?;
@ -159,8 +155,27 @@ pub struct TypliteFeat {
pub remove_html: bool,
/// The target to convert
pub target: Format,
/// Import context for code examples (e.g., "#import \"/path/to/file.typ\": *")
/// Import context for code examples (e.g., "#import \"/path/to/file.typ\":
/// *")
pub import_context: Option<String>,
/// Specifies the package to process markup.
///
/// ## `article` function
///
/// The article function is used to wrap the typst content during
/// compilation.
///
/// typlite exactly uses the `#article` function to process the content as
/// follow:
///
/// ```typst
/// #import "@local/processor": article
/// #article(include "the-processed-content.typ")
/// ```
///
/// It resembles the regular typst show rule function, like `#show:
/// article`.
pub processor: Option<String>,
}
/// Task builder for converting a typst document to Markdown.
@ -198,7 +213,7 @@ impl Typlite {
pub fn convert(self) -> tinymist_std::Result<ecow::EcoString> {
match self.format {
Format::Md => self.convert_doc(Format::Md)?.to_md_string(),
Format::LaTeX => self.convert_doc(Format::LaTeX)?.to_tex_string(true),
Format::LaTeX => self.convert_doc(Format::LaTeX)?.to_tex_string(),
Format::Text => self.convert_doc(Format::Text)?.to_text_string(),
#[cfg(feature = "docx")]
Format::Docx => bail!("docx format is not supported"),
@ -227,9 +242,19 @@ impl Typlite {
}
let wrap_main_id = current.join("__wrap_md_main.typ");
let wrap_main_path = world
.path_for_id(wrap_main_id)
.context_ut("getting source for main file")?;
let (main_id, main_content) = match self.feat.processor.as_ref() {
None => (wrap_main_id, None),
Some(processor) => {
let main_id = current.join("__md_main.typ");
let content = format!(
r#"#import {processor:?}: article
#article(include "__wrap_md_main.typ")"#
);
(main_id, Some(Bytes::from_string(content)))
}
};
let mut dict = TypstDict::new();
dict.insert("x-target".into(), Str("md".into()));
@ -238,7 +263,7 @@ impl Typlite {
}
let task_inputs = TaskInputs {
entry: Some(entry.select_in_workspace(wrap_main_id.vpath().as_rooted_path())),
entry: Some(entry.select_in_workspace(main_id.vpath().as_rooted_path())),
inputs: Some(Arc::new(LazyHash::new(dict))),
};
@ -266,8 +291,8 @@ impl Typlite {
.context_ut("cannot map markdown.typ")?;
world
.map_shadow(
wrap_main_path.as_path(),
.map_shadow_by_id(
wrap_main_id,
Bytes::from_string(format!(
r#"#import "@local/markdown:0.1.0": md-doc, example
#show: md-doc
@ -280,6 +305,12 @@ impl Typlite {
)
.context_ut("cannot map source for main file")?;
if let Some(main_content) = main_content {
world
.map_shadow_by_id(main_id, main_content)
.context_ut("cannot map source for main file")?;
}
// todo: ignoring warnings
let base = typst::compile(&world).output?;
let mut feat = self.feat;

View file

@ -11,7 +11,7 @@ use clap::Parser;
use tinymist_project::{
base::print_diagnostics, DiagnosticFormat, LspWorld, SourceWorld, WorldProvider,
};
use tinymist_std::error::prelude::*;
use tinymist_std::{error::prelude::*, Result};
use typlite::{common::Format, TypliteFeat};
use typlite::{CompileOnceArgs, Typlite};
use typst::foundations::Bytes;
@ -28,62 +28,76 @@ pub struct CompileArgs {
/// Configures the path of assets directory
#[clap(long, default_value = None, value_name = "ASSETS_PATH")]
pub assets_path: Option<String>,
pub assets_path: Option<PathBuf>,
/// Specifies the package to process markup.
///
/// ## `article` function
///
/// The article function is used to wrap the typst content during
/// compilation.
///
/// typlite exactly uses the `#article` function to process the content as
/// follow:
///
/// ```typst
/// #import "@local/processor": article
/// #article(include "the-processed-content.typ")
/// ```
///
/// It resembles the regular typst show rule function, like `#show:
/// article`.
#[clap(long = "processor", default_value = None, value_name = "PACKAGE_SPEC")]
pub processor: Option<String>,
}
fn main() -> tinymist_std::Result<()> {
fn main() -> Result<()> {
// Parse command line arguments
let args = CompileArgs::parse();
let universe = args.compile.resolve()?;
let world = Arc::new(universe.snapshot());
let verse = args.compile.resolve()?;
let world = Arc::new(verse.snapshot());
print_diag_or_error(world.as_ref(), run(args, world.clone()))
}
fn run(args: CompileArgs, world: Arc<LspWorld>) -> tinymist_std::Result<()> {
fn run(args: CompileArgs, world: Arc<LspWorld>) -> Result<()> {
let input = args
.compile
.input
.as_ref()
.context("Missing required argument: INPUT")?;
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"));
.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,
Some(ext) if ext == std::ffi::OsStr::new("txt") => Format::Text,
let output_format = match output_path.extension().and_then(std::ffi::OsStr::to_str) {
Some("tex") => Format::LaTeX,
Some("txt") => Format::Text,
#[cfg(feature = "docx")]
Some(ext) if ext == std::ffi::OsStr::new("docx") => Format::Docx,
Some("docx") => Format::Docx,
_ => Format::Md,
};
let assets_path = match args.assets_path {
Some(assets_path) => {
let path = PathBuf::from(assets_path);
if !path.exists() {
if let Err(e) = std::fs::create_dir_all(&path) {
bail!("failed to create assets directory: {e}");
}
}
Some(path)
if let Some(assets_path) = args.assets_path.as_ref() {
if !assets_path.exists() {
std::fs::create_dir_all(assets_path).context("failed to create assets directory")?;
}
None => None,
};
}
let converter = Typlite::new(world.clone()).with_feature(TypliteFeat {
assets_path: assets_path.clone(),
..Default::default()
});
let doc = converter.convert_doc(output_format)?;
let doc = Typlite::new(world.clone())
.with_feature(TypliteFeat {
assets_path: args.assets_path,
processor: args.processor,
..Default::default()
})
.convert_doc(output_format)?;
let result = match output_format {
Format::Md => Bytes::from_string(doc.to_md_string()?),
Format::LaTeX => Bytes::from_string(doc.to_tex_string(true)?),
Format::LaTeX => Bytes::from_string(doc.to_tex_string()?),
Format::Text => Bytes::from_string(doc.to_text_string()?),
#[cfg(feature = "docx")]
Format::Docx => Bytes::new(doc.to_docx()?),
@ -100,10 +114,7 @@ fn run(args: CompileArgs, world: Arc<LspWorld>) -> tinymist_std::Result<()> {
Ok(())
}
fn print_diag_or_error<T>(
world: &impl SourceWorld,
result: tinymist_std::Result<T>,
) -> tinymist_std::Result<T> {
fn print_diag_or_error<T>(world: &impl SourceWorld, result: Result<T>) -> Result<T> {
match result {
Ok(v) => Ok(v),
Err(err) => {

View file

@ -8,8 +8,8 @@ use ecow::EcoString;
use tinymist_project::LspWorld;
use typst::html::{tag, HtmlElement, HtmlNode};
use crate::attributes::{AlertsAttr, HeadingAttr, RawAttr, TypliteAttrsParser};
use crate::common::{AlertNode, CenterNode, ListState};
use crate::attributes::{md_attr, AlertsAttr, HeadingAttr, RawAttr, TypliteAttrsParser};
use crate::common::{AlertNode, CenterNode, ListState, VerbatimNode};
use crate::tags::md_tag;
use crate::Result;
use crate::TypliteFeat;
@ -181,6 +181,19 @@ impl HtmlToAstParser {
Ok(())
}
md_tag::verbatim => {
self.inline_buffer.push(Node::Custom(Box::new(VerbatimNode {
content: element
.attrs
.0
.iter()
.find(|(name, _)| *name == md_attr::src)
.map(|(_, value)| value.clone())
.unwrap_or_default(),
})));
Ok(())
}
_ => {
let tag_name = element.tag.resolve().to_string();

View file

@ -22,6 +22,7 @@ pub mod md_tag {
highlight -> m1highlight
strike -> m1strike
raw -> m1raw
verbatim -> m1verbatim
label -> m1label
reference -> m1ref
heading -> m1heading

View file

@ -104,7 +104,7 @@ fn conv(world: LspWorld, kind: ConvKind) -> String {
let repr = typst_html::html(&redact(doc.base.clone())).unwrap();
let res = match kind {
ConvKind::Md { .. } => doc.to_md_string().unwrap(),
ConvKind::LaTeX => doc.to_tex_string(false).unwrap(),
ConvKind::LaTeX => doc.to_tex_string().unwrap(),
};
static REG: OnceLock<Regex> = OnceLock::new();

View file

@ -7,7 +7,9 @@ use ecow::EcoString;
use std::fs;
use std::io::Cursor;
use crate::common::{CenterNode, FigureNode, FormatWriter, HighlightNode, InlineNode};
use crate::common::{
CenterNode, FigureNode, FormatWriter, HighlightNode, InlineNode, VerbatimNode,
};
use crate::Result;
use super::image_processor::DocxImageProcessor;
@ -248,6 +250,10 @@ impl DocxWriter {
run = self.process_inline_to_run(run, child)?;
}
}
node if node.is_custom_type::<VerbatimNode>() => {
let node = node.as_custom_type::<VerbatimNode>().unwrap();
eprintln!("Warning: `m1verbatim` is ignored {:?}.", node.content);
}
// Other inline element types
_ => {
println!("other inline element: {:?}", node);

View file

@ -8,6 +8,7 @@ use tinymist_std::path::unix_slash;
use crate::common::{
CenterNode, ExternalFrameNode, FigureNode, FormatWriter, HighlightNode, InlineNode, ListState,
VerbatimNode,
};
use crate::Result;
@ -27,32 +28,6 @@ impl LaTeXWriter {
Self { list_state: None }
}
pub fn default_prelude(output: &mut EcoString) {
// Write LaTeX document preamble using the new method
output.push_str("\\documentclass[12pt,a4paper]{article}\n");
output.push_str("\\usepackage[utf8]{inputenc}\n");
output.push_str("\\usepackage{hyperref}\n"); // For links
output.push_str("\\usepackage{graphicx}\n"); // For images
output.push_str("\\usepackage{ulem}\n"); // For strikethrough \sout
output.push_str("\\usepackage{listings}\n"); // For code blocks
output.push_str("\\usepackage{xcolor}\n"); // For colored text and backgrounds
output.push_str("\\usepackage{amsmath}\n"); // Math formula support
output.push_str("\\usepackage{amssymb}\n"); // Additional math symbols
output.push_str("\\usepackage{array}\n"); // Enhanced table functionality
// Set code highlighting style
output.push_str("\\lstset{\n");
output.push_str(" basicstyle=\\ttfamily\\small,\n");
output.push_str(" breaklines=true,\n");
output.push_str(" frame=single,\n");
output.push_str(" numbers=left,\n");
output.push_str(" numberstyle=\\tiny,\n");
output.push_str(" keywordstyle=\\color{blue},\n");
output.push_str(" commentstyle=\\color{green!60!black},\n");
output.push_str(" stringstyle=\\color{red}\n");
output.push_str("}\n\n");
}
fn write_inline_nodes(&mut self, nodes: &[Node], output: &mut EcoString) -> Result<()> {
for node in nodes {
self.write_node(node, output)?;
@ -314,6 +289,10 @@ impl LaTeXWriter {
self.write_node(child, output)?;
}
}
node if node.is_custom_type::<VerbatimNode>() => {
let inline_node = node.as_custom_type::<VerbatimNode>().unwrap();
output.push_str(&inline_node.content);
}
Node::Text(text) => {
output.push_str(&escape_latex(text));
}
@ -410,14 +389,8 @@ fn escape_latex(text: &str) -> String {
impl FormatWriter for LaTeXWriter {
fn write_eco(&mut self, document: &Node, output: &mut EcoString) -> Result<()> {
output.push_str("\\begin{document}\n\n");
// Write the document content
self.write_node(document, output)?;
// Add document ending
output.push_str("\n\\end{document}\n");
Ok(())
}

View file

@ -6,7 +6,11 @@
"type": "typst",
"command": "export",
"export": {
"format": ["latex"]
"format": ["latex"],
// It is totally legal to use the processor in the current workspace,
// but we suggest make a local package and use the package spec instead.
// like: "package": "@local/ieee-tex:0.1.0"
"processor": "/ieee-tex.typ"
}
},
{

View file

@ -2,6 +2,11 @@
/// `ieee` will not style the document if `is-html-target` is true.
#let is-html-target = ("target" in dictionary(std))
#let title-state = state("tex:title", "")
#let authors-state = state("tex:authors", ())
#let abstract-state = state("tex:abstract", "")
#let bibliography-state = state("tex:bibliography", "")
// This function gets your whole document as its `body` and formats
// it as an article in the style of the IEEE.
#let ieee(
@ -27,10 +32,15 @@
) = if is-html-target {
set heading(numbering: "I.A.a)")
set math.equation(numbering: "(1)")
title-state.update(_ => title)
authors-state.update(_ => authors)
abstract-state.update(_ => abstract)
if bibliography != none {
bibliography-state.update(_ => bibliography.sources.at(0))
}
body
// Display bibliography.
bibliography
} else {
// Set document metadata.

View file

@ -0,0 +1,553 @@
#let verbatim(body) = {
show raw.where(lang: "tex"): it => html.elem("m1verbatim", attrs: (src: it.text))
body
}
#let prelude1 = verbatim(```tex
%% bare_conf_compsoc.tex
%% V1.4b
%% 2015/08/26
%% by Michael Shell
%% See:
%% http://www.michaelshell.org/
%% for current contact information.
%%
%% This is a skeleton file demonstrating the use of IEEEtran.cls
%% (requires IEEEtran.cls version 1.8b or later) with an IEEE Computer
%% Society conference paper.
%%
%% Support sites:
%% http://www.michaelshell.org/tex/ieeetran/
%% http://www.ctan.org/pkg/ieeetran
%% and
%% http://www.ieee.org/
%%*************************************************************************
%% Legal Notice:
%% This code is offered as-is without any warranty either expressed or
%% implied; without even the implied warranty of MERCHANTABILITY or
%% FITNESS FOR A PARTICULAR PURPOSE!
%% User assumes all risk.
%% In no event shall the IEEE or any contributor to this code be liable for
%% any damages or losses, including, but not limited to, incidental,
%% consequential, or any other damages, resulting from the use or misuse
%% of any information contained here.
%%
%% All comments are the opinions of their respective authors and are not
%% necessarily endorsed by the IEEE.
%%
%% This work is distributed under the LaTeX Project Public License (LPPL)
%% ( http://www.latex-project.org/ ) version 1.3, and may be freely used,
%% distributed and modified. A copy of the LPPL, version 1.3, is included
%% in the base LaTeX documentation of all distributions of LaTeX released
%% 2003/12/01 or later.
%% Retain all contribution notices and credits.
%% ** Modified files should be clearly indicated as such, including **
%% ** renaming them and changing author support contact information. **
%%*************************************************************************
% *** Authors should verify (and, if needed, correct) their LaTeX system ***
% *** with the testflow diagnostic prior to trusting their LaTeX platform ***
% *** with production work. The IEEE's font choices and paper sizes can ***
% *** trigger bugs that do not appear when using other class files. *** ***
% The testflow support page is at:
% http://www.michaelshell.org/tex/testflow/
\documentclass[conference,compsoc]{IEEEtran}
% Some/most Computer Society conferences require the compsoc mode option,
% but others may want the standard conference format.
%
% If IEEEtran.cls has not been installed into the LaTeX system files,
% manually specify the path to it like:
% \documentclass[conference,compsoc]{../sty/IEEEtran}
% Some very useful LaTeX packages include:
% (uncomment the ones you want to load)
% *** MISC UTILITY PACKAGES ***
%
%\usepackage{ifpdf}
% Heiko Oberdiek's ifpdf.sty is very useful if you need conditional
% compilation based on whether the output is pdf or dvi.
% usage:
% \ifpdf
% % pdf code
% \else
% % dvi code
% \fi
% The latest version of ifpdf.sty can be obtained from:
% http://www.ctan.org/pkg/ifpdf
% Also, note that IEEEtran.cls V1.7 and later provides a builtin
% \ifCLASSINFOpdf conditional that works the same way.
% When switching from latex to pdflatex and vice-versa, the compiler may
% have to be run twice to clear warning/error messages.
% *** CITATION PACKAGES ***
%
\ifCLASSOPTIONcompsoc
% IEEE Computer Society needs nocompress option
% requires cite.sty v4.0 or later (November 2003)
\usepackage[nocompress]{cite}
\else
% normal IEEE
\usepackage{cite}
\fi
% cite.sty was written by Donald Arseneau
% V1.6 and later of IEEEtran pre-defines the format of the cite.sty package
% \cite{} output to follow that of the IEEE. Loading the cite package will
% result in citation numbers being automatically sorted and properly
% "compressed/ranged". e.g., [1], [9], [2], [7], [5], [6] without using
% cite.sty will become [1], [2], [5]--[7], [9] using cite.sty. cite.sty's
% \cite will automatically add leading space, if needed. Use cite.sty's
% noadjust option (cite.sty V3.8 and later) if you want to turn this off
% such as if a citation ever needs to be enclosed in parenthesis.
% cite.sty is already installed on most LaTeX systems. Be sure and use
% version 5.0 (2009-03-20) and later if using hyperref.sty.
% The latest version can be obtained at:
% http://www.ctan.org/pkg/cite
% The documentation is contained in the cite.sty file itself.
%
% Note that some packages require special options to format as the Computer
% Society requires. In particular, Computer Society papers do not use
% compressed citation ranges as is done in typical IEEE papers
% (e.g., [1]-[4]). Instead, they list every citation separately in order
% (e.g., [1], [2], [3], [4]). To get the latter we need to load the cite
% package with the nocompress option which is supported by cite.sty v4.0
% and later.
% *** GRAPHICS RELATED PACKAGES ***
%
\ifCLASSINFOpdf
% \usepackage[pdftex]{graphicx}
% declare the path(s) where your graphic files are
% \graphicspath{{../pdf/}{../jpeg/}}
% and their extensions so you won't have to specify these with
% every instance of \includegraphics
% \DeclareGraphicsExtensions{.pdf,.jpeg,.png}
\else
% or other class option (dvipsone, dvipdf, if not using dvips). graphicx
% will default to the driver specified in the system graphics.cfg if no
% driver is specified.
% \usepackage[dvips]{graphicx}
% declare the path(s) where your graphic files are
% \graphicspath{{../eps/}}
% and their extensions so you won't have to specify these with
% every instance of \includegraphics
% \DeclareGraphicsExtensions{.eps}
\fi
% graphicx was written by David Carlisle and Sebastian Rahtz. It is
% required if you want graphics, photos, etc. graphicx.sty is already
% installed on most LaTeX systems. The latest version and documentation
% can be obtained at:
% http://www.ctan.org/pkg/graphicx
% Another good source of documentation is "Using Imported Graphics in
% LaTeX2e" by Keith Reckdahl which can be found at:
% http://www.ctan.org/pkg/epslatex
%
% latex, and pdflatex in dvi mode, support graphics in encapsulated
% postscript (.eps) format. pdflatex in pdf mode supports graphics
% in .pdf, .jpeg, .png and .mps (metapost) formats. Users should ensure
% that all non-photo figures use a vector format (.eps, .pdf, .mps) and
% not a bitmapped formats (.jpeg, .png). The IEEE frowns on bitmapped formats
% which can result in "jaggedy"/blurry rendering of lines and letters as
% well as large increases in file sizes.
%
% You can find documentation about the pdfTeX application at:
% http://www.tug.org/applications/pdftex
% *** MATH PACKAGES ***
%
%\usepackage{amsmath}
% A popular package from the American Mathematical Society that provides
% many useful and powerful commands for dealing with mathematics.
%
% Note that the amsmath package sets \interdisplaylinepenalty to 10000
% thus preventing page breaks from occurring within multiline equations. Use:
%\interdisplaylinepenalty=2500
% after loading amsmath to restore such page breaks as IEEEtran.cls normally
% does. amsmath.sty is already installed on most LaTeX systems. The latest
% version and documentation can be obtained at:
% http://www.ctan.org/pkg/amsmath
% *** SPECIALIZED LIST PACKAGES ***
%
%\usepackage{algorithmic}
% algorithmic.sty was written by Peter Williams and Rogerio Brito.
% This package provides an algorithmic environment for describing algorithms.
% You can use the algorithmic environment in-text or within a figure
% environment to provide for a floating algorithm. Do NOT use the algorithm
% floating environment provided by algorithm.sty (by the same authors) or
% algorithm2e.sty (by Christophe Fiorio) as the IEEE does not use dedicated
% algorithm float types and packages that provide these will not provide
% correct IEEE style captions. The latest version and documentation of
% algorithmic.sty can be obtained at:
% http://www.ctan.org/pkg/algorithms
% Also of interest may be the (relatively newer and more customizable)
% algorithmicx.sty package by Szasz Janos:
% http://www.ctan.org/pkg/algorithmicx
% *** ALIGNMENT PACKAGES ***
%
%\usepackage{array}
% Frank Mittelbach's and David Carlisle's array.sty patches and improves
% the standard LaTeX2e array and tabular environments to provide better
% appearance and additional user controls. As the default LaTeX2e table
% generation code is lacking to the point of almost being broken with
% respect to the quality of the end results, all users are strongly
% advised to use an enhanced (at the very least that provided by array.sty)
% set of table tools. array.sty is already installed on most systems. The
% latest version and documentation can be obtained at:
% http://www.ctan.org/pkg/array
% IEEEtran contains the IEEEeqnarray family of commands that can be used to
% generate multiline equations as well as matrices, tables, etc., of high
% quality.
% *** SUBFIGURE PACKAGES ***
%\ifCLASSOPTIONcompsoc
% \usepackage[caption=false,font=footnotesize,labelfont=sf,textfont=sf]{subfig}
%\else
% \usepackage[caption=false,font=footnotesize]{subfig}
%\fi
% subfig.sty, written by Steven Douglas Cochran, is the modern replacement
% for subfigure.sty, the latter of which is no longer maintained and is
% incompatible with some LaTeX packages including fixltx2e. However,
% subfig.sty requires and automatically loads Axel Sommerfeldt's caption.sty
% which will override IEEEtran.cls' handling of captions and this will result
% in non-IEEE style figure/table captions. To prevent this problem, be sure
% and invoke subfig.sty's "caption=false" package option (available since
% subfig.sty version 1.3, 2005/06/28) as this is will preserve IEEEtran.cls
% handling of captions.
% Note that the Computer Society format requires a sans serif font rather
% than the serif font used in traditional IEEE formatting and thus the need
% to invoke different subfig.sty package options depending on whether
% compsoc mode has been enabled.
%
% The latest version and documentation of subfig.sty can be obtained at:
% http://www.ctan.org/pkg/subfig
% *** FLOAT PACKAGES ***
%
%\usepackage{fixltx2e}
% fixltx2e, the successor to the earlier fix2col.sty, was written by
% Frank Mittelbach and David Carlisle. This package corrects a few problems
% in the LaTeX2e kernel, the most notable of which is that in current
% LaTeX2e releases, the ordering of single and double column floats is not
% guaranteed to be preserved. Thus, an unpatched LaTeX2e can allow a
% single column figure to be placed prior to an earlier double column
% figure.
% Be aware that LaTeX2e kernels dated 2015 and later have fixltx2e.sty's
% corrections already built into the system in which case a warning will
% be issued if an attempt is made to load fixltx2e.sty as it is no longer
% needed.
% The latest version and documentation can be found at:
% http://www.ctan.org/pkg/fixltx2e
%\usepackage{stfloats}
% stfloats.sty was written by Sigitas Tolusis. This package gives LaTeX2e
% the ability to do double column floats at the bottom of the page as well
% as the top. (e.g., "\begin{figure*}[!b]" is not normally possible in
% LaTeX2e). It also provides a command:
%\fnbelowfloat
% to enable the placement of footnotes below bottom floats (the standard
% LaTeX2e kernel puts them above bottom floats). This is an invasive package
% which rewrites many portions of the LaTeX2e float routines. It may not work
% with other packages that modify the LaTeX2e float routines. The latest
% version and documentation can be obtained at:
% http://www.ctan.org/pkg/stfloats
% Do not use the stfloats baselinefloat ability as the IEEE does not allow
% \baselineskip to stretch. Authors submitting work to the IEEE should note
% that the IEEE rarely uses double column equations and that authors should try
% to avoid such use. Do not be tempted to use the cuted.sty or midfloat.sty
% packages (also by Sigitas Tolusis) as the IEEE does not format its papers in
% such ways.
% Do not attempt to use stfloats with fixltx2e as they are incompatible.
% Instead, use Morten Hogholm'a dblfloatfix which combines the features
% of both fixltx2e and stfloats:
%
% \usepackage{dblfloatfix}
% The latest version can be found at:
% http://www.ctan.org/pkg/dblfloatfix
% *** PDF, URL AND HYPERLINK PACKAGES ***
%
%\usepackage{url}
% url.sty was written by Donald Arseneau. It provides better support for
% handling and breaking URLs. url.sty is already installed on most LaTeX
% systems. The latest version and documentation can be obtained at:
% http://www.ctan.org/pkg/url
% Basically, \url{my_url_here}.
% *** Do not adjust lengths that control margins, column widths, etc. ***
% *** Do not use packages that alter fonts (such as pslatex). ***
% There should be no need to do such things with IEEEtran.cls V1.6 and later.
% (Unless specifically asked to do so by the journal or conference you plan
% to submit to, of course. )
% correct bad hyphenation here
\hyphenation{op-tical net-works semi-conduc-tor}
\begin{document}
%
% paper title
% Titles are generally capitalized except for words such as a, an, and, as,
% at, but, by, for, in, nor, of, on, or, the, to and up, which are usually
% not capitalized unless they are the first or last word of the title.
% Linebreaks \\ can be used within to get better formatting as desired.
% Do not put math or special symbols in the title.
```)
#let paper-title = context {
let title = state("tex:title", "").final()
verbatim[
```tex
\title{
```
]
title
verbatim[
```tex
}
```
]
}
#let paper-authors = context {
let to-text(author, field) = {
let value = author.at(field)
if type(value) == str {
value
} else if type(value) == content and value.has("text") {
value.text
} else {
panic("Expected a string or content with `text` in field: " + field)
}
}
let authors = state("tex:authors", ())
.final()
.map(author => {
verbatim(
raw(
lang: "tex",
{
"\n\\IEEEauthorblockN{"
to-text(author, "name")
"}"
if ("department" in author) or ("organization" in author) or ("location" in author) {
"\n\\IEEEauthorblockA{"
if "department" in author {
"\n" + to-text(author, "department") + "\\"
}
if "organization" in author {
"\n" + to-text(author, "organization") + "\\"
}
if "location" in author {
"\n" + to-text(author, "location") + "\\"
}
"\n}"
}
},
),
)
})
let _and = verbatim(raw(lang: "tex", "\n\and\n"))
verbatim[
```tex
% author names and affiliations
% use a multiple column layout for up to three different
% affiliations
\author{
```
]
authors.join(_and)
verbatim[
```tex
}
```
]
}
#let prelude2 = verbatim(```tex
% conference papers do not typically use \thanks and this command
% is locked out in conference mode. If really needed, such as for
% the acknowledgment of grants, issue a \IEEEoverridecommandlockouts
% after \documentclass
% for over three affiliations, or if they all won't fit within the width
% of the page (and note that there is less available width in this regard for
% compsoc conferences compared to traditional conferences), use this
% alternative format:
%
%\author{\IEEEauthorblockN{Michael Shell\IEEEauthorrefmark{1},
%Homer Simpson\IEEEauthorrefmark{2},
%James Kirk\IEEEauthorrefmark{3},
%Montgomery Scott\IEEEauthorrefmark{3} and
%Eldon Tyrell\IEEEauthorrefmark{4}}
%\IEEEauthorblockA{\IEEEauthorrefmark{1}School of Electrical and Computer Engineering\\
%Georgia Institute of Technology,
%Atlanta, Georgia 30332--0250\\ Email: see http://www.michaelshell.org/contact.html}
%\IEEEauthorblockA{\IEEEauthorrefmark{2}Twentieth Century Fox, Springfield, USA\\
%Email: homer@thesimpsons.com}
%\IEEEauthorblockA{\IEEEauthorrefmark{3}Starfleet Academy, San Francisco, California 96678-2391\\
%Telephone: (800) 555--1212, Fax: (888) 555--1212}
%\IEEEauthorblockA{\IEEEauthorrefmark{4}Tyrell Inc., 123 Replicant Street, Los Angeles, California 90210--4321}}
% use for special paper notices
%\IEEEspecialpapernotice{(Invited Paper)}
% make the title area
\maketitle
```)
#let abstract = context {
let abstract = state("tex:abstract", "").final()
verbatim[
```tex
% As a general rule, do not put math, special symbols or citations
% in the abstract
\begin{abstract}
```
]
abstract
verbatim[
```tex
\end{abstract}
```
]
}
#let prelude3 = verbatim(```tex
% no keywords
% For peer review papers, you can put extra information on the cover
% page as needed:
% \ifCLASSOPTIONpeerreview
% \begin{center} \bfseries EDICS Category: 3-BBND \end{center}
% \fi
%
% For peerreview papers, this IEEEtran command inserts a page break and
% creates the second title. It will be ignored for other modes.
\IEEEpeerreviewmaketitle
```)
#let bibliography-section = context {
let bibliography-state = state("tex:bibliography", "").final()
verbatim[
```tex
% trigger a \newpage just before the given reference
% number - used to balance the columns on the last page
% adjust value as needed - may need to be readjusted if
% the document is modified later
%\IEEEtriggeratref{8}
% The "triggered" command can be changed if desired:
%\IEEEtriggercmd{\enlargethispage{-5in}}
% references section
% can use a bibliography generated by BibTeX as a .bbl file
% BibTeX documentation can be easily obtained at:
% http://mirror.ctan.org/biblio/bibtex/contrib/doc/
% The IEEEtran BibTeX style support page is at:
% http://www.michaelshell.org/tex/ieeetran/bibtex/
%\bibliographystyle{IEEEtran}
% argument is your BibTeX string definitions and bibliography database(s)
```
]
verbatim(
raw(
lang: "tex",
if bibliography-state == none {
"%\bibliography{IEEEabrv,../bib/paper}"
} else {
"%\bibliography{IEEEabrv,"
bibliography-state
"}"
},
),
)
}
#let postlude = verbatim(```tex
% that's all folks
\end{document}
```)
#let article(body) = {
// make bibliography available but not visible in the document
show bibliography: it => {
verbatim(```tex
\iffalse
```)
it
verbatim(```tex
\fi
```)
}
prelude1
paper-title
paper-authors
prelude2
abstract
prelude3
body
bibliography-section
postlude
}