diff --git a/pkg/parser/document_attributes_test.go b/pkg/parser/document_attributes_test.go index 027c949b..d4f23848 100644 --- a/pkg/parser/document_attributes_test.go +++ b/pkg/parser/document_attributes_test.go @@ -1188,7 +1188,9 @@ a paragraph written by {author}.` a paragraph written by {author}.` expected := types.Document{ Attributes: types.Attributes{ - "author": "Xavier", + "author": "Xavier", + "author1": nil, + "author2": nil, }, Elements: []interface{}{ types.Paragraph{ diff --git a/pkg/parser/document_processing_apply_substitutions.go b/pkg/parser/document_processing_apply_substitutions.go index e8dd93b4..9544a63c 100644 --- a/pkg/parser/document_processing_apply_substitutions.go +++ b/pkg/parser/document_processing_apply_substitutions.go @@ -80,7 +80,7 @@ func applyAttributeSubstitutionsOnElement(element interface{}, attrs types.Attri attrs.Set(e.Name, e.Value) return e, false, nil case types.AttributeReset: - attrs.Delete(e.Name) + attrs.Set(e.Name, nil) // This allows us to test for a reset vs. undefined. return e, false, nil case types.AttributeSubstitution: if value, ok := attrs.GetAsString(e.Name); ok { diff --git a/pkg/parser/link_test.go b/pkg/parser/link_test.go index ee075df4..98b418d6 100644 --- a/pkg/parser/link_test.go +++ b/pkg/parser/link_test.go @@ -740,6 +740,7 @@ a link to {scheme}://{path} and https://foo.baz` expected := types.Document{ Attributes: types.Attributes{ "scheme": "https", + "path": nil, }, Elements: []interface{}{ types.Paragraph{ @@ -1193,6 +1194,7 @@ a link to {scheme}:{path}[] and https://foo.baz` expected := types.Document{ Attributes: types.Attributes{ "scheme": "link", + "path": nil, }, Elements: []interface{}{ types.Paragraph{ diff --git a/pkg/renderer/sgml/document_details.go b/pkg/renderer/sgml/document_details.go index 2a49b595..f677063e 100644 --- a/pkg/renderer/sgml/document_details.go +++ b/pkg/renderer/sgml/document_details.go @@ -2,6 +2,7 @@ package sgml import ( "bytes" + "fmt" "strconv" "strings" @@ -17,20 +18,24 @@ func (r *sgmlRenderer) renderDocumentDetails(ctx *renderer.Context) (*sanitized, return nil, errors.Wrap(err, "error while rendering the document details") } documentDetailsBuff := &bytes.Buffer{} + revLabel, _ := ctx.Attributes.GetAsString("version-label") revNumber, _ := ctx.Attributes.GetAsString("revnumber") revDate, _ := ctx.Attributes.GetAsString("revdate") revRemark, _ := ctx.Attributes.GetAsString("revremark") err = r.documentDetails.Execute(documentDetailsBuff, struct { Authors sanitized + RevLabel string RevNumber string RevDate string RevRemark string }{ Authors: *authors, + RevLabel: revLabel, RevNumber: revNumber, RevDate: revDate, RevRemark: revRemark, }) + fmt.Printf("DEBUG: REVISION: %q\n", revLabel) if err != nil { return nil, errors.Wrap(err, "error while rendering the document details") } diff --git a/pkg/renderer/sgml/html5/document_details.go b/pkg/renderer/sgml/html5/document_details.go index a0936eee..e4e17bc2 100644 --- a/pkg/renderer/sgml/html5/document_details.go +++ b/pkg/renderer/sgml/html5/document_details.go @@ -3,7 +3,7 @@ package html5 const ( documentDetailsTmpl = `
{{ if .Authors }} {{ .Authors }}{{ end }}{{ if .RevNumber }} -version {{ .RevNumber }}{{ if .RevDate }},{{ end }}{{ end }}{{ if .RevDate }} +{{ if .RevLabel }}{{ .RevLabel }} {{ end }}{{ .RevNumber }}{{ if .RevDate }},{{ end }}{{ end }}{{ if .RevDate }} {{ .RevDate }}{{ end }}{{ if .RevRemark }}
{{ .RevRemark }}{{ end }}
diff --git a/pkg/renderer/sgml/xhtml5/document_details.go b/pkg/renderer/sgml/xhtml5/document_details.go index dd37dab7..400f6603 100644 --- a/pkg/renderer/sgml/xhtml5/document_details.go +++ b/pkg/renderer/sgml/xhtml5/document_details.go @@ -3,7 +3,7 @@ package xhtml5 const ( documentDetailsTmpl = `
{{ if .Authors }} {{ .Authors }}{{ end }}{{ if .RevNumber }} -version {{ .RevNumber }}{{ if .RevDate }},{{ end }}{{ end }}{{ if .RevDate }} +{{ if .RevLabel }}{{ .RevLabel }} {{ end }}{{ .RevNumber }}{{ if .RevDate }},{{ end }}{{ end }}{{ if .RevDate }} {{ .RevDate }}{{ end }}{{ if .RevRemark }}
{{ .RevRemark }}{{ end }}
diff --git a/pkg/renderer/sgml/xhtml5/document_details_test.go b/pkg/renderer/sgml/xhtml5/document_details_test.go index 6fe34157..36cb39a0 100644 --- a/pkg/renderer/sgml/xhtml5/document_details_test.go +++ b/pkg/renderer/sgml/xhtml5/document_details_test.go @@ -173,6 +173,92 @@ a paragraph` )).To(MatchHTMLTemplate(expected, now)) }) + It("with author and version label reset", func() { + source := `= Document Title +Joe Blow +1.5, May 21, 1999 +:version-label!: + +a paragraph` + expected := ` + + + + + + + +Document Title + + + +
+
+

a paragraph

+
+
+ +` + Expect(RenderXHTML(source, + configuration.WithHeaderFooter(true), + configuration.WithLastUpdated(now), + configuration.WithAttributes(map[string]string{ + types.AttrNoFooter: "", + }), + )).To(MatchHTMLTemplate(expected, now)) + }) + + It("with author and custom version label only", func() { + source := `= Document Title +Joe Blow +1.0, May 21, 1999 +:version-label: Edition + +a paragraph` + expected := ` + + + + + + + +Document Title + + + +
+
+

a paragraph

+
+
+ +` + Expect(RenderXHTML(source, + configuration.WithHeaderFooter(true), + configuration.WithLastUpdated(now), + configuration.WithAttributes(map[string]string{ + types.AttrNoFooter: "", + }), + )).To(MatchHTMLTemplate(expected, now)) + }) + It("without header and with footer", func() { source := `= Document Title @@ -238,6 +324,5 @@ a paragraph` }), )).To(MatchHTMLTemplate(expected, now)) }) - }) }) diff --git a/pkg/types/attributes.go b/pkg/types/attributes.go index 9cad684a..6a99c17e 100644 --- a/pkg/types/attributes.go +++ b/pkg/types/attributes.go @@ -109,6 +109,8 @@ const ( AttrPositional2 = "@2" // AttrPositional3 positional parameter 3 AttrPositional3 = "@3" + // AttrVersionLabel labels the version number in the document + AttrVersionLabel = "version-label" ) // NewElementID initializes a new attribute map with a single entry for the ID using the given value @@ -338,32 +340,38 @@ func (a Attributes) NilSafeSet(key string, value interface{}) { // GetAsString gets the string value for the given key (+ `true`), // or empty string (+ `false`) if none was found func (a Attributes) GetAsString(key string) (string, bool) { - // check in predefined attributes - if value, found := Predefined[key]; found { - return value, true - } if value, found := a[key]; found { + if value == nil { + return "", false // nil here means attribute was reset + } if value, ok := value.(string); ok { return value, true } else if v, ok := a[key]; ok { return fmt.Sprintf("%v", v), true } } + // check in predefined attributes + if value, found := Predefined[key]; found { + return value, true + } return "", false } // GetAsStringWithDefault gets the string value for the given key, // or returns the given default value func (a Attributes) GetAsStringWithDefault(key, defaultValue string) string { - // check in predefined attributes - if value, found := Predefined[key]; found { - return value - } if value, found := a[key]; found { + if value == nil { + return "" // nil present means attribute was reset + } if value, ok := value.(string); ok { return value } } + // check in predefined attributes + if value, found := Predefined[key]; found { + return value + } return defaultValue } diff --git a/pkg/types/predefined_attributes.go b/pkg/types/predefined_attributes.go index 9710d8f9..b9bd054f 100644 --- a/pkg/types/predefined_attributes.go +++ b/pkg/types/predefined_attributes.go @@ -34,5 +34,6 @@ func init() { "two-colons": "::", "two-semicolons": ";", "cpp": "C++", + AttrVersionLabel: "version", } } diff --git a/pkg/types/types.go b/pkg/types/types.go index ff9636c4..56d56827 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -272,20 +272,10 @@ type AttributeDeclaration struct { // NewAttributeDeclaration initializes a new AttributeDeclaration with the given name and optional value func NewAttributeDeclaration(name string, value interface{}) (AttributeDeclaration, error) { - var attrName, attrValue string - attrName = Apply(name, - func(s string) string { - return strings.TrimSpace(s) - }) - if value, ok := value.(string); ok { - attrValue = Apply(value, - func(s string) string { - return strings.TrimSpace(s) - }) - } - log.Debugf("initialized a new AttributeDeclaration: '%s' -> '%s'", attrName, attrValue) + attrValue, _ := value.(string) + log.Debugf("initialized a new AttributeDeclaration: '%s' -> '%s'", name, attrValue) return AttributeDeclaration{ - Name: attrName, + Name: name, Value: attrValue, }, nil }