Index: Cargo.toml
==================================================================
--- Cargo.toml
+++ Cargo.toml
@@ -1,8 +1,8 @@
[package]
name = "sidoc"
-version = "0.1.1"
+version = "0.1.2"
edition = "2021"
license = "0BSD"
# https://crates.io/category_slugs
categories = [ "template-engine" ]
keywords = [ "text", "document", "html" ]
Index: src/builder.rs
==================================================================
--- src/builder.rs
+++ src/builder.rs
@@ -31,10 +31,97 @@
} else {
self.scope_stack.push(None);
}
self
}
+
+ /// Wrap [`Builder::scope()`] and [`Builder::exit()`].
+ ///
+ /// Initialize a new scope, call caller-supplied closure, and automatically
+ /// exit scope before returning.
+ ///
+ /// ```
+ /// use std::sync::Arc;
+ /// use sidoc::{Builder, RenderContext};
+ ///
+ /// let mut bldr = Builder::new();
+ ///
+ /// bldr
+ /// .line("")
+ /// .autoscope("", Some(""), |bldr| {
+ /// bldr.autoscope("
", Some(""), |bldr| {
+ /// bldr.line("hello");
+ /// });
+ /// });
+ ///
+ /// let doc = bldr.build().unwrap();
+ /// let mut r = RenderContext::new();
+ /// r.doc("root", Arc::new(doc));
+ /// let buf = r.render("root").unwrap();
+ ///
+ /// assert_eq!(
+ /// buf,
+ /// "\n\n \n hello\n \n\n"
+ /// );
+ /// ```
+ #[allow(clippy::needless_pass_by_value)]
+ pub fn autoscope(
+ &mut self,
+ begin_line: L,
+ term_line: Option,
+ f: F
+ ) -> &mut Self
+ where
+ F: FnOnce(&mut Self)
+ {
+ self.scope(begin_line, term_line);
+ f(self);
+ self.exit();
+ self
+ }
+
+ /// Same as [`Builder::autoscope()`], but only init scope and call closure if
+ /// predicate is true.
+ #[allow(clippy::needless_pass_by_value)]
+ pub fn autoscope_if(
+ &mut self,
+ pred: bool,
+ begin_line: L,
+ term_line: Option,
+ f: F
+ ) -> &mut Self
+ where
+ F: FnOnce(&mut Self)
+ {
+ if pred {
+ self.scope(begin_line, term_line);
+ f(self);
+ self.exit();
+ }
+ self
+ }
+
+ /// Same as [`Builder::autoscope()`], but only init scope and call closure if
+ /// `opt` is `Some(T)`. `T` will be passed to the closure.
+ #[allow(clippy::needless_pass_by_value)]
+ pub fn autoscope_opt(
+ &mut self,
+ opt: Option,
+ begin_line: L,
+ term_line: Option,
+ f: F
+ ) -> &mut Self
+ where
+ F: FnOnce(&mut Self, T)
+ {
+ if let Some(o) = opt {
+ self.scope(begin_line, term_line);
+ f(self, o);
+ self.exit();
+ }
+ self
+ }
/// Leave a previously entered scope.
///
/// If the `scope()` call that created the current scope
///
ADDED tests/simple_html.rs
Index: tests/simple_html.rs
==================================================================
--- /dev/null
+++ tests/simple_html.rs
@@ -0,0 +1,77 @@
+use std::sync::Arc;
+
+use sidoc::{Builder, RenderContext};
+
+#[test]
+fn simple_html() {
+ let mut bldr = Builder::new();
+
+ bldr.line("");
+ bldr.scope("", Some("")).exit();
+
+ let doc = bldr.build().unwrap();
+
+ let mut r = RenderContext::new();
+
+ r.doc("hello", Arc::new(doc));
+
+ let buf = r.render("hello").unwrap();
+
+ assert_eq!(buf, "\n\n\n");
+}
+
+
+#[test]
+fn simple_html_head() {
+ let mut bldr = Builder::new();
+
+ bldr
+ .line("")
+ .scope("", Some(""))
+ .scope("", Some(""))
+ .exit()
+ .exit();
+
+ let doc = bldr.build().unwrap();
+
+ let mut r = RenderContext::new();
+
+ r.doc("root", Arc::new(doc));
+
+ let buf = r.render("root").unwrap();
+
+ assert_eq!(
+ buf,
+ "\n\n \n \n\n"
+ );
+}
+
+
+#[test]
+fn autoscope() {
+ let mut bldr = Builder::new();
+
+ bldr
+ .line("")
+ .autoscope("", Some(""), |bldr| {
+ bldr.autoscope("", Some(""), |bldr| {
+ bldr.line("hello");
+ });
+ });
+
+ let doc = bldr.build().unwrap();
+
+ let mut r = RenderContext::new();
+
+ r.doc("root", Arc::new(doc));
+
+ let buf = r.render("root").unwrap();
+
+ assert_eq!(
+ buf,
+ "\n\n \n hello\n \
+ \n\n"
+ );
+}
+
+// vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 :
DELETED tests/simple_http.rs
Index: tests/simple_http.rs
==================================================================
--- tests/simple_http.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-use std::sync::Arc;
-
-use sidoc::{Builder, RenderContext};
-
-#[test]
-fn simple_html() {
- let mut bldr = Builder::new();
-
- bldr.line("");
- bldr.scope("", Some("")).exit();
-
- let doc = bldr.build().unwrap();
-
- let mut r = RenderContext::new();
-
- r.doc("hello", Arc::new(doc));
-
- let buf = r.render("hello").unwrap();
-
- assert_eq!(buf, "\n\n\n");
-}
-
-
-#[test]
-fn simple_html_head() {
- let mut bldr = Builder::new();
-
- bldr
- .line("")
- .scope("", Some(""))
- .scope("", Some(""))
- .exit()
- .exit();
-
- let doc = bldr.build().unwrap();
-
- let mut r = RenderContext::new();
-
- r.doc("root", Arc::new(doc));
-
- let buf = r.render("root").unwrap();
-
- assert_eq!(
- buf,
- "\n\n \n \n\n"
- );
-}
-
-// vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 :
Index: www/changelog.md
==================================================================
--- www/changelog.md
+++ www/changelog.md
@@ -2,20 +2,36 @@
⚠️ indicates a breaking change.
## [Unreleased]
-[Details](/vdiff?from=sidoc-0.1.0&to=trunk)
+[Details](/vdiff?from=sidoc-0.1.1&to=trunk)
### Added
-- Derive `Default` on `Doc` and `RenderContext`
+- `Builder::autoscope()` is a helper for adding scopes that will automatically
+ be closed.
+- `Builder::autoscope_if()` is a variant of `Builder::autoscope()` that will
+ only add a scope, and call callback, if a predicate is true.
+- `Builder::autoscope_opt()` is another variant of `Builder::autoscope()` that
+ will only add scope, and call callback, if an input option paramter is
+ `Some(T)`.
### Changed
### Removed
+---
+
+## [0.1.1] - 2024-11-07
+
+[Details](/vdiff?from=sidoc-0.1.0&to=sidoc-0.1.1)
+
+### Added
+
+- Derive `Default` on `Doc` and `RenderContext`
+
---
## [0.1.0] - 2020-09-12
Initial release