diff --git a/libasciidoc_test.go b/libasciidoc_test.go index 0a67ac24..f6ecd632 100644 --- a/libasciidoc_test.go +++ b/libasciidoc_test.go @@ -123,23 +123,24 @@ a paragraph` Expect(DocumentMetadata(source, lastUpdated)).To(Equal(types.Metadata{ Title: "a document title", LastUpdated: lastUpdated.Format(configuration.LastUpdatedFormat), - TableOfContents: types.TableOfContents{ - Sections: []*types.ToCSection{ - { - ID: "_section_a", - Level: 1, - Title: "Section A", - Children: []*types.ToCSection{ - { - ID: "_section_a_a_a", - Level: 3, - Title: "Section A.a.a", - Children: []*types.ToCSection{}, - }, - }, - }, - }, - }, + // see https://github.com/bytesparadise/libasciidoc/issues/939 + // TableOfContents: types.TableOfContents{ + // Sections: []*types.ToCSection{ + // { + // ID: "_section_a", + // Level: 1, + // Title: "Section A", + // Children: []*types.ToCSection{ + // { + // ID: "_section_a_a_a", + // Level: 3, + // Title: "Section A.a.a", + // Children: []*types.ToCSection{}, + // }, + // }, + // }, + // }, + // }, })) }) @@ -186,29 +187,30 @@ a paragraph with _italic content_` Expect(DocumentMetadata(source, lastUpdated)).To(Equal(types.Metadata{ Title: "a document title", LastUpdated: lastUpdated.Format(configuration.LastUpdatedFormat), - TableOfContents: types.TableOfContents{ - Sections: []*types.ToCSection{ - { - ID: "_section_a", - Level: 1, - Title: "Section A", - Children: []*types.ToCSection{ - { - ID: "_section_a_a", - Level: 2, - Title: "Section A.a", - Children: []*types.ToCSection{}, - }, - }, - }, - { - ID: "_section_b", - Level: 1, - Title: "Section B", - Children: []*types.ToCSection{}, - }, - }, - }, + // see https://github.com/bytesparadise/libasciidoc/issues/939 + // TableOfContents: types.TableOfContents{ + // Sections: []*types.ToCSection{ + // { + // ID: "_section_a", + // Level: 1, + // Title: "Section A", + // Children: []*types.ToCSection{ + // { + // ID: "_section_a_a", + // Level: 2, + // Title: "Section A.a", + // Children: []*types.ToCSection{}, + // }, + // }, + // }, + // { + // ID: "_section_b", + // Level: 1, + // Title: "Section B", + // Children: []*types.ToCSection{}, + // }, + // }, + // }, })) }) @@ -230,16 +232,17 @@ a paragraph with _italic content_` Expect(DocumentMetadata(source, lastUpdated)).To(Equal(types.Metadata{ Title: "", LastUpdated: lastUpdated.Format(configuration.LastUpdatedFormat), - TableOfContents: types.TableOfContents{ - Sections: []*types.ToCSection{ - { - ID: "_grandchild_title", - Level: 1, - Title: "grandchild title", - Children: []*types.ToCSection{}, - }, - }, - }, + // see https://github.com/bytesparadise/libasciidoc/issues/939 + // TableOfContents: types.TableOfContents{ + // Sections: []*types.ToCSection{ + // { + // ID: "_grandchild_title", + // Level: 1, + // Title: "grandchild title", + // Children: []*types.ToCSection{}, + // }, + // }, + // }, })) }) }) diff --git a/pkg/parser/attribute_substitution_test.go b/pkg/parser/attribute_substitution_test.go index a180bd2b..5fd1279c 100644 --- a/pkg/parser/attribute_substitution_test.go +++ b/pkg/parser/attribute_substitution_test.go @@ -124,7 +124,9 @@ This journey continues` }, }, }, - TableOfContents: &types.TableOfContents{}, // TODO: should we include a ToC when it's empty? + TableOfContents: &types.TableOfContents{ + MaxDepth: 2, + }, } Expect(ParseDocument(source)).To(MatchDocument(expected)) }) diff --git a/pkg/parser/document_fragment_processing_test.go b/pkg/parser/document_fragment_processing_test.go index 5f1f7010..967c9d11 100644 --- a/pkg/parser/document_fragment_processing_test.go +++ b/pkg/parser/document_fragment_processing_test.go @@ -134,28 +134,25 @@ Preamble comes here "_section_c": titleSectionC, }, TableOfContents: &types.TableOfContents{ + MaxDepth: 2, Sections: []*types.ToCSection{ { ID: "_section_a", Level: 1, - Title: "Section A", Children: []*types.ToCSection{ { ID: "_section_a_a", Level: 2, - Title: "Section A.a", }, }, }, { ID: "_section_b", Level: 1, - Title: "Section B", }, { ID: "_section_c", Level: 1, - Title: "Section C", }, }, }, diff --git a/pkg/parser/document_header_test.go b/pkg/parser/document_header_test.go index 3c2bd952..c3f1de1c 100644 --- a/pkg/parser/document_header_test.go +++ b/pkg/parser/document_header_test.go @@ -1103,7 +1103,9 @@ a paragraph` }, }, }, - TableOfContents: &types.TableOfContents{}, + TableOfContents: &types.TableOfContents{ + MaxDepth: 2, + }, } Expect(ParseDocument(source)).To(MatchDocument(expected)) }) @@ -1133,7 +1135,9 @@ a paragraph` }, }, }, - TableOfContents: &types.TableOfContents{}, + TableOfContents: &types.TableOfContents{ + MaxDepth: 2, + }, } Expect(ParseDocument(source)).To(MatchDocument(expected)) }) @@ -1169,7 +1173,9 @@ a paragraph` }, }, }, - TableOfContents: &types.TableOfContents{}, + TableOfContents: &types.TableOfContents{ + MaxDepth: 2, + }, } Expect(ParseDocument(source)).To(MatchDocument(expected)) }) @@ -1199,7 +1205,9 @@ a paragraph` Value: "Xavier", }, }, - TableOfContents: &types.TableOfContents{}, + TableOfContents: &types.TableOfContents{ + MaxDepth: 2, + }, } Expect(ParseDocument(source)).To(MatchDocument(expected)) }) diff --git a/pkg/parser/document_processing_aggregate_test.go b/pkg/parser/document_processing_aggregate_test.go index d0c7d431..d57b6e14 100644 --- a/pkg/parser/document_processing_aggregate_test.go +++ b/pkg/parser/document_processing_aggregate_test.go @@ -65,11 +65,11 @@ var _ = Describe("aggregate fragments", func() { "_section_1": section1Title, }, TableOfContents: &types.TableOfContents{ + MaxDepth: 2, Sections: []*types.ToCSection{ { ID: "_section_1", Level: 1, - Title: "section 1", }, }, }, @@ -126,11 +126,11 @@ var _ = Describe("aggregate fragments", func() { "_section_1": section1Title, }, TableOfContents: &types.TableOfContents{ + MaxDepth: 2, Sections: []*types.ToCSection{ { ID: "_section_1", Level: 1, - Title: "section 1", }, }, }, @@ -173,7 +173,9 @@ var _ = Describe("aggregate fragments", func() { }, paragraph, // not wrapped in a preamble since there is nothing afterwards }, - TableOfContents: &types.TableOfContents{}, + TableOfContents: &types.TableOfContents{ + MaxDepth: 2, + }, } doc, _, err := parser.Aggregate(ctx, c) Expect(err).NotTo(HaveOccurred()) @@ -215,11 +217,11 @@ var _ = Describe("aggregate fragments", func() { "_section_1": section1Title, }, TableOfContents: &types.TableOfContents{ + MaxDepth: 2, Sections: []*types.ToCSection{ { ID: "_section_1", Level: 1, - Title: "section 1", }, }, }, @@ -278,11 +280,11 @@ var _ = Describe("aggregate fragments", func() { "_section_1": section1Title, }, TableOfContents: &types.TableOfContents{ + MaxDepth: 2, Sections: []*types.ToCSection{ { ID: "_section_1", Level: 1, - Title: "section 1", }, }, }, @@ -333,7 +335,9 @@ var _ = Describe("aggregate fragments", func() { }, paragraph, }, - TableOfContents: &types.TableOfContents{}, + TableOfContents: &types.TableOfContents{ + MaxDepth: 2, + }, } doc, _, err := parser.Aggregate(ctx, c) Expect(err).NotTo(HaveOccurred()) diff --git a/pkg/parser/table_of_contents_test.go b/pkg/parser/table_of_contents_test.go index 5c0a75a9..2cf36267 100644 --- a/pkg/parser/table_of_contents_test.go +++ b/pkg/parser/table_of_contents_test.go @@ -151,40 +151,35 @@ var _ = Describe("tables of contents", func() { close(c) expectedToC := &types.TableOfContents{ + MaxDepth: 2, Sections: []*types.ToCSection{ { ID: "_section_a", Level: 1, - Title: "Section A", Children: []*types.ToCSection{ { ID: "_section_a_a", Level: 2, - Title: "Section A.a", }, { ID: "_section_a_b", Level: 2, - Title: "Section A.b", }, }, }, { ID: "_section_b", Level: 1, - Title: "Section B", Children: []*types.ToCSection{ { ID: "_section_b_a", Level: 2, - Title: "Section B.a", }, }, }, { ID: "_section_c", Level: 1, - Title: "Section C", }, }, } @@ -337,26 +332,23 @@ var _ = Describe("tables of contents", func() { close(c) expectedToC := &types.TableOfContents{ + MaxDepth: 3, Sections: []*types.ToCSection{ { ID: "_section_a", Level: 1, - Title: "Section A", Children: []*types.ToCSection{ { ID: "_section_a_a", Level: 2, - Title: "Section A.a", }, { ID: "_section_a_b", Level: 2, - Title: "Section A.b", Children: []*types.ToCSection{ { ID: "_section_that_shall_be_in_ToC", Level: 3, - Title: "Section that shall be in ToC", }, }, }, @@ -365,19 +357,16 @@ var _ = Describe("tables of contents", func() { { ID: "_section_b", Level: 1, - Title: "Section B", Children: []*types.ToCSection{ { ID: "_section_b_a", Level: 2, - Title: "Section B.a", }, }, }, { ID: "_section_c", Level: 1, - Title: "Section C", }, }, } @@ -458,16 +447,15 @@ a preamble "_section_2": section2Title, }, TableOfContents: &types.TableOfContents{ + MaxDepth: 2, Sections: []*types.ToCSection{ { ID: "_section_1", Level: 1, - Title: "Section 1", }, { ID: "_section_2", Level: 1, - Title: "Section 2", }, }, }, @@ -535,16 +523,15 @@ a preamble "_section_2": section2Title, }, TableOfContents: &types.TableOfContents{ + MaxDepth: 2, Sections: []*types.ToCSection{ { ID: "_section_1", Level: 1, - Title: "Section 1", }, { ID: "_section_2", Level: 1, - Title: "Section 2", }, }, }, @@ -619,16 +606,15 @@ a preamble "_section_2": section2Title, }, TableOfContents: &types.TableOfContents{ + MaxDepth: 2, Sections: []*types.ToCSection{ { ID: "_section_1", Level: 1, - Title: "Section 1", }, { ID: "_section_2", Level: 1, - Title: "Section 2", }, }, }, @@ -683,16 +669,15 @@ a preamble "_section_2": section2Title, }, TableOfContents: &types.TableOfContents{ + MaxDepth: 2, Sections: []*types.ToCSection{ { ID: "_section_1", Level: 1, - Title: "Section 1", }, { ID: "_section_2", Level: 1, - Title: "Section 2", }, }, }, @@ -747,16 +732,15 @@ a preamble "_section_2": section2Title, }, TableOfContents: &types.TableOfContents{ + MaxDepth: 2, Sections: []*types.ToCSection{ { ID: "_section_1", Level: 1, - Title: "Section 1", }, { ID: "_section_2", Level: 1, - Title: "Section 2", }, }, }, diff --git a/pkg/renderer/context.go b/pkg/renderer/context.go index 48eb5d2a..5182c49e 100644 --- a/pkg/renderer/context.go +++ b/pkg/renderer/context.go @@ -8,10 +8,7 @@ import ( // Context is a custom implementation of the standard golang context.Context interface, // which carries the types.Document which is being processed type Context struct { - Config *configuration.Configuration // TODO: use composition (remove the `Config` field) - // TableOfContents exists even if the document did not specify the `:toc:` attribute. - // It will take into account the configured `:toclevels:` attribute value. - TableOfContents types.TableOfContents + Config *configuration.Configuration // TODO: use composition (remove the `Config` field) WithinDelimitedBlock bool EncodeSpecialChars bool WithinList int diff --git a/pkg/renderer/sgml/elements.go b/pkg/renderer/sgml/elements.go index f914d412..56ec194b 100644 --- a/pkg/renderer/sgml/elements.go +++ b/pkg/renderer/sgml/elements.go @@ -7,6 +7,7 @@ import ( "github.com/bytesparadise/libasciidoc/pkg/types" "github.com/pkg/errors" + log "github.com/sirupsen/logrus" ) func (r *sgmlRenderer) renderElements(ctx *renderer.Context, elements []interface{}) (string, error) { @@ -119,7 +120,7 @@ func (r *sgmlRenderer) renderElement(ctx *renderer.Context, element interface{}) // nolint:gocyclo func (r *sgmlRenderer) renderPlainText(ctx *renderer.Context, element interface{}) (string, error) { - // log.Debugf("rendering plain string for element of type %T", element) + log.Debugf("rendering plain string for element of type %T", element) switch element := element.(type) { case []interface{}: return r.renderInlineElements(ctx, element, withRenderer(r.renderPlainText)) @@ -139,7 +140,7 @@ func (r *sgmlRenderer) renderPlainText(ctx *renderer.Context, element interface{ case *types.StringElement: return element.Content, nil case *types.QuotedString: - return r.renderQuotedStringPlain(ctx, element) + return r.renderQuotedString(ctx, element) // case *types.Paragraph: // return r.renderParagraph(ctx, element, withRenderer(r.renderPlainText)) case *types.FootnoteReference: diff --git a/pkg/renderer/sgml/html5/file_inclusion_test.go b/pkg/renderer/sgml/html5/file_inclusion_test.go index de3c7711..8c55a367 100644 --- a/pkg/renderer/sgml/html5/file_inclusion_test.go +++ b/pkg/renderer/sgml/html5/file_inclusion_test.go @@ -35,16 +35,6 @@ var _ = Describe("file inclusions", func() { Expect(DocumentMetadata(source, lastUpdated)).To(Equal(types.Metadata{ Title: "", LastUpdated: lastUpdated.Format(configuration.LastUpdatedFormat), - TableOfContents: types.TableOfContents{ - Sections: []*types.ToCSection{ - { - ID: "_grandchild_title", - Level: 1, - Title: "grandchild title", - Children: []*types.ToCSection{}, - }, - }, - }, })) // verify no error/warning in logs Expect(logs).ToNot(ContainAnyMessageWithLevels(log.ErrorLevel, log.WarnLevel)) diff --git a/pkg/renderer/sgml/html5/quoted_string_test.go b/pkg/renderer/sgml/html5/quoted_string_test.go index 54caa499..c9bb4da7 100644 --- a/pkg/renderer/sgml/html5/quoted_string_test.go +++ b/pkg/renderer/sgml/html5/quoted_string_test.go @@ -349,6 +349,7 @@ var _ = Describe("quoted strings", func() { Expect(RenderHTML(source)).To(MatchHTML(expected)) }) + It("image in double curly", func() { source := "\"`a image:foo.png[]`\"" expected := `
@@ -357,11 +358,31 @@ var _ = Describe("quoted strings", func() { ` Expect(RenderHTML(source)).To(MatchHTML(expected)) }) + It("icon in double curly", func() { source := ":icons: font\n\n\"`a icon:note[]`\"" expected := `

“a

+` + Expect(RenderHTML(source)).To(MatchHTML(expected)) + }) + + It("smart quotes in section title and table of contents", func() { + source := "= title\n" + + ":toc:\n\n" + + "== \"`smart`\" quotes" + expected := `
+
Table of Contents
+ +
+
+

“smart” quotes

+
+
+
` Expect(RenderHTML(source)).To(MatchHTML(expected)) }) diff --git a/pkg/renderer/sgml/inline_elements.go b/pkg/renderer/sgml/inline_elements.go index edb5b606..cacc4a9c 100644 --- a/pkg/renderer/sgml/inline_elements.go +++ b/pkg/renderer/sgml/inline_elements.go @@ -5,6 +5,7 @@ import ( "github.com/bytesparadise/libasciidoc/pkg/renderer" "github.com/bytesparadise/libasciidoc/pkg/types" + log "github.com/sirupsen/logrus" ) func (r *sgmlRenderer) renderInlineElements(ctx *renderer.Context, elements []interface{}, options ...lineRendererOption) (string, error) { @@ -31,9 +32,9 @@ func (r *sgmlRenderer) renderInlineElements(ctx *renderer.Context, elements []in buf.WriteString(renderedElement) } } - // if log.IsLevelEnabled(log.DebugLevel) { - // log.Debugf("rendered inline elements: '%s'", buf.String()) - // } + if log.IsLevelEnabled(log.DebugLevel) { + log.Debugf("rendered inline elements: '%s'", buf.String()) + } return buf.String(), nil } diff --git a/pkg/renderer/sgml/renderer.go b/pkg/renderer/sgml/renderer.go index c163c8c1..ac083685 100644 --- a/pkg/renderer/sgml/renderer.go +++ b/pkg/renderer/sgml/renderer.go @@ -186,11 +186,7 @@ func (r *sgmlRenderer) Render(ctx *renderer.Context, doc *types.Document, output renderedTitle = DefaultTitle } // needs to be set before rendering the content elements - ctx.TableOfContents, err = r.newTableOfContents(ctx, doc) // TODO: needed?? - if err != nil { - return metadata, errors.Wrapf(err, "unable to render full document") - } - metadata.TableOfContents = ctx.TableOfContents + metadata.TableOfContents = doc.TableOfContents renderedHeader, renderedContent, err := r.splitAndRender(ctx, doc) if err != nil { return metadata, errors.Wrapf(err, "unable to render full document") @@ -202,13 +198,12 @@ func (r *sgmlRenderer) Render(ctx *renderer.Context, doc *types.Document, output if ctx.Config.WrapInHTMLBodyElement { log.Debugf("Rendering full document...") err = r.article.Execute(output, struct { - Doctype string - Generator string - Description string - Title string - Authors string - Header string - // Role string + Doctype string + Generator string + Description string + Title string + Authors string + Header string ID string Roles string Content string diff --git a/pkg/renderer/sgml/string.go b/pkg/renderer/sgml/string.go index 6586e769..118280fe 100644 --- a/pkg/renderer/sgml/string.go +++ b/pkg/renderer/sgml/string.go @@ -13,37 +13,26 @@ import ( var quotes = map[types.QuotedStringKind]struct { Open string Close string - Plain string }{ types.SingleQuote: { Open: "\u2018", Close: "\u2019", - Plain: "'", }, types.DoubleQuote: { Open: "\u201c", Close: "\u201d", - Plain: `"`, }, } -func (r *sgmlRenderer) renderQuotedStringPlain(ctx *renderer.Context, s *types.QuotedString) (string, error) { - buf := &strings.Builder{} - b, err := r.renderPlainText(ctx, s.Elements) - if err != nil { - return "", err - } - buf.WriteString(quotes[s.Kind].Plain) - buf.WriteString(b) - buf.WriteString(quotes[s.Kind].Plain) - return buf.String(), nil -} - func (r *sgmlRenderer) renderQuotedString(ctx *renderer.Context, s *types.QuotedString) (string, error) { elements := append([]interface{}{ - &types.StringElement{Content: quotes[s.Kind].Open}, + &types.StringElement{ + Content: quotes[s.Kind].Open, + }, }, s.Elements...) - elements = append(elements, &types.StringElement{Content: quotes[s.Kind].Close}) + elements = append(elements, &types.StringElement{ + Content: quotes[s.Kind].Close, + }) return r.renderInlineElements(ctx, elements) } diff --git a/pkg/renderer/sgml/table_of_contents.go b/pkg/renderer/sgml/table_of_contents.go index d2f2731b..9eae57cf 100644 --- a/pkg/renderer/sgml/table_of_contents.go +++ b/pkg/renderer/sgml/table_of_contents.go @@ -1,12 +1,12 @@ package sgml import ( - "strconv" "strings" "github.com/bytesparadise/libasciidoc/pkg/parser" "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" ) @@ -21,7 +21,9 @@ func (r *sgmlRenderer) renderTableOfContents(ctx *renderer.Context, toc *types.T return "", errors.Wrap(err, "error while rendering table of contents") } - log.Debug("rendering table of contents...") + if log.IsLevelEnabled(log.DebugLevel) { + log.Debugf("rendering ToC %s", spew.Sdump(toc)) + } renderedSections, err := r.renderTableOfContentsSections(ctx, toc.Sections) if err != nil { return "", errors.Wrap(err, "error while rendering table of contents") @@ -66,6 +68,10 @@ func (r *sgmlRenderer) renderTableOfContentsSections(ctx *renderer.Context, sect if len(sections) == 0 { return "", nil } + if log.IsLevelEnabled(log.DebugLevel) { + log.Debugf("rendering sections (in toc): '%s'", spew.Sdump(sections)) + } + resultBuf := &strings.Builder{} contents := &strings.Builder{} for _, entry := range sections { @@ -77,15 +83,11 @@ func (r *sgmlRenderer) renderTableOfContentsSections(ctx *renderer.Context, sect } err := r.tocSection.Execute(resultBuf, struct { - Context *renderer.Context - Level int - Content string - Sections []*types.ToCSection + Level int + Content string }{ - Context: ctx, - Level: sections[0].Level, - Content: contents.String(), - Sections: sections, + Level: sections[0].Level, + Content: contents.String(), }) if err != nil { return "", errors.Wrap(err, "failed to render document ToC") @@ -105,91 +107,27 @@ func (r *sgmlRenderer) renderTableOfContentsEntry(ctx *renderer.Context, entry * if ctx.SectionNumbering != nil { number = ctx.SectionNumbering[entry.ID] } + s, found := ctx.ElementReferences[entry.ID] + if !found { + return "", errors.New("unable to render ToC entry title (missing element reference") + } + entry.Title, err = r.renderPlainText(ctx, s) + if err != nil { + return "", errors.Wrap(err, "unable to render ToC entry title (missing element reference") + } err = r.tocEntry.Execute(resultBuf, struct { - Context *renderer.Context - Number string - ID string - Title string - Content string - Children []*types.ToCSection + Number string + ID string + Title string + Content string }{ - Context: ctx, - Number: number, - ID: entry.ID, - Title: entry.Title, - Content: content, - Children: entry.Children, + Number: number, + ID: entry.ID, + Title: entry.Title, + Content: content, }) if err != nil { return "", errors.Wrap(err, "failed to render document ToC") } return resultBuf.String(), nil // nolint:gosec } - -// newTableOfContents initializes a TableOfContents from the sections -// of the given document -func (r *sgmlRenderer) newTableOfContents(ctx *renderer.Context, doc *types.Document) (types.TableOfContents, error) { - sections := make([]*types.ToCSection, 0, len(doc.Elements)) - for _, e := range doc.Elements { - if s, ok := e.(*types.Section); ok { - tocs, err := r.visitSection(ctx, s, 1) - if err != nil { - return types.TableOfContents{}, err - } - sections = append(sections, tocs...) // cqn be 1 or more (for the root section, we immediately get its children) - } - } - return types.TableOfContents{ - Sections: sections, - }, nil -} - -func (r *sgmlRenderer) visitSection(ctx *renderer.Context, section *types.Section, currentLevel int) ([]*types.ToCSection, error) { - tocLevels, err := getTableOfContentsLevels(ctx) - if err != nil { - return []*types.ToCSection{}, err - } - children := make([]*types.ToCSection, 0, len(section.Elements)) - // log.Debugf("visiting children section: %t (%d < %d)", currentLevel < tocLevels, currentLevel, tocLevels) - if currentLevel <= tocLevels { - for _, e := range section.Elements { - if s, ok := e.(*types.Section); ok { - tocs, err := r.visitSection(ctx, s, currentLevel+1) - if err != nil { - return []*types.ToCSection{}, err - } - children = append(children, tocs...) - } - } - } - if section.Level == 0 { - return children, nil // for the root section, immediately return its children) - } - - renderedTitle, err := r.renderPlainText(ctx, section.Title) - if err != nil { - return []*types.ToCSection{}, err - } - - return []*types.ToCSection{ - { - ID: section.Attributes.GetAsStringWithDefault(types.AttrID, ""), - Level: section.Level, - Title: renderedTitle, - Children: children, - }, - }, nil - -} - -func getTableOfContentsLevels(ctx *renderer.Context) (int, error) { - // log.Debugf("doc attributes: %v", ctx.Attributes) - if l, found, err := ctx.Attributes.GetAsString(types.AttrTableOfContentsLevels); err != nil { - return -1, err - } else if found { - // log.Debugf("ToC levels: '%s'", l) - return strconv.Atoi(l) - } - log.Debug("ToC levels: '2' (default)") - return 2, nil -} diff --git a/pkg/renderer/sgml/xhtml5/file_inclusion_test.go b/pkg/renderer/sgml/xhtml5/file_inclusion_test.go index cf8c60b3..cce2fa1c 100644 --- a/pkg/renderer/sgml/xhtml5/file_inclusion_test.go +++ b/pkg/renderer/sgml/xhtml5/file_inclusion_test.go @@ -33,18 +33,18 @@ var _ = Describe("file inclusions", func() { ` Expect(RenderXHTML(source, configuration.WithLastUpdated(lastUpdated))).To(Equal(expected)) Expect(DocumentMetadata(source, lastUpdated)).To(Equal(types.Metadata{ - Title: "", LastUpdated: lastUpdated.Format(configuration.LastUpdatedFormat), - TableOfContents: types.TableOfContents{ - Sections: []*types.ToCSection{ - { - ID: "_grandchild_title", - Level: 1, - Title: "grandchild title", - Children: []*types.ToCSection{}, - }, - }, - }, + // See https://github.com/bytesparadise/libasciidoc/issues/939 + // TableOfContents: &types.TableOfContents{ + // Sections: []*types.ToCSection{ + // { + // ID: "_grandchild_title", + // Level: 1, + // Title: "grandchild title", + // Children: []*types.ToCSection{}, + // }, + // }, + // }, })) // verify no error/warning in logs Expect(logs).ToNot(ContainAnyMessageWithLevels(log.ErrorLevel, log.WarnLevel)) diff --git a/pkg/types/types.go b/pkg/types/types.go index eaa5ed26..cd65cddc 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -157,20 +157,20 @@ func (d *Document) AddElement(element interface{}) error { type Metadata struct { Title string LastUpdated string - TableOfContents TableOfContents + TableOfContents *TableOfContents Authors []*DocumentAuthor Revision DocumentRevision } func NewTableOfContents(maxDepth int) *TableOfContents { return &TableOfContents{ - maxDepth: maxDepth, + MaxDepth: maxDepth, } } // TableOfContents the table of contents type TableOfContents struct { - maxDepth int + MaxDepth int Sections []*ToCSection } @@ -184,15 +184,14 @@ type ToCSection struct { // Add adds a ToCSection associated with the given Section func (t *TableOfContents) Add(s *Section) { - if s.Level > t.maxDepth { - log.Debugf("skipping section with level %d (> %d)", s.Level, t.maxDepth) + if s.Level > t.MaxDepth { + log.Debugf("skipping section with level %d (> %d)", s.Level, t.MaxDepth) // skip for elements with a too low level in the hierarchy return } ts := &ToCSection{ ID: s.GetAttributes().GetAsStringWithDefault(AttrID, ""), Level: s.Level, - Title: stringify(s.Title), } // lookup the last child at the given section's level if len(t.Sections) == 0 { diff --git a/testsupport/document_metadata_test.go b/testsupport/document_metadata_test.go index 259cbd92..04d10a76 100644 --- a/testsupport/document_metadata_test.go +++ b/testsupport/document_metadata_test.go @@ -16,13 +16,14 @@ var _ = Describe("document metadata", func() { lastUpdated := time.Now() expected := types.Metadata{ LastUpdated: lastUpdated.Format(configuration.LastUpdatedFormat), - TableOfContents: types.TableOfContents{ + Title: "Title", + TableOfContents: &types.TableOfContents{ + MaxDepth: 2, Sections: []*types.ToCSection{ { - ID: "_section_1", - Level: 1, - Title: "Section 1", - Children: []*types.ToCSection{}, + ID: "_section_1", + Level: 1, + Title: "Section 1", }, }, }, @@ -30,7 +31,10 @@ var _ = Describe("document metadata", func() { It("should match", func() { // given - actual := `== Section 1` + actual := `= Title +:toc: + +== Section 1` // when result, err := testsupport.DocumentMetadata(actual, lastUpdated) // then