diff --git a/parser/asciidoc-grammar.peg b/parser/asciidoc-grammar.peg index dee4663a..2f649604 100644 --- a/parser/asciidoc-grammar.peg +++ b/parser/asciidoc-grammar.peg @@ -124,8 +124,8 @@ Paragraph <- metadata:(MetadataElement)* lines:(InlineContent)+ { } // an inline content element may begin and end with spaces, -// but it must contain at least a quoted text, an external link or a word -InlineContent <- elements:(WS* (QuotedText / ExternalLink / Word) WS*)+ EOL { +// but it must contain at least an image, a quoted text, an external link or a word +InlineContent <- elements:(WS* (InlineImage / QuotedText / ExternalLink / Word) WS*)+ EOL { return types.NewInlineContent(c.text, elements.([]interface{})) } @@ -168,15 +168,20 @@ ExternalLink <- url:(URL_SCHEME URL) text:('[' (URL_TEXT)* ']')? { // ------------------------------------------ BlockImage <- metadata:(MetadataElement)* image:BlockImageMacro WS* EOL { // here we can ignore the blank line in the returned element - return types.NewBlockImage(c.text, *image.(*types.BlockImageMacro), metadata.([]interface{})) + return types.NewBlockImage(c.text, *image.(*types.ImageMacro), metadata.([]interface{})) } BlockImageMacro <- "image::" path:(URL) '[' attributes:(URL_TEXT?) ']' { - if attributes != nil { - attrs := attributes.(string) - return types.NewBlockImageMacro(c.text, path.(string), &attrs) - } - return types.NewBlockImageMacro(c.text, path.(string), nil) + return types.NewImageMacro(c.text, path.(string), attributes) +} + +InlineImage <- image:InlineImageMacro { + // here we can ignore the blank line in the returned element + return types.NewInlineImage(c.text, *image.(*types.ImageMacro)) +} + +InlineImageMacro <- "image:" !":" path:(URL) '[' attributes:(URL_TEXT?) ']' { + return types.NewImageMacro(c.text, path.(string), attributes) } // ------------------------------------------ diff --git a/parser/asciidoc_parser_test.go b/parser/asciidoc_parser_test.go index 2968c558..554b2667 100644 --- a/parser/asciidoc_parser_test.go +++ b/parser/asciidoc_parser_test.go @@ -74,7 +74,7 @@ var _ = Describe("Parsing content", func() { }) func verify(t GinkgoTInterface, expectedDocument *types.Document, content string) { - log.Debugf("processing:\n%s", content) + log.Debugf("processing: %s", content) reader := strings.NewReader(content) result, err := ParseReader("", reader) if err != nil { @@ -83,7 +83,7 @@ func verify(t GinkgoTInterface, expectedDocument *types.Document, content string require.Nil(t, err) actualDocument := result.(*types.Document) t.Logf("actual document structure: %+v", actualDocument.Elements) - t.Logf("actual document: %s", actualDocument.String(0)) - t.Logf("expected document: %s", expectedDocument.String(0)) + t.Logf("actual document: `%s`", actualDocument.String(0)) + t.Logf("expected document: `%s`", expectedDocument.String(0)) assert.EqualValues(t, *expectedDocument, *actualDocument) } diff --git a/parser/blank_line_test.go b/parser/blank_line_test.go index f54de200..83b297a3 100644 --- a/parser/blank_line_test.go +++ b/parser/blank_line_test.go @@ -5,7 +5,7 @@ import ( . "github.com/onsi/ginkgo" ) -var _ = Describe("Rendering Blank lines", func() { +var _ = Describe("Blank lines", func() { It("blank line between 2 paragraphs", func() { actualDocument := `first paragraph diff --git a/parser/block_image_test.go b/parser/block_image_test.go deleted file mode 100644 index eea2edbf..00000000 --- a/parser/block_image_test.go +++ /dev/null @@ -1,159 +0,0 @@ -package parser_test - -import ( - "github.com/bytesparadise/libasciidoc/types" - . "github.com/onsi/ginkgo" -) - -var _ = Describe("Parsing Block Images", func() { - Context("Correct behaviour", func() { - - It("block image with empty alt", func() { - actualContent := "image::images/foo.png[]" - expectedDocument := &types.Document{ - Elements: []types.DocElement{ - &types.BlockImage{ - Macro: types.BlockImageMacro{ - Path: "images/foo.png", - Alt: "foo", - }, - }, - }, - } - verify(GinkgoT(), expectedDocument, actualContent) - }) - - It("block image with empty alt and trailing spaces", func() { - actualContent := "image::images/foo.png[] \t\t " - expectedDocument := &types.Document{ - Elements: []types.DocElement{ - &types.BlockImage{ - Macro: types.BlockImageMacro{ - Path: "images/foo.png", - Alt: "foo", - }, - }, - }, - } - verify(GinkgoT(), expectedDocument, actualContent) - }) - - It("block image with line return", func() { - // line return here is not considered as a blank line - actualContent := `image::images/foo.png[] -` - expectedDocument := &types.Document{ - Elements: []types.DocElement{ - &types.BlockImage{ - Macro: types.BlockImageMacro{ - Path: "images/foo.png", - Alt: "foo", - }, - }, - }, - } - verify(GinkgoT(), expectedDocument, actualContent) - }) - - It("block image with 1 empty blank line", func() { - // here, there's a real blank line with some spaces - actualContent := `image::images/foo.png[] - ` - expectedDocument := &types.Document{ - Elements: []types.DocElement{ - &types.BlockImage{ - Macro: types.BlockImageMacro{ - Path: "images/foo.png", - Alt: "foo", - }, - }, - // &types.BlankLine{}, - }, - } - verify(GinkgoT(), expectedDocument, actualContent) - }) - - It("block image with 2 blank lines with spaces and tabs", func() { - actualContent := `image::images/foo.png[] - - ` - expectedDocument := &types.Document{ - Elements: []types.DocElement{ - &types.BlockImage{ - Macro: types.BlockImageMacro{ - Path: "images/foo.png", - Alt: "foo", - }, - }, - // &types.BlankLine{}, - // &types.BlankLine{}, - }, - } - verify(GinkgoT(), expectedDocument, actualContent) - }) - - It("block image with alt", func() { - actualContent := "image::images/foo.png[the foo.png image]" - expectedDocument := &types.Document{ - Elements: []types.DocElement{ - &types.BlockImage{ - Macro: types.BlockImageMacro{ - Path: "images/foo.png", - Alt: "the foo.png image", - }, - }, - }, - } - verify(GinkgoT(), expectedDocument, actualContent) - }) - - It("block image with dimensions and i d link title meta", func() { - actualContent := "[#img-foobar]\n" + - ".A title to foobar\n" + - "[link=http://foo.bar]\n" + - "image::images/foo.png[the foo.png image, 600, 400]" - width := "600" - height := "400" - expectedDocument := &types.Document{ - Elements: []types.DocElement{ - &types.BlockImage{ - Macro: types.BlockImageMacro{ - Path: "images/foo.png", - Alt: "the foo.png image", - Width: &width, - Height: &height, - }, - ID: &types.ElementID{Value: "img-foobar"}, - Title: &types.ElementTitle{Value: "A title to foobar"}, - Link: &types.ElementLink{Path: "http://foo.bar"}, - }, - }, - } - verify(GinkgoT(), expectedDocument, actualContent) - }) - }) - Context("Errors", func() { - It("block image appending inline content", func() { - actualContent := "a paragraph\nimage::images/foo.png[]" - expectedDocument := &types.Document{ - Elements: []types.DocElement{ - &types.Paragraph{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "a paragraph"}, - }, - }, - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "image::images/foo.png[]"}, - }, - }, - }, - }, - }, - } - verify(GinkgoT(), expectedDocument, actualContent) - }) - }) -}) diff --git a/parser/delimited_block_test.go b/parser/delimited_block_test.go index 564e48ba..c05e904c 100644 --- a/parser/delimited_block_test.go +++ b/parser/delimited_block_test.go @@ -5,7 +5,7 @@ import ( . "github.com/onsi/ginkgo" ) -var _ = Describe("Parsing Delimited Blocks", func() { +var _ = Describe("Delimited Blocks", func() { It("delimited source block with single line", func() { content := "some source code" diff --git a/parser/external_link_test.go b/parser/external_link_test.go index 582ee83b..7aea9754 100644 --- a/parser/external_link_test.go +++ b/parser/external_link_test.go @@ -5,7 +5,7 @@ import ( . "github.com/onsi/ginkgo" ) -var _ = Describe("Parsing External Links", func() { +var _ = Describe("External Links", func() { It("external link", func() { actualContent := "a link to https://foo.bar" diff --git a/parser/image_test.go b/parser/image_test.go new file mode 100644 index 00000000..f38f3a84 --- /dev/null +++ b/parser/image_test.go @@ -0,0 +1,291 @@ +package parser_test + +import ( + "github.com/bytesparadise/libasciidoc/types" + . "github.com/onsi/ginkgo" +) + +var _ = Describe("Images", func() { + Context("Block Images", func() { + Context("Correct behaviour", func() { + + It("block image with empty alt", func() { + actualContent := "image::images/foo.png[]" + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.BlockImage{ + Macro: types.ImageMacro{ + Path: "images/foo.png", + Alt: "foo", + }, + }, + }, + } + verify(GinkgoT(), expectedDocument, actualContent) + }) + + It("block image with empty alt and trailing spaces", func() { + actualContent := "image::images/foo.png[] \t\t " + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.BlockImage{ + Macro: types.ImageMacro{ + Path: "images/foo.png", + Alt: "foo", + }, + }, + }, + } + verify(GinkgoT(), expectedDocument, actualContent) + }) + + It("block image with line return", func() { + // line return here is not considered as a blank line + actualContent := `image::images/foo.png[] +` + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.BlockImage{ + Macro: types.ImageMacro{ + Path: "images/foo.png", + Alt: "foo", + }, + }, + }, + } + verify(GinkgoT(), expectedDocument, actualContent) + }) + + It("block image with 1 empty blank line", func() { + // here, there's a real blank line with some spaces + actualContent := `image::images/foo.png[] + ` + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.BlockImage{ + Macro: types.ImageMacro{ + Path: "images/foo.png", + Alt: "foo", + }, + }, + // &types.BlankLine{}, + }, + } + verify(GinkgoT(), expectedDocument, actualContent) + }) + + It("block image with 2 blank lines with spaces and tabs", func() { + actualContent := `image::images/foo.png[] + + ` + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.BlockImage{ + Macro: types.ImageMacro{ + Path: "images/foo.png", + Alt: "foo", + }, + }, + // &types.BlankLine{}, + // &types.BlankLine{}, + }, + } + verify(GinkgoT(), expectedDocument, actualContent) + }) + + It("block image with alt", func() { + actualContent := "image::images/foo.png[the foo.png image]" + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.BlockImage{ + Macro: types.ImageMacro{ + Path: "images/foo.png", + Alt: "the foo.png image", + }, + }, + }, + } + verify(GinkgoT(), expectedDocument, actualContent) + }) + + It("block image with dimensions and i d link title meta", func() { + actualContent := "[#img-foobar]\n" + + ".A title to foobar\n" + + "[link=http://foo.bar]\n" + + "image::images/foo.png[the foo.png image, 600, 400]" + width := "600" + height := "400" + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.BlockImage{ + Macro: types.ImageMacro{ + Path: "images/foo.png", + Alt: "the foo.png image", + Width: &width, + Height: &height, + }, + ID: &types.ElementID{Value: "img-foobar"}, + Title: &types.ElementTitle{Value: "A title to foobar"}, + Link: &types.ElementLink{Path: "http://foo.bar"}, + }, + }, + } + verify(GinkgoT(), expectedDocument, actualContent) + }) + }) + Context("Errors", func() { + It("block image appending inline content", func() { + actualContent := "a paragraph\nimage::images/foo.png[]" + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.Paragraph{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "a paragraph"}, + }, + }, + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "image::images/foo.png[]"}, + }, + }, + }, + }, + }, + } + verify(GinkgoT(), expectedDocument, actualContent) + }) + }) + }) + + Context("Inline Images", func() { + Context("Correct behaviour", func() { + + It("inline image with empty alt", func() { + actualContent := "image:images/foo.png[]" + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.Paragraph{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.InlineImage{ + Macro: types.ImageMacro{ + Path: "images/foo.png", + Alt: "foo", + }, + }, + }, + }, + }, + }, + }, + } + verify(GinkgoT(), expectedDocument, actualContent) + }) + + It("inline image with empty alt and trailing spaces", func() { + actualContent := "image:images/foo.png[] \t\t " + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.Paragraph{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.InlineImage{ + Macro: types.ImageMacro{ + Path: "images/foo.png", + Alt: "foo", + }, + }, + &types.StringElement{ + Content: " \t\t ", + }, + }, + }, + }, + }, + }, + } + verify(GinkgoT(), expectedDocument, actualContent) + }) + + It("inline image surrounded with test", func() { + actualContent := "a foo image:images/foo.png[] bar..." + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.Paragraph{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{ + Content: "a foo ", + }, + &types.InlineImage{ + Macro: types.ImageMacro{ + Path: "images/foo.png", + Alt: "foo", + }, + }, + &types.StringElement{ + Content: " bar...", + }, + }, + }, + }, + }, + }, + } + verify(GinkgoT(), expectedDocument, actualContent) + }) + + It("inline image with alt", func() { + actualContent := "image:images/foo.png[the foo.png image]" + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.Paragraph{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.InlineImage{ + Macro: types.ImageMacro{ + Path: "images/foo.png", + Alt: "the foo.png image", + }, + }, + }, + }, + }, + }, + }, + } + verify(GinkgoT(), expectedDocument, actualContent) + }) + }) + Context("Errors", func() { + It("inline image appending inline content", func() { + actualContent := "a paragraph\nimage::images/foo.png[]" + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.Paragraph{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "a paragraph"}, + }, + }, + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "image::images/foo.png[]"}, + }, + }, + }, + }, + }, + } + verify(GinkgoT(), expectedDocument, actualContent) + }) + }) + }) +}) diff --git a/parser/list_test.go b/parser/list_test.go index f99ce011..7b5fc2f6 100644 --- a/parser/list_test.go +++ b/parser/list_test.go @@ -5,22 +5,24 @@ import ( . "github.com/onsi/ginkgo" ) -var _ = Describe("Parsing Unordered List Items", func() { +var _ = Describe("List Items", func() { - Context("Valid content", func() { - It("1 list with a single item", func() { - actualContent := "* a list item" - expectedDocument := &types.Document{ - Elements: []types.DocElement{ - &types.List{ - Items: []*types.ListItem{ - &types.ListItem{ - Level: 1, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "a list item"}, + Context("Unordered ", func() { + Context("Valid content", func() { + It("1 list with a single item", func() { + actualContent := "* a list item" + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.List{ + Items: []*types.ListItem{ + &types.ListItem{ + Level: 1, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "a list item"}, + }, }, }, }, @@ -28,25 +30,25 @@ var _ = Describe("Parsing Unordered List Items", func() { }, }, }, - }, - } - verify(GinkgoT(), expectedDocument, actualContent) - }) - It("1 list with an ID and a single item", func() { - actualContent := "[#listID]\n" + - "* a list item" - expectedDocument := &types.Document{ - Elements: []types.DocElement{ - &types.List{ - ID: &types.ElementID{Value: "listID"}, - Items: []*types.ListItem{ - &types.ListItem{ - Level: 1, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "a list item"}, + } + verify(GinkgoT(), expectedDocument, actualContent) + }) + It("1 list with an ID and a single item", func() { + actualContent := "[#listID]\n" + + "* a list item" + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.List{ + ID: &types.ElementID{Value: "listID"}, + Items: []*types.ListItem{ + &types.ListItem{ + Level: 1, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "a list item"}, + }, }, }, }, @@ -54,40 +56,40 @@ var _ = Describe("Parsing Unordered List Items", func() { }, }, }, - }, - } - verify(GinkgoT(), expectedDocument, actualContent) - }) + } + verify(GinkgoT(), expectedDocument, actualContent) + }) - It("1 list with 2 items with stars", func() { - actualContent := "* a first item\n" + - "* a second item with *bold content*" - expectedDocument := &types.Document{ - Elements: []types.DocElement{ - &types.List{ - Items: []*types.ListItem{ - &types.ListItem{ - Level: 1, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "a first item"}, + It("1 list with 2 items with stars", func() { + actualContent := "* a first item\n" + + "* a second item with *bold content*" + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.List{ + Items: []*types.ListItem{ + &types.ListItem{ + Level: 1, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "a first item"}, + }, }, }, }, }, - }, - &types.ListItem{ - Level: 1, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "a second item with "}, - &types.QuotedText{Kind: types.Bold, - Elements: []types.DocElement{ - &types.StringElement{Content: "bold content"}, + &types.ListItem{ + Level: 1, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "a second item with "}, + &types.QuotedText{Kind: types.Bold, + Elements: []types.DocElement{ + &types.StringElement{Content: "bold content"}, + }, }, }, }, @@ -97,39 +99,39 @@ var _ = Describe("Parsing Unordered List Items", func() { }, }, }, - }, - } - verify(GinkgoT(), expectedDocument, actualContent) - }) - It("1 list with 2 items with carets", func() { - actualContent := "- a first item\n" + - "- a second item with *bold content*" - expectedDocument := &types.Document{ - Elements: []types.DocElement{ - &types.List{ - Items: []*types.ListItem{ - &types.ListItem{ - Level: 1, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "a first item"}, + } + verify(GinkgoT(), expectedDocument, actualContent) + }) + It("1 list with 2 items with carets", func() { + actualContent := "- a first item\n" + + "- a second item with *bold content*" + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.List{ + Items: []*types.ListItem{ + &types.ListItem{ + Level: 1, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "a first item"}, + }, }, }, }, }, - }, - &types.ListItem{ - Level: 1, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "a second item with "}, - &types.QuotedText{Kind: types.Bold, - Elements: []types.DocElement{ - &types.StringElement{Content: "bold content"}, + &types.ListItem{ + Level: 1, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "a second item with "}, + &types.QuotedText{Kind: types.Bold, + Elements: []types.DocElement{ + &types.StringElement{Content: "bold content"}, + }, }, }, }, @@ -139,41 +141,41 @@ var _ = Describe("Parsing Unordered List Items", func() { }, }, }, - }, - } - verify(GinkgoT(), expectedDocument, actualContent) - }) - It("1 list with 2 items with empty line in-between", func() { - // fist line after list item is swallowed - actualContent := "* a first item\n" + - "\n" + - "* a second item with *bold content*" - expectedDocument := &types.Document{ - Elements: []types.DocElement{ - &types.List{ - Items: []*types.ListItem{ - &types.ListItem{ - Level: 1, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "a first item"}, + } + verify(GinkgoT(), expectedDocument, actualContent) + }) + It("1 list with 2 items with empty line in-between", func() { + // fist line after list item is swallowed + actualContent := "* a first item\n" + + "\n" + + "* a second item with *bold content*" + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.List{ + Items: []*types.ListItem{ + &types.ListItem{ + Level: 1, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "a first item"}, + }, }, }, }, }, - }, - &types.ListItem{ - Level: 1, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "a second item with "}, - &types.QuotedText{Kind: types.Bold, - Elements: []types.DocElement{ - &types.StringElement{Content: "bold content"}, + &types.ListItem{ + Level: 1, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "a second item with "}, + &types.QuotedText{Kind: types.Bold, + Elements: []types.DocElement{ + &types.StringElement{Content: "bold content"}, + }, }, }, }, @@ -183,48 +185,48 @@ var _ = Describe("Parsing Unordered List Items", func() { }, }, }, - }, - } - verify(GinkgoT(), expectedDocument, actualContent) - }) - It("1 list with 2 items on multiple lines", func() { - actualContent := "* item 1\n" + - " on 2 lines.\n" + - "* item 2\n" + - "on 2 lines, too." - expectedDocument := &types.Document{ - Elements: []types.DocElement{ - &types.List{ - Items: []*types.ListItem{ - &types.ListItem{ - Level: 1, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "item 1"}, + } + verify(GinkgoT(), expectedDocument, actualContent) + }) + It("1 list with 2 items on multiple lines", func() { + actualContent := "* item 1\n" + + " on 2 lines.\n" + + "* item 2\n" + + "on 2 lines, too." + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.List{ + Items: []*types.ListItem{ + &types.ListItem{ + Level: 1, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "item 1"}, + }, }, - }, - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: " on 2 lines."}, + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: " on 2 lines."}, + }, }, }, }, }, - }, - &types.ListItem{ - Level: 1, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "item 2"}, + &types.ListItem{ + Level: 1, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "item 2"}, + }, }, - }, - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "on 2 lines, too."}, + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "on 2 lines, too."}, + }, }, }, }, @@ -232,44 +234,44 @@ var _ = Describe("Parsing Unordered List Items", func() { }, }, }, - }, - } - verify(GinkgoT(), expectedDocument, actualContent) - }) - It("2 lists with 2 empty lines in-between", func() { - // the first blank lines after the first list is swallowed (for the list item) - actualContent := "* an item in the first list\n" + - "\n" + - "\n" + - "* an item in the second list" - expectedDocument := &types.Document{ - Elements: []types.DocElement{ - &types.List{ - Items: []*types.ListItem{ - &types.ListItem{ - Level: 1, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "an item in the first list"}, + } + verify(GinkgoT(), expectedDocument, actualContent) + }) + It("2 lists with 2 empty lines in-between", func() { + // the first blank lines after the first list is swallowed (for the list item) + actualContent := "* an item in the first list\n" + + "\n" + + "\n" + + "* an item in the second list" + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.List{ + Items: []*types.ListItem{ + &types.ListItem{ + Level: 1, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "an item in the first list"}, + }, }, }, }, }, }, }, - }, - // &types.BlankLine{}, - &types.List{ - Items: []*types.ListItem{ - &types.ListItem{ - Level: 1, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "an item in the second list"}, + // &types.BlankLine{}, + &types.List{ + Items: []*types.ListItem{ + &types.ListItem{ + Level: 1, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "an item in the second list"}, + }, }, }, }, @@ -277,73 +279,73 @@ var _ = Describe("Parsing Unordered List Items", func() { }, }, }, - }, - } - verify(GinkgoT(), expectedDocument, actualContent) - }) + } + verify(GinkgoT(), expectedDocument, actualContent) + }) - }) + }) - Context("List of multiple levels", func() { - It("a list with items on 3 levels", func() { - actualContent := "* item 1\n" + - "** item 1.1\n" + - "** item 1.2\n" + - "*** item 1.2.1\n" + - "** item 1.3\n" + - "** item 1.4\n" + - "* item 2\n" + - "** item 2.1\n" - expectedDocument := &types.Document{ - Elements: []types.DocElement{ - &types.List{ - Items: []*types.ListItem{ - &types.ListItem{ - Level: 1, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "item 1"}, + Context("List of multiple levels", func() { + It("a list with items on 3 levels", func() { + actualContent := "* item 1\n" + + "** item 1.1\n" + + "** item 1.2\n" + + "*** item 1.2.1\n" + + "** item 1.3\n" + + "** item 1.4\n" + + "* item 2\n" + + "** item 2.1\n" + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.List{ + Items: []*types.ListItem{ + &types.ListItem{ + Level: 1, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "item 1"}, + }, }, }, }, - }, - Children: &types.List{ - Items: []*types.ListItem{ - &types.ListItem{ - Level: 2, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ + Children: &types.List{ + Items: []*types.ListItem{ + &types.ListItem{ + Level: 2, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "item 1.1"}, + Elements: []types.DocElement{ + &types.StringElement{Content: "item 1.1"}, + }, }, }, }, }, - }, - &types.ListItem{ - Level: 2, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "item 1.2"}, + &types.ListItem{ + Level: 2, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "item 1.2"}, + }, }, }, }, - }, - Children: &types.List{ - Items: []*types.ListItem{ - &types.ListItem{ - Level: 3, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "item 1.2.1"}, + Children: &types.List{ + Items: []*types.ListItem{ + &types.ListItem{ + Level: 3, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "item 1.2.1"}, + }, }, }, }, @@ -351,26 +353,26 @@ var _ = Describe("Parsing Unordered List Items", func() { }, }, }, - }, - &types.ListItem{ - Level: 2, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "item 1.3"}, + &types.ListItem{ + Level: 2, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "item 1.3"}, + }, }, }, }, }, - }, - &types.ListItem{ - Level: 2, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "item 1.4"}, + &types.ListItem{ + Level: 2, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "item 1.4"}, + }, }, }, }, @@ -378,27 +380,27 @@ var _ = Describe("Parsing Unordered List Items", func() { }, }, }, - }, - &types.ListItem{ - Level: 1, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "item 2"}, + &types.ListItem{ + Level: 1, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "item 2"}, + }, }, }, }, - }, - Children: &types.List{ - Items: []*types.ListItem{ - &types.ListItem{ - Level: 2, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "item 2.1"}, + Children: &types.List{ + Items: []*types.ListItem{ + &types.ListItem{ + Level: 2, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "item 2.1"}, + }, }, }, }, @@ -409,57 +411,57 @@ var _ = Describe("Parsing Unordered List Items", func() { }, }, }, - }, - } - verify(GinkgoT(), expectedDocument, actualContent) - }) + } + verify(GinkgoT(), expectedDocument, actualContent) + }) - }) + }) - Context("Invalid content", func() { - It("a list with items on 2 levels - bad numbering", func() { - actualContent := "* item 1\n" + - "*** item 1.1\n" + - "*** item 1.1.1\n" + - "** item 1.2\n" + - "* item 2" - expectedDocument := &types.Document{ - Elements: []types.DocElement{ - &types.List{ - Items: []*types.ListItem{ - &types.ListItem{ - Level: 1, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "item 1"}, + Context("Invalid content", func() { + It("a list with items on 2 levels - bad numbering", func() { + actualContent := "* item 1\n" + + "*** item 1.1\n" + + "*** item 1.1.1\n" + + "** item 1.2\n" + + "* item 2" + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.List{ + Items: []*types.ListItem{ + &types.ListItem{ + Level: 1, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "item 1"}, + }, }, }, }, - }, - Children: &types.List{ - Items: []*types.ListItem{ - &types.ListItem{ - Level: 2, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "item 1.1"}, + Children: &types.List{ + Items: []*types.ListItem{ + &types.ListItem{ + Level: 2, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "item 1.1"}, + }, }, }, }, - }, - Children: &types.List{ - Items: []*types.ListItem{ - &types.ListItem{ - Level: 3, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "item 1.1.1"}, + Children: &types.List{ + Items: []*types.ListItem{ + &types.ListItem{ + Level: 3, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "item 1.1.1"}, + }, }, }, }, @@ -467,14 +469,14 @@ var _ = Describe("Parsing Unordered List Items", func() { }, }, }, - }, - &types.ListItem{ - Level: 2, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "item 1.2"}, + &types.ListItem{ + Level: 2, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "item 1.2"}, + }, }, }, }, @@ -482,14 +484,14 @@ var _ = Describe("Parsing Unordered List Items", func() { }, }, }, - }, - &types.ListItem{ - Level: 1, - Content: &types.ListItemContent{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "item 2"}, + &types.ListItem{ + Level: 1, + Content: &types.ListItemContent{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "item 2"}, + }, }, }, }, @@ -497,28 +499,27 @@ var _ = Describe("Parsing Unordered List Items", func() { }, }, }, - }, - } - verify(GinkgoT(), expectedDocument, actualContent) - }) + } + verify(GinkgoT(), expectedDocument, actualContent) + }) - It("invalid list item", func() { - actualContent := "*an invalid list item" - expectedDocument := &types.Document{ - Elements: []types.DocElement{ - &types.Paragraph{ - Lines: []*types.InlineContent{ - &types.InlineContent{ - Elements: []types.DocElement{ - &types.StringElement{Content: "*an invalid list item"}, + It("invalid list item", func() { + actualContent := "*an invalid list item" + expectedDocument := &types.Document{ + Elements: []types.DocElement{ + &types.Paragraph{ + Lines: []*types.InlineContent{ + &types.InlineContent{ + Elements: []types.DocElement{ + &types.StringElement{Content: "*an invalid list item"}, + }, }, }, }, }, - }, - } - verify(GinkgoT(), expectedDocument, actualContent) + } + verify(GinkgoT(), expectedDocument, actualContent) + }) }) }) - }) diff --git a/parser/meta_elements_test.go b/parser/meta_elements_test.go index 93995992..3e6dc21a 100644 --- a/parser/meta_elements_test.go +++ b/parser/meta_elements_test.go @@ -5,11 +5,11 @@ import ( . "github.com/onsi/ginkgo" ) -var _ = Describe("Parsing Meta Elements", func() { +var _ = Describe("Meta Elements", func() { - Context("element link", func() { + Context("Element link", func() { - It("element link", func() { + It("element link alone", func() { actualContent := "[link=http://foo.bar]" expectedDocument := &types.Document{ Elements: []types.DocElement{ diff --git a/parser/paragraph_test.go b/parser/paragraph_test.go index 3a03c9f3..614a6d97 100644 --- a/parser/paragraph_test.go +++ b/parser/paragraph_test.go @@ -5,7 +5,7 @@ import ( . "github.com/onsi/ginkgo" ) -var _ = Describe("Parsing Paragraphs", func() { +var _ = Describe("Paragraphs", func() { It("paragraph with 1 word", func() { actualContent := "hello" diff --git a/parser/quoted_text_test.go b/parser/quoted_text_test.go index 4b89dfb4..69f44969 100644 --- a/parser/quoted_text_test.go +++ b/parser/quoted_text_test.go @@ -5,7 +5,7 @@ import ( . "github.com/onsi/ginkgo" ) -var _ = Describe("Parsing Quoted Texts", func() { +var _ = Describe("Quoted Texts", func() { It("bold text of 1 word", func() { actualContent := "*hello*" diff --git a/parser/section_test.go b/parser/section_test.go index aebc0b8e..59f697f6 100644 --- a/parser/section_test.go +++ b/parser/section_test.go @@ -5,7 +5,7 @@ import ( . "github.com/onsi/ginkgo" ) -var _ = Describe("Parsing Sections", func() { +var _ = Describe("Sections", func() { Context("Valid document", func() { diff --git a/renderer/html5/image.go b/renderer/html5/image.go index addf3eb0..274bac0e 100644 --- a/renderer/html5/image.go +++ b/renderer/html5/image.go @@ -11,6 +11,7 @@ import ( ) var blockImageTmpl *template.Template +var inlineImageTmpl *template.Template // initializes the templates func init() { @@ -21,6 +22,7 @@ func init() {
+
+
+
a foo bar
+a foo image::foo.png[foo image, 600, 400] bar
+