From 89fec4cca4364b36212d1e15e39ead4779c1b105 Mon Sep 17 00:00:00 2001 From: linerlock Date: Sun, 12 Jul 2015 10:37:05 +0900 Subject: [PATCH 1/2] Change specs to match the issue #44 --- .../knockoff/ChunkParsersSpec.scala | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/test/scala/com/tristanhunt/knockoff/ChunkParsersSpec.scala b/src/test/scala/com/tristanhunt/knockoff/ChunkParsersSpec.scala index 2518831..fe86a9d 100644 --- a/src/test/scala/com/tristanhunt/knockoff/ChunkParsersSpec.scala +++ b/src/test/scala/com/tristanhunt/knockoff/ChunkParsersSpec.scala @@ -12,31 +12,31 @@ class ChunkParsersSpec extends ChunkParser with FunSpecLike with ShouldMatchers describe("ChunkParser") { it("should handle simple bullet items") { val src = "* item 1\n* item 2\n" - parse( chunk, src ).get should equal ( BulletLineChunk("item 1\n") ) + parse( chunk, src ).get should equal ( BulletLineChunk("item 1") ) } - + it("should group a second line that's not a bullet") { val src = "* item 1\n more\n" parse( chunk, src ).get should equal ( - BulletLineChunk("item 1\nmore\n") + BulletLineChunk("item 1\nmore") ) } - + it("should ignore whitespace around headers") { val src = "# Header 1 #" parse( chunk, src ).get should equal { HeaderChunk(1, "Header 1") } } - + it("should be ok with empty code blocks") { val src = " " parse( chunk, src ).get should equal { IndentedChunk("") } } - + it("should not explode on a code block with a trailing line") { val line = " line\n " - parse( chunk, line ).get should equal { IndentedChunk("line\n") } + parse( chunk, line ).get should equal { IndentedChunk("line") } } - + it("should handle nothin' but code") { val src = " This is just a code block.\n" + " \n" + @@ -45,15 +45,15 @@ class ChunkParsersSpec extends ChunkParser with FunSpecLike with ShouldMatchers parse( chunk, src ).get should equal { IndentedChunk( "This is just a code block.\n" + "\n" + - "And it has a trailing whitespace line... that's also indented.\n" + "And it has a trailing whitespace line... that's also indented." ) } } - + it("should deal with a CRLF") { val src = "This is a line \r\nthat is broken in\r\n a couple places.\r\n" - parse( chunk, src ).get should equal { TextChunk(src) } + parse( chunk, src ).get should equal { TextChunk(src.stripSuffix("\r\n")) } } - + it("should deal with just a CRLF") { val src = "\u000d\u000a" parse( chunk, src ).get should equal { EmptySpace(src) } From 27bfedba54595c2a0bc864fb0cbc7368e6f8da8f Mon Sep 17 00:00:00 2001 From: linerlock Date: Sun, 12 Jul 2015 13:38:59 +0900 Subject: [PATCH 2/2] Remove an unnecessary trailing line break before end tag (issue #44) --- .../knockoff/MarkdownParsing.scala | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/scala/com/tristanhunt/knockoff/MarkdownParsing.scala b/src/main/scala/com/tristanhunt/knockoff/MarkdownParsing.scala index f5cd3da..8f1f9e8 100644 --- a/src/main/scala/com/tristanhunt/knockoff/MarkdownParsing.scala +++ b/src/main/scala/com/tristanhunt/knockoff/MarkdownParsing.scala @@ -94,6 +94,15 @@ class ChunkParser extends RegexParsers with StringExtras { horizontalRule | leadingStrongTextBlock | leadingEmTextBlock | bulletItem | numberedItem | indentedChunk | header | blockquote | linkDefinition | htmlBlock | textBlockWithBreak | textBlock | emptyLines | emptySpace + } ^^ { + // Remove an unnecessary trailing line break from Chunk. + case BlockquotedChunk(content) => BlockquotedChunk(dropTrailingBreak(content)) + case HeaderChunk(level, content) => HeaderChunk(level, dropTrailingBreak(content)) + case IndentedChunk(content) => IndentedChunk(dropTrailingBreak(content)) + case NumberedLineChunk(content) => NumberedLineChunk(dropTrailingBreak(content)) + case TextChunk(content) => TextChunk(dropTrailingBreak(content)) + case BulletLineChunk(content) => BulletLineChunk(dropTrailingBreak(content)) + case chunk => chunk } def emptyLines: Parser[Chunk] = @@ -311,6 +320,14 @@ class ChunkParser extends RegexParsers with StringExtras { /** Take a series of very similar chunks and group them. */ private def foldedString(texts: List[Chunk]): String = ("" /: texts)((current, text) => current + text.content) + + private def dropTrailingBreak(content : String) : String = + content match { + case s if s.endsWith("\r\n") => s.stripSuffix("\r\n") + case s if s.endsWith("\r") => s.stripSuffix("\r") + case s if s.endsWith("\n") => s.stripSuffix("\n") + case s => s + } } /* @@ -415,7 +432,7 @@ case class HeaderChunk(val level: Int, val content: String) extends Chunk { } case object HorizontalRuleChunk extends Chunk { - val content = "* * *\n" + val content = "* * *" def appendNewBlock(list: ListBuffer[Block], remaining: List[(Chunk, Seq[Span], Position)],