summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorQrius <[email protected]>2024-09-26 00:11:05 +0200
committerQrius <[email protected]>2024-09-26 00:11:05 +0200
commitbaaa4f147e36f8f667557ee1c64c7240da624001 (patch)
treea9729129c86f11b47169b576dcd9367c417972d5 /src
parent0db0021655f45ce9b1a8dc64e5ca3e1cfd7535e1 (diff)
downloadskaldpress-baaa4f147e36f8f667557ee1c64c7240da624001.tar.gz
skaldpress-baaa4f147e36f8f667557ee1c64c7240da624001.zip
Add sorting function to YamlValue, make it possible to sort in special macros, add special parsing for dates and numbers
Diffstat (limited to 'src')
-rw-r--r--src/skaldpress/main.rs34
-rw-r--r--src/skaldpress/metadata_parser.rs56
2 files changed, 84 insertions, 6 deletions
diff --git a/src/skaldpress/main.rs b/src/skaldpress/main.rs
index 84a4285..45d0a78 100644
--- a/src/skaldpress/main.rs
+++ b/src/skaldpress/main.rs
@@ -33,6 +33,13 @@ struct CompiledFile {
source_path: String,
}
+/// SMP Macro for processing input with a template
+///
+/// This will keep state of the macro_processor from the document which invokes the macro.
+/// No additional metadata will be added.
+///
+/// Usage in files:
+/// template(<template>, <content>)
fn sp_template(
smp: &mut MacroProcessor,
macro_name: &str,
@@ -50,6 +57,10 @@ fn sp_template(
smp.process_input(&template)
}
+/// SMP Macro for getting all files with specific tag, this is only _really_ effective the second run
+///
+/// Usage in files:
+/// all_tagged_by(<tag name>, <template> [, <field to sort by>] [, reversed])
fn sp_all_tagged_by(
smp: &mut MacroProcessor,
macro_name: &str,
@@ -72,8 +83,29 @@ fn sp_all_tagged_by(
let mut out = String::new();
+ let mut tagged_files = tagged_files.clone();
+ if args.len() > 2 {
+ if args.len() > 3 && args[3] == "reversed" {
+ tagged_files.sort_by(|a, b| {
+ *(&compiled_files[*b]
+ .metadata
+ .get(&args[2])
+ .unwrap()
+ .cmp(&compiled_files[*a].metadata.get(&args[2]).unwrap()))
+ });
+ } else {
+ tagged_files.sort_by(|a, b| {
+ *(&compiled_files[*a]
+ .metadata
+ .get(&args[2])
+ .unwrap()
+ .cmp(&compiled_files[*b].metadata.get(&args[2]).unwrap()))
+ });
+ }
+ }
+
for doc_i in tagged_files {
- let file = &compiled_files[*doc_i];
+ let file = &compiled_files[doc_i];
let mut smp_local = macro_processor(&file.metadata, Some(smp));
out.push_str(&sp_template(
&mut smp_local,
diff --git a/src/skaldpress/metadata_parser.rs b/src/skaldpress/metadata_parser.rs
index 4d6e352..a2abcc2 100644
--- a/src/skaldpress/metadata_parser.rs
+++ b/src/skaldpress/metadata_parser.rs
@@ -1,9 +1,14 @@
+#[cfg(feature = "time")]
+use chrono::DateTime;
+use std::cmp::Ordering;
use std::collections::HashMap;
use std::fmt;
-#[derive(Debug)]
+#[derive(Eq, PartialEq, Debug)]
pub enum YamlValue {
Scalar(String),
+ Integer(i64),
+ Date(String, i64),
List(Vec<String>),
}
@@ -11,6 +16,8 @@ impl fmt::Display for YamlValue {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
YamlValue::Scalar(x) => write!(f, "{}", x),
+ YamlValue::Integer(x) => write!(f, "{}", x),
+ YamlValue::Date(x, _) => write!(f, "{}", x),
YamlValue::List(_l) => write!(f, "List<String>"),
}
}
@@ -22,11 +29,53 @@ impl TryFrom<&YamlValue> for String {
fn try_from(s: &YamlValue) -> Result<String, String> {
match s {
YamlValue::Scalar(s) => Ok(String::from(s)),
+ YamlValue::Integer(s) => Ok(s.to_string()),
+ YamlValue::Date(s, _) => Ok(s.to_string()),
YamlValue::List(_) => Err(String::from("List value cannot be turned into string")),
}
}
}
+impl PartialOrd for YamlValue {
+ fn partial_cmp(&self, other: &YamlValue) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl Ord for YamlValue {
+ fn cmp(&self, other: &YamlValue) -> Ordering {
+ if let YamlValue::Integer(a_int) = self {
+ if let YamlValue::Integer(b_int) = other {
+ return a_int.cmp(b_int);
+ }
+ }
+ if let YamlValue::Scalar(a_str) = self {
+ if let YamlValue::Scalar(b_str) = other {
+ return a_str.cmp(b_str);
+ }
+ }
+ if let YamlValue::Date(_, a_timestamp) = self {
+ if let YamlValue::Date(_, b_timestamp) = other {
+ return a_timestamp.cmp(b_timestamp);
+ }
+ }
+ self.to_string().cmp(&other.to_string())
+ }
+}
+
+fn str_to_yaml_value(in_str: &str) -> YamlValue {
+ let in_str = in_str.trim();
+ if let Ok(int) = in_str.parse::<i64>() {
+ return YamlValue::Integer(int);
+ }
+ #[cfg(feature = "time")]
+ if let Ok(dt) = DateTime::parse_from_rfc3339(in_str) {
+ return YamlValue::Date(in_str.to_string(), dt.timestamp());
+ }
+
+ YamlValue::Scalar(in_str.to_string())
+}
+
/// Extract a beginning YAML block of a input-string into a HashMap
pub fn extract_parse_yaml_metadata<'a>(
markdown: &'a str,
@@ -64,10 +113,7 @@ pub fn extract_parse_yaml_metadata<'a>(
}
current_key = Some(key.trim().to_string());
if !value.trim().is_empty() {
- yaml_map.insert(
- current_key.clone().unwrap(),
- YamlValue::Scalar(value.trim().to_string()),
- );
+ yaml_map.insert(current_key.clone().unwrap(), str_to_yaml_value(value));
current_key = None;
}
}