From ec334c2821157c2463d53b5524377354a29d1ade Mon Sep 17 00:00:00 2001 From: PoiScript Date: Mon, 28 Oct 2019 16:02:56 +0800 Subject: [PATCH] chore: rename several functions --- examples/custom.rs | 2 +- src/headline.rs | 212 ++++++++++++++++++++------------------------- src/org.rs | 82 ++++++++++++++---- src/validate.rs | 4 +- tests/blank.rs | 2 +- tests/parse.rs | 20 +++-- 6 files changed, 177 insertions(+), 145 deletions(-) diff --git a/examples/custom.rs b/examples/custom.rs index 01468ea..3f650ff 100644 --- a/examples/custom.rs +++ b/examples/custom.rs @@ -72,7 +72,7 @@ fn main() -> Result<(), MyError> { let mut writer = Vec::new(); let mut handler = MyHtmlHandler::default(); - Org::parse(&contents).html_with_handler(&mut writer, &mut handler)?; + Org::parse(&contents).write_html_custom(&mut writer, &mut handler)?; println!("{}", String::from_utf8(writer)?); } diff --git a/src/headline.rs b/src/headline.rs index 88f6f1c..e584419 100644 --- a/src/headline.rs +++ b/src/headline.rs @@ -34,7 +34,8 @@ impl Document { }) } - /// Retuen the ID of the section element of this document, or `None` if it has no section. + /// Returns the ID of the section element of this document, + /// or `None` if it has no section. pub fn section_node(self) -> Option { self.0.sec_n } @@ -45,7 +46,8 @@ impl Document { /// # use orgize::Org; /// # /// let mut org = Org::parse( - /// r#"** h1 + /// r#" + /// ** h1 /// ** h2 /// *** h2_1 /// *** h2_2 @@ -74,13 +76,14 @@ impl Document { }) } - /// Returns the first child of this document, or None if it has no child. + /// Returns the first child of this document, or `None` if it has no child. /// /// ```rust /// # use orgize::Org; /// # /// let mut org = Org::parse( - /// r#"** h1 + /// r#" + /// ** h1 /// ** h2 /// *** h2_1 /// *** h2_2 @@ -112,13 +115,14 @@ impl Document { }) } - /// Returns the last child of this document, or None if it has no child. + /// Returns the last child of this document, or `None` if it has no child. /// /// ```rust /// # use orgize::Org; /// # /// let mut org = Org::parse( - /// r#"** h1_1 + /// r#" + /// ** h1_1 /// ** h1_2 /// *** h1_2_1 /// *** h1_2_2 @@ -148,7 +152,8 @@ impl Document { /// # use orgize::Org; /// # /// let mut org = Org::parse( - /// r#"** h1_1 + /// r#" + /// ** h1_1 /// ** h1_2 /// "#, /// ); @@ -161,7 +166,8 @@ impl Document { /// org.org(&mut writer).unwrap(); /// assert_eq!( /// String::from_utf8(writer).unwrap(), - /// r#"s + /// r#" + /// s /// ** h1_1 /// ** h1_2 /// "#, @@ -215,7 +221,8 @@ impl Document { /// # use orgize::{elements::Title, Headline, Org}; /// # /// let mut org = Org::parse( - /// r#"***** h1 + /// r#" + /// ***** h1 /// **** h2 /// *** h3 /// "#, @@ -242,7 +249,8 @@ impl Document { /// org.org(&mut writer).unwrap(); /// assert_eq!( /// String::from_utf8(writer).unwrap(), - /// r#"***** h1 + /// r#" + /// ***** h1 /// **** h2 /// *** h3 /// ** h4 @@ -265,7 +273,8 @@ impl Document { /// # use orgize::{elements::Title, Headline, Org}; /// # /// let mut org = Org::parse( - /// r#"** h2 + /// r#" + /// ** h2 /// ** h3 /// "#, /// ); @@ -291,7 +300,8 @@ impl Document { /// org.org(&mut writer).unwrap(); /// assert_eq!( /// String::from_utf8(writer).unwrap(), - /// r#"**** h1 + /// r#" + /// **** h1 /// ** h2 /// ** h3 /// "#, @@ -389,17 +399,17 @@ impl Headline { self.lvl } - /// Retuen the ID of the headline element of this headline. + /// Returns the ID of the headline element of this headline. pub fn headline_node(self) -> NodeId { self.hdl_n } - /// Retuen the ID of the title element of this headline. + /// Returns the ID of the title element of this headline. pub fn title_node(self) -> NodeId { self.ttl_n } - /// Retuen the ID of the section element of this headline, or `None` if it has no section.. + /// Returns the ID of the section element of this headline, or `None` if it has no section. pub fn section_node(self) -> Option { self.sec_n } @@ -425,9 +435,7 @@ impl Headline { /// # /// let mut org = Org::parse("* h1"); /// - /// // .. - /// # let headlines = org.headlines().collect::>(); - /// # let h1 = headlines[0]; + /// let h1 = org.headlines().nth(0).unwrap(); /// /// h1.title_mut(&mut org).priority = Some('A'); /// @@ -454,19 +462,15 @@ impl Headline { /// # use orgize::{elements::Title, Headline, Org}; /// # /// let mut org = Org::parse( - /// r#"* h1 + /// r#" + /// * h1 /// ****** h1_1 /// *** h1_2 /// ** h1_3 /// "#, /// ); /// - /// // .. - /// # let headlines = org.headlines().collect::>(); - /// # let h1 = headlines[0]; - /// # let h1_1 = headlines[1]; - /// # let mut h1_2 = headlines[2]; - /// # let h1_3 = headlines[3]; + /// let mut h1_2 = org.headlines().nth(2).unwrap(); /// /// // level must be greater than or equal to 2, and smaller than or equal to 6 /// assert!(h1_2.set_level(42, &mut org).is_err()); @@ -477,7 +481,8 @@ impl Headline { /// org.org(&mut writer).unwrap(); /// assert_eq!( /// String::from_utf8(writer).unwrap(), - /// r#"* h1 + /// r#" + /// * h1 /// ****** h1_1 /// ***** h1_2 /// ** h1_3 @@ -526,15 +531,14 @@ impl Headline { /// # use orgize::Org; /// # /// let mut org = Org::parse( - /// r#"* h1 + /// r#" + /// * h1 /// ** h1_1 /// "#, /// ); /// - /// // .. - /// # let headlines = org.headlines().collect::>(); - /// # let h1 = headlines[0]; - /// # let h1_1 = headlines[1]; + /// let h1 = org.headlines().nth(0).unwrap(); + /// let h1_1 = org.headlines().nth(1).unwrap(); /// /// h1.set_title_content("H1", &mut org); /// h1_1.set_title_content(String::from("*H1_1*"), &mut org); @@ -543,7 +547,8 @@ impl Headline { /// org.org(&mut writer).unwrap(); /// assert_eq!( /// String::from_utf8(writer).unwrap(), - /// r#"* H1 + /// r#" + /// * H1 /// ** *H1_1* /// "#, /// ); @@ -589,16 +594,15 @@ impl Headline { /// # use orgize::Org; /// # /// let mut org = Org::parse( - /// r#"* h1 + /// r#" + /// * h1 /// ** h1_1 /// s1_1 /// "#, /// ); /// - /// // .. - /// # let headlines = org.headlines().collect::>(); - /// # let mut h1 = headlines[0]; - /// # let mut h1_1 = headlines[1]; + /// let mut h1 = org.headlines().nth(0).unwrap(); + /// let mut h1_1 = org.headlines().nth(1).unwrap(); /// /// h1.set_section_content("s1", &mut org); /// h1_1.set_section_content(String::from("*s1_1*"), &mut org); @@ -607,7 +611,8 @@ impl Headline { /// org.org(&mut writer).unwrap(); /// assert_eq!( /// String::from_utf8(writer).unwrap(), - /// r#"* h1 + /// r#" + /// * h1 /// s1 /// ** h1_1 /// *s1_1* @@ -659,7 +664,8 @@ impl Headline { /// # use orgize::{elements::Title, Headline, Org}; /// # /// let mut org = Org::parse( - /// r#"* h1 + /// r#" + /// * h1 /// ** h1_1 /// ** h1_2 /// *** h1_2_1 @@ -668,11 +674,9 @@ impl Headline { /// "#, /// ); /// - /// // .. - /// # let headlines = org.headlines().collect::>(); - /// # let h1 = headlines[0]; - /// # let h1_1 = headlines[1]; - /// # let h1_2_1 = headlines[3]; + /// let h1 = org.headlines().nth(0).unwrap(); + /// let h1_1 = org.headlines().nth(1).unwrap(); + /// let h1_2_1 = org.headlines().nth(3).unwrap(); /// /// assert_eq!(h1_1.parent(&org).unwrap().title(&org).raw, "h1"); /// assert_eq!(h1_2_1.parent(&org).unwrap().title(&org).raw, "h1_2"); @@ -696,7 +700,8 @@ impl Headline { /// # use orgize::Org; /// # /// let mut org = Org::parse( - /// r#"* h1 + /// r#" + /// * h1 /// ** h1_1 /// ** h1_2 /// *** h1_2_1 @@ -705,9 +710,7 @@ impl Headline { /// "#, /// ); /// - /// // .. - /// # let headlines = org.headlines().collect::>(); - /// # let h1 = headlines[0]; + /// let h1 = org.headlines().nth(0).unwrap(); /// /// let mut iter = h1.children(&org); /// @@ -732,7 +735,8 @@ impl Headline { /// # use orgize::Org; /// # /// let mut org = Org::parse( - /// r#"* h1 + /// r#" + /// * h1 /// ** h1_1 /// ** h1_2 /// *** h1_2_1 @@ -741,14 +745,9 @@ impl Headline { /// "#, /// ); /// - /// // .. - /// # let headlines = org.headlines().collect::>(); - /// # let h1 = headlines[0]; - /// # let h1_1 = headlines[1]; - /// # let h1_2 = headlines[2]; - /// # let h1_2_1 = headlines[3]; - /// # let h1_2_2 = headlines[4]; - /// # let h1_3 = headlines[5]; + /// let h1_1 = org.headlines().nth(1).unwrap(); + /// let h1_2 = org.headlines().nth(2).unwrap(); + /// let h1_3 = org.headlines().nth(5).unwrap(); /// /// assert_eq!(h1_2.first_child(&org).unwrap().title(&org).raw, "h1_2_1"); /// @@ -771,7 +770,8 @@ impl Headline { /// # use orgize::Org; /// # /// let mut org = Org::parse( - /// r#"* h1 + /// r#" + /// * h1 /// ** h1_1 /// ** h1_2 /// *** h1_2_1 @@ -780,14 +780,9 @@ impl Headline { /// "#, /// ); /// - /// // .. - /// # let headlines = org.headlines().collect::>(); - /// # let h1 = headlines[0]; - /// # let h1_1 = headlines[1]; - /// # let h1_2 = headlines[2]; - /// # let h1_2_1 = headlines[3]; - /// # let h1_2_2 = headlines[4]; - /// # let h1_3 = headlines[5]; + /// let h1_1 = org.headlines().nth(1).unwrap(); + /// let h1_2 = org.headlines().nth(2).unwrap(); + /// let h1_3 = org.headlines().nth(5).unwrap(); /// /// assert_eq!(h1_2.last_child(&org).unwrap().title(&org).raw, "h1_2_2"); /// @@ -810,7 +805,8 @@ impl Headline { /// # use orgize::Org; /// # /// let mut org = Org::parse( - /// r#"* h1 + /// r#" + /// * h1 /// ** h1_1 /// ** h1_2 /// *** h1_2_1 @@ -819,14 +815,9 @@ impl Headline { /// "#, /// ); /// - /// // .. - /// # let headlines = org.headlines().collect::>(); - /// # let h1 = headlines[0]; - /// # let h1_1 = headlines[1]; - /// # let h1_2 = headlines[2]; - /// # let h1_2_1 = headlines[3]; - /// # let h1_2_2 = headlines[4]; - /// # let h1_3 = headlines[5]; + /// let h1_1 = org.headlines().nth(1).unwrap(); + /// let h1_2 = org.headlines().nth(2).unwrap(); + /// let h1_2_1 = org.headlines().nth(3).unwrap(); /// /// assert_eq!(h1_2.previous(&org).unwrap().title(&org).raw, "h1_1"); /// @@ -849,7 +840,8 @@ impl Headline { /// # use orgize::Org; /// # /// let mut org = Org::parse( - /// r#"* h1 + /// r#" + /// * h1 /// ** h1_1 /// ** h1_2 /// *** h1_2_1 @@ -858,14 +850,9 @@ impl Headline { /// "#, /// ); /// - /// // .. - /// # let headlines = org.headlines().collect::>(); - /// # let h1 = headlines[0]; - /// # let h1_1 = headlines[1]; - /// # let h1_2 = headlines[2]; - /// # let h1_2_1 = headlines[3]; - /// # let h1_2_2 = headlines[4]; - /// # let h1_3 = headlines[5]; + /// let h1_2 = org.headlines().nth(2).unwrap(); + /// let h1_2_2 = org.headlines().nth(4).unwrap(); + /// let h1_3 = org.headlines().nth(5).unwrap(); /// /// assert_eq!(h1_2.next(&org).unwrap().title(&org).raw, "h1_3"); /// @@ -885,7 +872,8 @@ impl Headline { /// # use orgize::Org; /// # /// let mut org = Org::parse( - /// r#"* h1 + /// r#" + /// * h1 /// ** h1_1 /// ** h1_2 /// *** h1_2_1 @@ -894,11 +882,7 @@ impl Headline { /// "#, /// ); /// - /// // .. - /// # let headlines = org.headlines().collect::>(); - /// # let h1 = headlines[0]; - /// # let h1_1 = headlines[1]; - /// # let h1_2 = headlines[2]; + /// let h1_2 = org.headlines().nth(2).unwrap(); /// /// h1_2.detach(&mut org); /// @@ -906,7 +890,8 @@ impl Headline { /// org.org(&mut writer).unwrap(); /// assert_eq!( /// String::from_utf8(writer).unwrap(), - /// r#"* h1 + /// r#" + /// * h1 /// ** h1_1 /// ** h1_3 /// "#, @@ -930,16 +915,14 @@ impl Headline { /// # use orgize::{elements::Title, Headline, Org}; /// # /// let mut org = Org::parse( - /// r#"* h1 + /// r#" + /// * h1 /// ** h1_1 /// ***** h1_1_1 /// "#, /// ); /// - /// // .. - /// # let headlines = org.headlines().collect::>(); - /// # let h1 = headlines[0]; - /// # let h1_1 = headlines[1]; + /// let h1_1 = org.headlines().nth(1).unwrap(); /// /// let mut h1_1_2 = Headline::new( /// Title { @@ -962,7 +945,8 @@ impl Headline { /// org.org(&mut writer).unwrap(); /// assert_eq!( /// String::from_utf8(writer).unwrap(), - /// r#"* h1 + /// r#" + /// * h1 /// ** h1_1 /// ***** h1_1_1 /// **** h1_1_2 @@ -997,16 +981,14 @@ impl Headline { /// # use orgize::{elements::Title, Headline, Org}; /// # /// let mut org = Org::parse( - /// r#"* h1 + /// r#" + /// * h1 /// ** h1_1 /// ***** h1_1_1 /// "#, /// ); /// - /// // .. - /// # let headlines = org.headlines().collect::>(); - /// # let h1 = headlines[0]; - /// # let h1_1 = headlines[1]; + /// let h1_1 = org.headlines().nth(1).unwrap(); /// /// let mut h1_1_2 = Headline::new( /// Title { @@ -1053,19 +1035,15 @@ impl Headline { /// # use orgize::{elements::Title, Headline, Org}; /// # /// let mut org = Org::parse( - /// r#"* h1 + /// r#" + /// * h1 /// ** h1_1 /// **** h1_1_1 /// *** h1_1_3 /// "#, /// ); /// - /// // .. - /// # let headlines = org.headlines().collect::>(); - /// # let h1 = headlines[0]; - /// # let h1_1 = headlines[1]; - /// # let h1_1_1 = headlines[2]; - /// # let h1_1_3 = headlines[3]; + /// let h1_1_3 = org.headlines().nth(3).unwrap(); /// /// let mut h1_1_2 = Headline::new( /// Title { @@ -1088,7 +1066,8 @@ impl Headline { /// org.org(&mut writer).unwrap(); /// assert_eq!( /// String::from_utf8(writer).unwrap(), - /// r#"* h1 + /// r#" + /// * h1 /// ** h1_1 /// **** h1_1_1 /// **** h1_1_2 @@ -1124,19 +1103,15 @@ impl Headline { /// # use orgize::{elements::Title, Headline, Org}; /// # /// let mut org = Org::parse( - /// r#"* h1 + /// r#" + /// * h1 /// ** h1_1 /// **** h1_1_1 /// *** h1_1_3 /// "#, /// ); /// - /// // .. - /// # let headlines = org.headlines().collect::>(); - /// # let h1 = headlines[0]; - /// # let h1_1 = headlines[1]; - /// # let h1_1_1 = headlines[2]; - /// # let h1_1_3 = headlines[3]; + /// let h1_1_1 = org.headlines().nth(2).unwrap(); /// /// let mut h1_1_2 = Headline::new( /// Title { @@ -1159,7 +1134,8 @@ impl Headline { /// org.org(&mut writer).unwrap(); /// assert_eq!( /// String::from_utf8(writer).unwrap(), - /// r#"* h1 + /// r#" + /// * h1 /// ** h1_1 /// **** h1_1_1 /// **** h1_1_2 diff --git a/src/org.rs b/src/org.rs index c7c5c89..9f16f96 100644 --- a/src/org.rs +++ b/src/org.rs @@ -21,23 +21,23 @@ pub enum Event<'a, 'b> { } impl<'a> Org<'a> { - /// Create a new empty `Org` struct + /// Creates a new empty `Org` struct. pub fn new() -> Org<'static> { let mut arena = Arena::new(); let root = arena.new_node(Element::Document { pre_blank: 0 }); Org { arena, root } } - /// Create a new `Org` struct from parsing `text`, using the default ParseConfig + /// Parses string `text` into `Org` struct. pub fn parse(text: &'a str) -> Org<'a> { - Org::parse_with_config(text, &DEFAULT_CONFIG) + Org::parse_custom(text, &DEFAULT_CONFIG) } - /// Create a new Org struct from parsing `text`, using a custom ParseConfig - pub fn parse_with_config(text: &'a str, config: &ParseConfig) -> Org<'a> { + /// Parses string `text` into `Org` struct with custom `ParseConfig`. + pub fn parse_custom(text: &'a str, config: &ParseConfig) -> Org<'a> { let mut arena = Arena::new(); - let (text, blank) = blank_lines(text); - let root = arena.new_node(Element::Document { pre_blank: blank }); + let (text, pre_blank) = blank_lines(text); + let root = arena.new_node(Element::Document { pre_blank }); let mut org = Org { arena, root }; parse_container( @@ -54,17 +54,23 @@ impl<'a> Org<'a> { org } - /// Return a refrence to underlay arena + /// Parses string `text` into `Org` struct with custom `ParseConfig`. + #[deprecated(since = "0.6.0", note = "rename to parse_custom")] + pub fn parse_with_config(text: &'a str, config: &ParseConfig) -> Org<'a> { + Org::parse_custom(text, config) + } + + /// Returns a refrence to the underlay arena. pub fn arena(&self) -> &Arena> { &self.arena } - /// Return a mutual reference to underlay arena + /// Returns a mutual reference to the underlay arena. pub fn arena_mut(&mut self) -> &mut Arena> { &mut self.arena } - /// Return an iterator of Event + /// Returns an iterator of `Event`s. pub fn iter<'b>(&'b self) -> impl Iterator> + 'b { self.root.traverse(&self.arena).map(move |edge| match edge { NodeEdge::Start(node) => Event::Start(&self[node]), @@ -72,14 +78,16 @@ impl<'a> Org<'a> { }) } - pub fn html(&self, writer: W) -> Result<(), Error> + /// Writes an `Org` struct as html format. + pub fn write_html(&self, writer: W) -> Result<(), Error> where W: Write, { - self.html_with_handler(writer, &mut DefaultHtmlHandler) + self.write_html_custom(writer, &mut DefaultHtmlHandler) } - pub fn html_with_handler(&self, mut writer: W, handler: &mut H) -> Result<(), E> + /// Writes an `Org` struct as html format with custom `HtmlHandler`. + pub fn write_html_custom(&self, mut writer: W, handler: &mut H) -> Result<(), E> where W: Write, E: From, @@ -95,14 +103,36 @@ impl<'a> Org<'a> { Ok(()) } - pub fn org(&self, writer: W) -> Result<(), Error> + /// Writes an `Org` struct as html format. + #[deprecated(since = "0.6.0", note = "rename to write_html")] + pub fn html(&self, writer: W) -> Result<(), Error> where W: Write, { - self.org_with_handler(writer, &mut DefaultOrgHandler) + self.write_html_custom(writer, &mut DefaultHtmlHandler) } - pub fn org_with_handler(&self, mut writer: W, handler: &mut H) -> Result<(), E> + /// Writes an `Org` struct as html format with custom `HtmlHandler`. + #[deprecated(since = "0.6.0", note = "rename to write_html_custom")] + pub fn html_with_handler(&self, writer: W, handler: &mut H) -> Result<(), E> + where + W: Write, + E: From, + H: HtmlHandler, + { + self.write_html_custom(writer, handler) + } + + /// Writes an `Org` struct as org format. + pub fn write_org(&self, writer: W) -> Result<(), Error> + where + W: Write, + { + self.write_org_custom(writer, &mut DefaultOrgHandler) + } + + /// Writes an `Org` struct as org format with custom `OrgHandler`. + pub fn write_org_custom(&self, mut writer: W, handler: &mut H) -> Result<(), E> where W: Write, E: From, @@ -117,6 +147,26 @@ impl<'a> Org<'a> { Ok(()) } + + /// Writes an `Org` struct as org format. + #[deprecated(since = "0.6.0", note = "rename to write_org")] + pub fn org(&self, writer: W) -> Result<(), Error> + where + W: Write, + { + self.write_org_custom(writer, &mut DefaultOrgHandler) + } + + /// Writes an `Org` struct as org format with custom `OrgHandler`. + #[deprecated(since = "0.6.0", note = "rename to write_org_custom")] + pub fn org_with_handler(&self, writer: W, handler: &mut H) -> Result<(), E> + where + W: Write, + E: From, + H: OrgHandler, + { + self.write_org_custom(writer, handler) + } } impl Default for Org<'static> { diff --git a/src/validate.rs b/src/validate.rs index 87ea501..1f41666 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -45,7 +45,7 @@ impl ValidationError { pub type ValidationResult = Result; impl Org<'_> { - /// Validate an `Org` struct. + /// Validates an `Org` struct. pub fn validate(&self) -> Vec { let mut errors = Vec::new(); @@ -176,7 +176,7 @@ impl Org<'_> { } #[deprecated(since = "0.3.1", note = "rename to validate")] - /// Validate an `Org` struct. + /// Validates an `Org` struct. pub fn check(&self) -> Vec { self.validate() } diff --git a/tests/blank.rs b/tests/blank.rs index 8e95686..b36f492 100644 --- a/tests/blank.rs +++ b/tests/blank.rs @@ -58,7 +58,7 @@ fn blank() { let org = Org::parse(ORG_STR); let mut writer = Vec::new(); - org.org(&mut writer).unwrap(); + org.write_org(&mut writer).unwrap(); // eprintln!("{}", serde_json::to_string_pretty(&org).unwrap()); diff --git a/tests/parse.rs b/tests/parse.rs index 30b4017..33a6de8 100644 --- a/tests/parse.rs +++ b/tests/parse.rs @@ -7,7 +7,7 @@ macro_rules! test_suite { fn $name() { let mut writer = Vec::new(); let org = Org::parse($content); - org.html(&mut writer).unwrap(); + org.write_html(&mut writer).unwrap(); let string = String::from_utf8(writer).unwrap(); assert_eq!(string, $expected); } @@ -29,14 +29,16 @@ test_suite!( test_suite!( section_and_headline, - r#"* title 1 + r#" +* title 1 section 1 ** title 2 section 2 * title 3 section 3 * title 4 -section 4"#, +section 4 +"#, "

title 1

section 1

\

title 2

section 2

\

title 3

section 3

\ @@ -45,7 +47,8 @@ section 4"#, test_suite!( list, - r#"+ 1 + r#" ++ 1 + 2 @@ -53,7 +56,8 @@ test_suite!( - 4 -+ 5"#, ++ 5 +"#, "
    \
  • 1

  • \
  • 2

    • 3

    • 4

  • \ @@ -69,7 +73,8 @@ test_suite!( test_suite!( paragraphs, - r#"* title + r#" +* title paragraph 1 @@ -77,7 +82,8 @@ paragraph 2 paragraph 3 -paragraph 4"#, +paragraph 4 +"#, "

    title

    \

    paragraph 1

    paragraph 2

    \

    paragraph 3

    paragraph 4

    \