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

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions examples/golden/Bedtime.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
% technique v1
! Private; © 2025 My Lovely Family
& childrens-task-list

I. Before school

1. Drink glass of water
2. Eat breakfast
3. Put dishes into sink
4. Get changed
5. Pack school bag
6. Clean teeth
7. Shoes on, wait by front door!

II. After school

1. Shower
2. Get changed into home clothes
3. Bring lunchbox to kitchen
4. Put dirty school clothes at washing machine
5. Turn on heater
6. Homework (as required)

III. Dinner

1. Set table
2. Eat dinner
3. Put dishes into dishwasher

IV. Bedtime

1. Get changed into pyjamas
2. Clean teeth
3. Read story
4. Into bed!
37 changes: 25 additions & 12 deletions src/formatting/formatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,12 @@ impl<'i> Formatter<'i> {
}

fn switch_syntax(&mut self, new_syntax: Syntax) {
if !self.buffer.is_empty() {
self.fragments.push((
self.current,
Cow::Owned(std::mem::take(&mut self.buffer)),
));
if !self
.buffer
.is_empty()
{
self.fragments
.push((self.current, Cow::Owned(std::mem::take(&mut self.buffer))));
}
self.current = new_syntax;
}
Expand All @@ -234,11 +235,12 @@ impl<'i> Formatter<'i> {
}

pub fn flush_current(&mut self) {
if !self.buffer.is_empty() {
self.fragments.push((
self.current,
Cow::Owned(std::mem::take(&mut self.buffer)),
));
if !self
.buffer
.is_empty()
{
self.fragments
.push((self.current, Cow::Owned(std::mem::take(&mut self.buffer))));
}
}

Expand Down Expand Up @@ -410,6 +412,11 @@ impl<'i> Formatter<'i> {
fn format_technique(&mut self, technique: &'i Technique) {
match technique {
Technique::Steps(steps) => {
// if a header has already been added,
// separate the upcoming steps with a blank line.
if !self.is_empty() {
self.append_char('\n');
}
self.append_steps(steps);
}
Technique::Procedures(procedures) => {
Expand Down Expand Up @@ -1242,7 +1249,10 @@ impl<'a, 'i> Line<'a, 'i> {

fn wrap_line(&mut self) {
// Emit all current fragments to the output
for (syntax, content) in self.current.drain(..) {
for (syntax, content) in self
.current
.drain(..)
{
self.output
.add_fragment(syntax, content);
}
Expand All @@ -1261,7 +1271,10 @@ impl<'a, 'i> Line<'a, 'i> {
.is_empty()
{
// Emit all current fragments to the output
for (syntax, content) in self.current.drain(..) {
for (syntax, content) in self
.current
.drain(..)
{
self.output
.add_fragment(syntax, content);
}
Expand Down
37 changes: 29 additions & 8 deletions src/parsing/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ impl<'i> Parser<'i> {

// Parse zero or more procedures, handling sections if they exist
let mut procedures = Vec::new();
let mut sections = Vec::new();

while !self.is_finished() {
self.trim_whitespace();
Expand All @@ -132,7 +133,25 @@ impl<'i> Parser<'i> {
break;
}

if is_procedure_declaration(self.source) {
// Check if this Technique is a a single set of one or more
// top-level Scope::SectionChunk

if is_section(self.source) && procedures.is_empty() {
while !self.is_finished() {
self.trim_whitespace();
if self.is_finished() {
break;
}

if is_section(self.source) {
let section = self.read_section()?;
sections.push(section);
} else {
return Err(ParsingError::Unrecognized(self.offset));
}
}
break;
} else if is_procedure_declaration(self.source) {
let mut procedure = self.take_block_lines(
is_procedure_declaration,
|line| is_section(line) || is_procedure_declaration(line),
Expand Down Expand Up @@ -186,10 +205,12 @@ impl<'i> Parser<'i> {
}
}

let body = if procedures.is_empty() {
None
} else {
let body = if !sections.is_empty() {
Some(Technique::Steps(sections))
} else if !procedures.is_empty() {
Some(Technique::Procedures(procedures))
} else {
None
};

Ok(Document { header, body })
Expand Down Expand Up @@ -890,11 +911,11 @@ impl<'i> Parser<'i> {
}

// Try to parse steps
if is_substep_dependent(outer.source) {
let step = outer.read_substep_dependent()?;
if is_step_dependent(outer.source) {
let step = outer.read_step_dependent()?;
steps.push(step);
} else if is_substep_parallel(outer.source) {
let step = outer.read_substep_parallel()?;
} else if is_step_parallel(outer.source) {
let step = outer.read_step_parallel()?;
steps.push(step);
} else {
// Skip unrecognized content line by line
Expand Down