Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 48 additions & 7 deletions src/domain/source/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,55 @@ impl Adapter for SourceAdapter {
fn extract(&self, document: &language::Document) -> Document {
let fragments = format_with_renderer(document, WIDTH);

let fragments: Vec<Fragment> = fragments
.into_iter()
.map(|(syntax, content)| Fragment {
syntax: format!("{:?}", syntax),
content: content.into_owned(),
})
.collect();

Document {
fragments: fragments
.into_iter()
.map(|(syntax, content)| Fragment {
syntax: format!("{:?}", syntax),
content: content.into_owned(),
})
.collect(),
fragments: coalesce(fragments),
}
}
}

/// Merge adjacent fragments to reduce verbosity in serialized output.
/// Same-syntax fragments are concatenated. Whitespace-only fragments
/// tagged Neutral or Description are absorbed into the preceding
/// fragment, allowing subsequent same-syntax merges to collapse runs
/// of words into single strings.
fn coalesce(fragments: Vec<Fragment>) -> Vec<Fragment> {
let mut result: Vec<Fragment> = Vec::with_capacity(fragments.len());

for frag in fragments {
if let Some(last) = result.last_mut() {
if last.syntax == frag.syntax
&& frag.syntax != "Newline"
&& frag.syntax != "BlockBegin"
&& frag.syntax != "BlockEnd"
{
last.content.push_str(&frag.content);
continue;
}
if is_text_whitespace(&frag) {
last.content.push_str(&frag.content);
continue;
}
}
result.push(frag);
}

result
}

fn is_text_whitespace(frag: &Fragment) -> bool {
(frag.syntax == "Neutral" || frag.syntax == "Description")
&& !frag.content.is_empty()
&& frag
.content
.bytes()
.all(|b| b == b' ')
}

8 changes: 7 additions & 1 deletion src/domain/source/typst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,13 @@ impl Render for Fragment {
_ => "render-neutral",
};

