X-Git-Url: http://git.scottworley.com/tablify/blobdiff_plain/fdc441dab9c793956ea5c6e4a7c766eb87b16588..7a246d87bb2de224662bb80526fd5ed31be05cbe:/src/lib.rs
diff --git a/src/lib.rs b/src/lib.rs
index 731457e..bfcfdec 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -4,10 +4,18 @@ use std::fmt::Write;
use std::io::BufRead;
use std::iter::Iterator;
-fn tally_marks(n: usize, mark: Option<&str>) -> String {
- let fives = { 0..n / 5 }.map(|_| 'ð¸');
- let ones = { 0..n % 5 }.map(|_| 'ð·');
- fives.chain(ones).collect()
+const TALLY_FONT: &str = "BabelStone Han";
+
+fn tally_marks(n: usize, mark: Option<&str>) -> HTML {
+ HTML(match mark {
+ None => {
+ let fives = { 0..n / 5 }.map(|_| 'ð¸');
+ let ones = { 0..n % 5 }.map(|_| 'ð·');
+ let marks: String = fives.chain(ones).collect();
+ format!("{marks}")
+ }
+ Some(m) => { 0..n }.map(|_| m).collect(),
+ })
}
#[derive(PartialEq, Eq, Debug)]
@@ -45,6 +53,16 @@ impl Config {
.substitute_labels
.insert(col.to_owned(), label.to_owned()),
};
+ } else if let Some(directive) = cmd.strip_prefix("mark ") {
+ match directive.split_once(':') {
+ None => {
+ return Err(std::io::Error::new(
+ std::io::ErrorKind::InvalidInput,
+ format!("line {line_num}: Mark missing ':'"),
+ ))
+ }
+ Some((col, label)) => self.mark.insert(col.to_owned(), label.to_owned()),
+ };
} else {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
@@ -192,9 +210,7 @@ impl<'cfg, Input: Iterator- >> Reader<'cfg,
}
}
}
-impl<'cfg, Input: Iterator
- >> Iterator
- for Reader<'cfg, Input>
-{
+impl>> Iterator for Reader<'_, Input> {
type Item = Result;
fn next(&mut self) -> Option {
loop {
@@ -211,7 +227,7 @@ impl<'cfg, Input: Iterator
- >> Iterator
return Ok(std::mem::take(&mut self.row).map(Rowlike::Row)).transpose()
}
InputLine::Blank => return Some(Ok(Rowlike::Spacer)),
- InputLine::Entry(col, instance) => match &mut self.row {
+ InputLine::Entry(col, instance) => match self.row {
None => {
return Some(Err(std::io::Error::other(format!(
"line {}: Entry with no header",
@@ -253,8 +269,8 @@ fn column_counts(rows: &[Rowlike]) -> Vec<(usize, String)> {
let empty = HashMap::new();
let mut counts: Vec<_> = rows
.iter()
- .flat_map(|rl| match rl {
- Rowlike::Row(r) => r.entries.keys(),
+ .flat_map(|rl| match *rl {
+ Rowlike::Row(ref r) => r.entries.keys(),
Rowlike::Spacer => empty.keys(),
})
.fold(HashMap::new(), |mut cs, col| {
@@ -266,7 +282,7 @@ fn column_counts(rows: &[Rowlike]) -> Vec<(usize, String)> {
.into_iter()
.map(|(col, n)| (n, col))
.collect();
- counts.sort_unstable_by(|(an, acol), (bn, bcol)| bn.cmp(an).then(acol.cmp(bcol)));
+ counts.sort_unstable_by(|a, b| b.0.cmp(&a.0).then(a.1.cmp(&b.1)));
counts
}
fn column_order(config: &Config, rows: &[Rowlike]) -> Vec {
@@ -291,11 +307,11 @@ fn render_instances(instances: &[Option], mark: Option<&str>) -> HTML {
let mut tally = 0;
let mut out = vec![];
for ins in instances {
- match ins {
+ match *ins {
None => tally += 1,
- Some(content) => {
+ Some(ref content) => {
if tally > 0 {
- out.push(HTML(tally_marks(tally, mark)));
+ out.push(tally_marks(tally, mark));
tally = 0;
}
out.push(HTML::escape(content));
@@ -303,11 +319,11 @@ fn render_instances(instances: &[Option], mark: Option<&str>) -> HTML {
}
}
if tally > 0 {
- out.push(HTML(tally_marks(tally, mark)));
+ out.push(tally_marks(tally, mark));
}
HTML(
out.into_iter()
- .map(|html| html.0) // Waiting for slice_concat_trait to stabilize
+ .map(|html| html.0)
.collect::>()
.join(" "),
)
@@ -324,9 +340,9 @@ fn render_cell(config: &Config, col: &str, row: &mut Row) -> HTML {
let instances: Option<&Vec