diff --git a/default_environment/templates/html/inline_source_block.dust b/default_environment/templates/html/inline_source_block.dust
index 7ab64e2..85ced05 100644
--- a/default_environment/templates/html/inline_source_block.dust
+++ b/default_environment/templates/html/inline_source_block.dust
@@ -1 +1 @@
-!!!!!!!! inline_source_block
+{.value}
diff --git a/default_environment/templates/html/src_block.dust b/default_environment/templates/html/src_block.dust
index 02185e2..22e7f33 100644
--- a/default_environment/templates/html/src_block.dust
+++ b/default_environment/templates/html/src_block.dust
@@ -1 +1,9 @@
-!!!!!!!! src_block
+
+
+ {#.lines}
+
+ {.} |
+
+ {/.lines}
+
+
diff --git a/src/context/inline_source_block.rs b/src/context/inline_source_block.rs
index 9972c95..8aa3ced 100644
--- a/src/context/inline_source_block.rs
+++ b/src/context/inline_source_block.rs
@@ -9,15 +9,19 @@ use crate::intermediate::IInlineSourceBlock;
#[derive(Debug, Serialize)]
#[serde(tag = "type")]
#[serde(rename = "inline_source_block")]
-pub(crate) struct RenderInlineSourceBlock {}
+pub(crate) struct RenderInlineSourceBlock {
+ value: String,
+}
impl RenderInlineSourceBlock {
pub(crate) fn new(
config: &Config,
output_directory: &Path,
output_file: &Path,
- comment: &IInlineSourceBlock,
+ original: &IInlineSourceBlock,
) -> Result {
- Ok(RenderInlineSourceBlock {})
+ Ok(RenderInlineSourceBlock {
+ value: original.value.clone(),
+ })
}
}
diff --git a/src/context/src_block.rs b/src/context/src_block.rs
index 0c19570..6c06124 100644
--- a/src/context/src_block.rs
+++ b/src/context/src_block.rs
@@ -9,7 +9,9 @@ use crate::intermediate::ISrcBlock;
#[derive(Debug, Serialize)]
#[serde(tag = "type")]
#[serde(rename = "src_block")]
-pub(crate) struct RenderSrcBlock {}
+pub(crate) struct RenderSrcBlock {
+ lines: Vec,
+}
impl RenderSrcBlock {
pub(crate) fn new(
@@ -18,6 +20,8 @@ impl RenderSrcBlock {
output_file: &Path,
original: &ISrcBlock,
) -> Result {
- Ok(RenderSrcBlock {})
+ Ok(RenderSrcBlock {
+ lines: original.lines.clone(),
+ })
}
}
diff --git a/src/intermediate/inline_source_block.rs b/src/intermediate/inline_source_block.rs
index 5a90e29..29071b3 100644
--- a/src/intermediate/inline_source_block.rs
+++ b/src/intermediate/inline_source_block.rs
@@ -3,13 +3,17 @@ use crate::error::CustomError;
use super::registry::Registry;
#[derive(Debug)]
-pub(crate) struct IInlineSourceBlock {}
+pub(crate) struct IInlineSourceBlock {
+ pub(crate) value: String,
+}
impl IInlineSourceBlock {
pub(crate) async fn new<'parse>(
registry: &mut Registry<'parse>,
original: &organic::types::InlineSourceBlock<'parse>,
) -> Result {
- Ok(IInlineSourceBlock {})
+ Ok(IInlineSourceBlock {
+ value: original.value.to_owned(),
+ })
}
}
diff --git a/src/intermediate/src_block.rs b/src/intermediate/src_block.rs
index ed90cd0..9577179 100644
--- a/src/intermediate/src_block.rs
+++ b/src/intermediate/src_block.rs
@@ -1,15 +1,23 @@
use crate::error::CustomError;
use super::registry::Registry;
+use super::util::GetFullLines;
#[derive(Debug)]
-pub(crate) struct ISrcBlock {}
+pub(crate) struct ISrcBlock {
+ pub(crate) lines: Vec,
+}
impl ISrcBlock {
pub(crate) async fn new<'parse>(
registry: &mut Registry<'parse>,
original: &organic::types::SrcBlock<'parse>,
) -> Result {
- Ok(ISrcBlock {})
+ let lines = original
+ .contents
+ .full_lines()
+ .map(|s| s.to_owned())
+ .collect();
+ Ok(ISrcBlock { lines })
}
}
diff --git a/src/intermediate/util.rs b/src/intermediate/util.rs
index b482b98..f2718dc 100644
--- a/src/intermediate/util.rs
+++ b/src/intermediate/util.rs
@@ -46,3 +46,129 @@ enum CoalesceWhitespace {
Normal,
HasWhitespace { in_whitespace: bool, ret: String },
}
+
+pub(crate) struct FullLinesIterator<'i> {
+ inner: Option<&'i str>,
+}
+
+impl<'i> Iterator for FullLinesIterator<'i> {
+ type Item = &'i str;
+
+ fn next(&mut self) -> Option {
+ if let Some(inner) = self.inner {
+ for (i, c) in inner.char_indices() {
+ if c == '\n' {
+ let (current_line, remainder) = inner.split_at(i + 1);
+ self.inner = Some(remainder);
+ return Some(current_line);
+ }
+ }
+ if inner.is_empty() {
+ None
+ } else {
+ let final_unterminated_line = Some(inner);
+ self.inner = None;
+ final_unterminated_line
+ }
+ } else {
+ None
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option) {
+ if let Some(inner) = self.inner {
+ let line_count = {
+ inner.bytes().filter(|b| *b == b'\n').count()
+ + (if inner.ends_with('\n') { 0 } else { 1 })
+ };
+ (line_count, Some(line_count))
+ } else {
+ (0, Some(0))
+ }
+ }
+}
+
+impl ExactSizeIterator for FullLinesIterator<'_> {}
+
+pub(crate) trait GetFullLines {
+ fn full_lines(&self) -> FullLinesIterator<'_>;
+}
+
+impl<'s, S: AsRef> GetFullLines for S {
+ fn full_lines(&self) -> FullLinesIterator<'_> {
+ let inner = self.as_ref();
+ FullLinesIterator {
+ inner: if inner.is_empty() { None } else { Some(inner) },
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_full_lines_iterator() {
+ {
+ let input = "foo\nbar\nbaz";
+ assert_eq!(input.lines().count(), input.full_lines().count());
+ assert_eq!(input.lines().count(), input.full_lines().len());
+ assert_eq!(input.lines().collect::>(), vec!["foo", "bar", "baz"]);
+ assert_eq!(
+ input.full_lines().collect::>(),
+ vec!["foo\n", "bar\n", "baz"]
+ );
+ }
+
+ {
+ // Trailing newline
+ let input = "foo\nbar\nbaz\n";
+ assert_eq!(input.lines().count(), input.full_lines().count());
+ assert_eq!(input.lines().count(), input.full_lines().len());
+ assert_eq!(input.lines().collect::>(), vec!["foo", "bar", "baz"]);
+ assert_eq!(
+ input.full_lines().collect::>(),
+ vec!["foo\n", "bar\n", "baz\n"]
+ );
+ }
+
+ {
+ // Leading newline
+ let input = "\nfoo\nbar\nbaz";
+ assert_eq!(input.lines().count(), input.full_lines().count());
+ assert_eq!(input.lines().count(), input.full_lines().len());
+ assert_eq!(
+ input.lines().collect::>(),
+ vec!["", "foo", "bar", "baz"]
+ );
+ assert_eq!(
+ input.full_lines().collect::>(),
+ vec!["\n", "foo\n", "bar\n", "baz"]
+ );
+ }
+
+ {
+ // Double newline
+ let input = "foo\nbar\n\nbaz";
+ assert_eq!(input.lines().count(), input.full_lines().count());
+ assert_eq!(input.lines().count(), input.full_lines().len());
+ assert_eq!(
+ input.lines().collect::>(),
+ vec!["foo", "bar", "", "baz"]
+ );
+ assert_eq!(
+ input.full_lines().collect::>(),
+ vec!["foo\n", "bar\n", "\n", "baz"]
+ );
+ }
+
+ {
+ // Empty
+ let input = "";
+ assert_eq!(input.lines().count(), input.full_lines().count());
+ assert_eq!(input.lines().count(), input.full_lines().len());
+ assert_eq!(input.lines().collect::>(), Vec::<&str>::new());
+ assert_eq!(input.full_lines().collect::>(), Vec::<&str>::new());
+ }
+ }
+}