if self.syntax == "Newline" {
if self.syntax == "BlockBegin" {
out.raw("#render-block()[\n");
return;
} else if self.syntax == "BlockEnd" {
out.raw("]\n");
return;
} else if self.syntax == "Newline" {
out.raw(&format!("#{}()\n", func));
} else {
out.raw(&format!(
Expand Down
55 changes: 38 additions & 17 deletions src/formatting/formatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub fn format_with_renderer<'i>(technique: &'i Document, width: u8) -> Vec<(Synt
.fragments
.last()
{
if !last_content.ends_with('\n') {
if !last_content.is_empty() && !last_content.ends_with('\n') {
output.add_fragment_reference(Syntax::Description, "\n");
}
}
Expand Down Expand Up @@ -473,7 +473,9 @@ impl<'i> Formatter<'i> {
self.append_char('\n');
}

// declaration
// declaration and title kept together

self.add_fragment_reference(Syntax::BlockBegin, "");

let name = &procedure.name;
self.add_fragment_reference(Syntax::Declaration, name.0);
Expand All @@ -497,9 +499,17 @@ impl<'i> Formatter<'i> {

self.append_char('\n');

// elements
// include title in block to keep it with the declaration
let mut elements = procedure.elements.iter();
if let Some(Element::Title(_)) = procedure.elements.first() {
self.append_element(elements.next().unwrap());
}

self.add_fragment_reference(Syntax::BlockEnd, "");

for element in &procedure.elements {
// remaining elements

for element in elements {
self.append_element(element);
}
}
Expand Down Expand Up @@ -720,6 +730,7 @@ impl<'i> Formatter<'i> {
}

fn append_step(&mut self, step: &'i Scope) {
self.add_fragment_reference(Syntax::BlockBegin, "");
match step {
Scope::DependentBlock {
ordinal,
Expand Down Expand Up @@ -768,6 +779,8 @@ impl<'i> Formatter<'i> {
}
_ => panic!("Shouldn't be calling append_step() with a non-step Scope"),
}

self.add_fragment_reference(Syntax::BlockEnd, "");
}

fn append_responses(&mut self, responses: &'i Vec<Response>) {
Expand Down Expand Up @@ -801,25 +814,33 @@ impl<'i> Formatter<'i> {
attributes,
subscopes,
} => {
if subscopes.len() == 0 {
self.indent();
self.append_attributes(attributes);
self.add_fragment_reference(Syntax::Newline, "\n");
return;
}

let is_code =
if let Scope::CodeBlock { .. } = subscopes[0] { true } else { false };

// Keep attribute with its first subscope
self.add_fragment_reference(Syntax::BlockBegin, "");
self.indent();
self.append_attributes(attributes);
self.add_fragment_reference(Syntax::Newline, "\n");

if subscopes.len() == 0 {
return;
if !is_code {
self.increase(4);
}
self.append_scope(&subscopes[0]);
self.add_fragment_reference(Syntax::BlockEnd, "");

let first = subscopes
.iter()
.next()
.unwrap();
for scope in &subscopes[1..] {
self.append_scope(scope);
}

if let Scope::CodeBlock { .. } = first {
// do NOT increase indent
self.append_scopes(subscopes);
} else {
self.increase(4);
self.append_scopes(subscopes);
if !is_code {
self.decrease(4);
}
}
Expand Down Expand Up @@ -1249,7 +1270,7 @@ impl<'a, 'i> Line<'a, 'i> {
+ word.len() as u8;
} else {
self.current
.push((Syntax::Description, Cow::Borrowed(" ")));
.push((syntax, Cow::Borrowed(" ")));
self.current
.push((syntax, Cow::Borrowed(word)));
self.position += 1 + word.len() as u8;
Expand Down
9 changes: 7 additions & 2 deletions src/formatting/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ pub enum Syntax {
Language,
Attribute,
Structure,
BlockBegin,
BlockEnd,
}

/// Trait for different rendering backends (the no-op no-markup one, ANSI
Expand All @@ -41,7 +43,10 @@ pub trait Render {
pub struct Identity;

impl Render for Identity {
fn style(&self, _syntax: Syntax, content: &str) -> String {
content.to_string()
fn style(&self, syntax: Syntax, content: &str) -> String {
match syntax {
Syntax::BlockBegin | Syntax::BlockEnd => String::new(),
_ => content.to_string(),
}
}
}
1 change: 1 addition & 0 deletions src/highlighting/terminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ impl Render for Terminal {
.color(owo_colors::Rgb(153, 153, 153))
.bold()
.to_string(),
Syntax::BlockBegin | Syntax::BlockEnd => String::new(),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/highlighting/typst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ impl Render for Typst {
Syntax::Language => markup("fill: rgb(0xc4, 0xa0, 0x00), weight: \"bold\"", &content),
Syntax::Attribute => markup("weight: \"bold\"", &content),
Syntax::Structure => markup("fill: rgb(0x99, 0x99, 0x99), weight: \"bold\"", &content),
Syntax::BlockBegin | Syntax::BlockEnd => String::new(),
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/templating/checklist.typ
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
}

#let render-step(ordinal: none, title: none, body: (), role: none, responses: none, children: none) = {
block(breakable: false, {
if role != none {
text(weight: "bold")[#role]
parbreak()
Expand All @@ -43,6 +44,7 @@
parbreak()
}
if children != none { children }
})
}

// -- Default template --------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions src/templating/procedure.typ
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
}

#let render-step(ordinal: none, title: none, body: (), invocations: (), responses: none, children: none) = {
block(breakable: false, {
if invocations.len() > 0 {
text(size: 7pt, raw(invocations.join(", ")))
linebreak()
Expand All @@ -84,6 +85,7 @@
if children != none {
pad(left: 16pt, children)
}
})
}

#let render-response(value: none, condition: none) = {
Expand Down
2 changes: 2 additions & 0 deletions src/templating/source.typ
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@
#let render-language(c) = text(fill: rgb(0xc4, 0xa0, 0x00), weight: "bold", raw(c))
#let render-attribute(c) = text(weight: "bold", raw(c))
#let render-structure(c) = text(fill: rgb(0x99, 0x99, 0x99), weight: "bold", raw(c))
#let render-block(body) = block(breakable: false, spacing: 0.65em, body)

// -- Default template --------------------------------------------------------

#let template(body) = {
set text(font: "Inconsolata")
set par(spacing: 0.65em, leading: 0.65em)
show raw: set block(breakable: true)
body
}
Loading