Skip to content

Commit

Permalink
fix(renderer): do not include section 0 element (#432)
Browse files Browse the repository at this point in the history
unless there's a relevant element before. Otherwise,
just retain the section elements

fixes #425

Signed-off-by: Xavier Coulon <[email protected]>
  • Loading branch information
xcoulon authored Oct 27, 2019
1 parent a8f8ac7 commit bfff288
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 8 deletions.
75 changes: 75 additions & 0 deletions pkg/parser/file_inclusion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,81 @@ var _ = Describe("file inclusions - preflight with preprocessing", func() {
Expect(console).ToNot(ContainAnyMessageWithLevels(log.ErrorLevel, log.WarnLevel))
})

It("should include section 0 by default", func() {
source := "include::../../test/includes/chapter-a.adoc[]"
// at this level (parsing), it is expected that the Section 0 is part of the Prefligh document
expected := types.PreflightDocument{
Blocks: []interface{}{
types.Section{
Attributes: types.ElementAttributes{
types.AttrID: "chapter_a",
types.AttrCustomID: false,
},
Level: 0,
Title: types.InlineElements{
types.StringElement{
Content: "Chapter A",
},
},
Elements: []interface{}{},
},
types.BlankLine{},
types.Paragraph{
Attributes: types.ElementAttributes{},
Lines: []types.InlineElements{
{
types.StringElement{
Content: "content",
},
},
},
},
},
}
Expect(source).To(BecomePreflightDocument(expected))
})

It("should not include section 0 when attribute exists", func() {
source := `:includedir: ../../test/includes
include::{includedir}/chapter-a.adoc[]`
// at this level (parsing), it is expected that the Section 0 is part of the Prefligh document
expected := types.PreflightDocument{
Blocks: []interface{}{
types.DocumentAttributeDeclaration{
Name: "includedir",
Value: "../../test/includes",
},
types.BlankLine{},
types.Section{
Attributes: types.ElementAttributes{
types.AttrID: "chapter_a",
types.AttrCustomID: false,
},
Level: 0,
Title: types.InlineElements{
types.StringElement{
Content: "Chapter A",
},
},
Elements: []interface{}{},
},
types.BlankLine{},
types.Paragraph{
Attributes: types.ElementAttributes{},
Lines: []types.InlineElements{
{
types.StringElement{
Content: "content",
},
},
},
},
},
}
Expect(source).To(BecomePreflightDocument(expected))
})

Context("file inclusions in delimited blocks", func() {

It("should include adoc file within fenced block", func() {
Expand Down
56 changes: 49 additions & 7 deletions pkg/renderer/html5/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/bytesparadise/libasciidoc/pkg/renderer"
"github.com/bytesparadise/libasciidoc/pkg/types"
"github.com/davecgh/go-spew/spew"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)
Expand Down Expand Up @@ -115,17 +116,58 @@ func renderDocument(ctx *renderer.Context, output io.Writer) (map[string]interfa
// but not the HEAD and BODY containers
func renderDocumentElements(ctx *renderer.Context) ([]byte, error) {
elements := []interface{}{}
if len(ctx.Document.Elements) > 0 {
// retrieve elements of the first section 0 (if available), plus remaining elements
if s, ok := ctx.Document.Elements[0].(types.Section); ok && s.Level == 0 {
elements = append(elements, s.Elements)
if len(ctx.Document.Elements) > 1 {
elements = append(elements, ctx.Document.Elements[1:]...)
for i, e := range ctx.Document.Elements {
switch e := e.(type) {
case types.Preamble:
if !e.HasContent() {
// retain the preamble
elements = append(elements, e)
continue
}
} else {
// retain everything "as-is"
elements = ctx.Document.Elements
break
case types.Section:
if e.Level == 0 {
// retain the section's elements...
elements = append(elements, e.Elements)
// ... and add the other elements
elements = append(elements, ctx.Document.Elements[i+1:]...)
continue
}
// retain everything "as-is"
elements = ctx.Document.Elements
break
default:
// retain everything "as-is"
elements = ctx.Document.Elements
break
}
}
if log.IsLevelEnabled(log.DebugLevel) {
log.Debug("pre-rendered elements:")
spew.Dump(elements)
}
// // retrieve elements of the first section 0 (if available), plus remaining elements
// // any document attribute before the section level 0 can be ignored
// if s, ok := ctx.Document.Elements[0].(types.Section); ok && s.Level == 0 {
// elements = append(elements, s.Elements)
// if len(ctx.Document.Elements) > 1 {
// elements = append(elements, ctx.Document.Elements[1:]...)
// }
// } else if p, ok := ctx.Document.Elements[0].(types.Preamble); ok {
// if p.HasContent() {
// // check if preamble has anything else than document attribute declarations and blanklines
// log.Debug("preamble has content")
// elements = ctx.Document.Elements
// } else {
// elements = append(elements, ctx.Document.Elements[1:]...)
// }
// } else {
// elements = ctx.Document.Elements
// }
// }

// log.Debugf("rendered document with %d element(s)...", len(elements))
buff := bytes.NewBuffer(nil)
renderedElements, err := renderElements(ctx, elements)
Expand Down
18 changes: 18 additions & 0 deletions pkg/renderer/html5/file_inclusion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,24 @@ include::../../../test/includes/chapter-a.adoc[leveloffset=+1]`
Expect(source).To(RenderHTML5Body(expected))
})

It("should not include section 0 by default", func() {
source := `include::../../../test/includes/chapter-a.adoc[]`
expected := `<div class="paragraph">
<p>content</p>
</div>`
Expect(source).To(RenderHTML5Body(expected))
})

It("should not include section 0 when attribute exists", func() {
source := `:includedir: ../../../test/includes
include::{includedir}/chapter-a.adoc[]`
expected := `<div class="paragraph">
<p>content</p>
</div>`
Expect(source).To(RenderHTML5Body(expected))
})

It("include non adoc file", func() {
source := `= Master Document
Expand Down
14 changes: 14 additions & 0 deletions pkg/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,20 @@ type Preamble struct {
Elements []interface{}
}

// HasContent returns `true` if this Preamble has at least one element which is neither a
// BlankLine nor a DocumentAttributeDeclaration
func (p Preamble) HasContent() bool {
for _, pe := range p.Elements {
switch pe.(type) {
case DocumentAttributeDeclaration, BlankLine:
continue
default:
return true
}
}
return false
}

// ------------------------------------------
// Front Matter
// ------------------------------------------
Expand Down
4 changes: 3 additions & 1 deletion testsupport/console_matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ type tee struct {
}

func (t tee) Write(p []byte) (n int, err error) {
t.out.Write(p)
if log.IsLevelEnabled(log.DebugLevel) {
t.out.Write(p)
}
return t.buf.Write(p)
}

Expand Down

0 comments on commit bfff288

Please sign in to comment.