diff --git a/pkg/parser/file_inclusion_test.go b/pkg/parser/file_inclusion_test.go index a6af153d..2e1f0d98 100644 --- a/pkg/parser/file_inclusion_test.go +++ b/pkg/parser/file_inclusion_test.go @@ -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() { diff --git a/pkg/renderer/html5/document.go b/pkg/renderer/html5/document.go index 111f7112..f4e6761b 100644 --- a/pkg/renderer/html5/document.go +++ b/pkg/renderer/html5/document.go @@ -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" ) @@ -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) diff --git a/pkg/renderer/html5/file_inclusion_test.go b/pkg/renderer/html5/file_inclusion_test.go index 40e4da7e..1133a803 100644 --- a/pkg/renderer/html5/file_inclusion_test.go +++ b/pkg/renderer/html5/file_inclusion_test.go @@ -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 := `
+

content

+
` + 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 := `
+

content

+
` + Expect(source).To(RenderHTML5Body(expected)) + }) + It("include non adoc file", func() { source := `= Master Document diff --git a/pkg/types/types.go b/pkg/types/types.go index 5e226d08..e78a0060 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -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 // ------------------------------------------ diff --git a/testsupport/console_matcher.go b/testsupport/console_matcher.go index a9b92c8e..f1abc436 100644 --- a/testsupport/console_matcher.go +++ b/testsupport/console_matcher.go @@ -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) }