Skip to content

Commit

Permalink
refactor(parser): do not parse for links if not needed (bytesparadise…
Browse files Browse the repository at this point in the history
…#463)

only parse for inline links if a document attribute
substitution occurred

also, update the grammar for inline links to parse
until the EOF

Fixes bytesparadise#462

Signed-off-by: Xavier Coulon <[email protected]>
  • Loading branch information
xcoulon authored Jan 3, 2020
1 parent 2a13488 commit 4b9cc03
Show file tree
Hide file tree
Showing 5 changed files with 961 additions and 930 deletions.
2 changes: 1 addition & 1 deletion pkg/parser/document_processing.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func ParseDocument(filename string, r io.Reader, opts ...Option) (types.Document
}

// apply document attribute substitutions and re-parse paragraphs that were affected
blocks, err := applyDocumentAttributeSubstitutions(draftDoc.Blocks, attrs)
blocks, _, err := applyDocumentAttributeSubstitutions(draftDoc.Blocks, attrs)
if err != nil {
return types.Document{}, err
}
Expand Down
82 changes: 46 additions & 36 deletions pkg/parser/document_processing_apply_substitutions.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,102 +10,112 @@ import (

// applyDocumentAttributeSubstitutions(elements applies the document attribute substitutions
// and re-parse the paragraphs that were affected
func applyDocumentAttributeSubstitutions(element interface{}, attrs types.DocumentAttributes) (interface{}, error) {
// nolint: gocyclo
func applyDocumentAttributeSubstitutions(element interface{}, attrs types.DocumentAttributes) (interface{}, bool, error) {
// the document attributes, as they are resolved while processing the blocks
log.Debugf("applying document substitutions on block of type %T", element)
switch e := element.(type) {
case []interface{}:
elements := make([]interface{}, 0, len(e)) // maximum capacity cannot exceed initial input
applied := false
for _, element := range e {
r, err := applyDocumentAttributeSubstitutions(element, attrs)
r, a, err := applyDocumentAttributeSubstitutions(element, attrs)
if err != nil {
return []interface{}{}, err
return []interface{}{}, false, err
}
elements = append(elements, r)
applied = applied || a
}
// elements = filter(elements, DocumentAttributeMatcher)
return parseInlineLinks(types.MergeStringElements(elements))
elements = types.MergeStringElements(elements)
if applied {
elements, err := parseInlineLinks(elements)
return elements, true, err
}
return elements, false, nil
case types.DocumentAttributeDeclaration:
attrs[e.Name] = e.Value
return e, nil
return e, false, nil
case types.DocumentAttributeReset:
delete(attrs, e.Name)
return e, nil
return e, false, nil
case types.DocumentAttributeSubstitution:
if value, ok := attrs[e.Name].(string); ok {
return types.StringElement{
Content: value,
}, nil
}, true, nil
}
return types.StringElement{
Content: "{" + e.Name + "}",
}, nil
}, false, nil
case types.ImageBlock:
return e.ResolveLocation(attrs), nil
return e.ResolveLocation(attrs), false, nil
case types.InlineImage:
return e.ResolveLocation(attrs), nil
return e.ResolveLocation(attrs), false, nil
case types.Section:
title, err := applyDocumentAttributeSubstitutions(e.Title, attrs)
title, applied, err := applyDocumentAttributeSubstitutions(e.Title, attrs)
if err != nil {
return struct{}{}, err
return struct{}{}, false, err
}
if title, ok := title.([]interface{}); ok {
e.Title = title
}
return e.ResolveID(attrs)
e, err = e.ResolveID(attrs)
return e, applied, err
case types.OrderedListItem:
elements, err := applyDocumentAttributeSubstitutions(e.Elements, attrs)
elements, applied, err := applyDocumentAttributeSubstitutions(e.Elements, attrs)
if err != nil {
return struct{}{}, err
return struct{}{}, false, err
}
e.Elements = elements.([]interface{})
return e, nil
return e, applied, nil
case types.UnorderedListItem:
elements, err := applyDocumentAttributeSubstitutions(e.Elements, attrs)
elements, applied, err := applyDocumentAttributeSubstitutions(e.Elements, attrs)
if err != nil {
return struct{}{}, err
return struct{}{}, false, err
}
e.Elements = elements.([]interface{})
return e, nil
return e, applied, nil
case types.LabeledListItem:
elements, err := applyDocumentAttributeSubstitutions(e.Elements, attrs)
elements, applied, err := applyDocumentAttributeSubstitutions(e.Elements, attrs)
if err != nil {
return struct{}{}, err
return struct{}{}, false, err
}
e.Elements = elements.([]interface{})
return e, nil
return e, applied, nil
case types.QuotedText:
elements, err := applyDocumentAttributeSubstitutions(e.Elements, attrs)
elements, applied, err := applyDocumentAttributeSubstitutions(e.Elements, attrs)
if err != nil {
return struct{}{}, err
return struct{}{}, false, err
}
e.Elements = elements.([]interface{})
return e, nil
return e, applied, nil
case types.ContinuedListItemElement:
element, err := applyDocumentAttributeSubstitutions(e.Element, attrs)
element, applied, err := applyDocumentAttributeSubstitutions(e.Element, attrs)
if err != nil {
return struct{}{}, err
return struct{}{}, false, err
}
e.Element = element
return e, nil
return e, applied, nil
case types.DelimitedBlock:
elements, err := applyDocumentAttributeSubstitutions(e.Elements, attrs)
elements, applied, err := applyDocumentAttributeSubstitutions(e.Elements, attrs)
if err != nil {
return struct{}{}, err
return struct{}{}, false, err
}
e.Elements = elements.([]interface{})
return e, nil
return e, applied, nil
case types.Paragraph:
applied := false
for i, line := range e.Lines {
line, err := applyDocumentAttributeSubstitutions(line, attrs)
line, a, err := applyDocumentAttributeSubstitutions(line, attrs)
if err != nil {
return struct{}{}, err
return struct{}{}, false, err
}
e.Lines[i] = line.([]interface{})
applied = applied || a
}
return e, nil
return e, applied, nil
default:
return e, nil
return e, false, nil
}
}

Expand Down
36 changes: 24 additions & 12 deletions pkg/parser/document_processing_apply_substitutions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ var _ = Describe("document attribute subsititutions", func() {
},
}
// when
result, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
result, applied, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
"foo": "bar",
})
// then
Expect(err).To(Not(HaveOccurred()))
Expect(applied).To(BeTrue())
Expect(result).To(Equal([]interface{}{
types.Paragraph{
Attributes: types.ElementAttributes{},
Expand Down Expand Up @@ -64,11 +65,12 @@ var _ = Describe("document attribute subsititutions", func() {
},
}
// when
result, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
result, applied, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
"foo": "bar",
})
// then
Expect(err).To(Not(HaveOccurred()))
Expect(applied).To(BeTrue())
Expect(result).To(Equal([]interface{}{
types.Paragraph{
Attributes: types.ElementAttributes{},
Expand Down Expand Up @@ -104,11 +106,12 @@ var _ = Describe("document attribute subsititutions", func() {
},
}
// when
result, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
result, applied, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
"foo": "bar",
})
// then
Expect(err).To(Not(HaveOccurred()))
Expect(applied).To(BeTrue())
Expect(result).To(Equal([]interface{}{
types.Paragraph{
Attributes: types.ElementAttributes{},
Expand Down Expand Up @@ -144,9 +147,10 @@ var _ = Describe("document attribute subsititutions", func() {
},
}
// when
result, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{})
result, applied, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{})
// then
Expect(err).To(Not(HaveOccurred()))
Expect(applied).To(BeFalse())
Expect(result).To(Equal([]interface{}{
types.Paragraph{
Attributes: types.ElementAttributes{},
Expand Down Expand Up @@ -182,9 +186,10 @@ var _ = Describe("document attribute subsititutions", func() {
},
}
// when
result, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{})
result, applied, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{})
// then
Expect(err).To(Not(HaveOccurred()))
Expect(applied).To(BeFalse())
Expect(result).To(Equal([]interface{}{
types.Paragraph{
Attributes: types.ElementAttributes{},
Expand Down Expand Up @@ -226,12 +231,13 @@ var _ = Describe("document attribute subsititutions", func() {
},
}
// when
result, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
result, applied, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
"scheme": "https",
"host": "foo.bar",
})
// then
Expect(err).To(Not(HaveOccurred()))
Expect(applied).To(BeTrue())
Expect(result).To(Equal([]interface{}{
types.Paragraph{
Attributes: types.ElementAttributes{},
Expand Down Expand Up @@ -283,11 +289,12 @@ var _ = Describe("document attribute subsititutions", func() {
},
}
// when
result, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
result, applied, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
"foo": "bar",
})
// then
Expect(err).To(Not(HaveOccurred()))
Expect(applied).To(BeTrue())
Expect(result).To(Equal([]interface{}{
types.OrderedListItem{
Elements: []interface{}{
Expand Down Expand Up @@ -328,11 +335,12 @@ var _ = Describe("document attribute subsititutions", func() {
},
}
// when
result, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
result, applied, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
"foo": "bar",
})
// then
Expect(err).To(Not(HaveOccurred()))
Expect(applied).To(BeTrue())
Expect(result).To(Equal([]interface{}{
types.UnorderedListItem{
Elements: []interface{}{
Expand Down Expand Up @@ -373,11 +381,12 @@ var _ = Describe("document attribute subsititutions", func() {
},
}
// when
result, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
result, applied, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
"foo": "bar",
})
// then
Expect(err).To(Not(HaveOccurred()))
Expect(applied).To(BeTrue())
Expect(result).To(Equal([]interface{}{
types.LabeledListItem{
Elements: []interface{}{
Expand Down Expand Up @@ -421,11 +430,12 @@ var _ = Describe("document attribute subsititutions", func() {
},
}
// when
result, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
result, applied, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
"foo": "bar",
})
// then
Expect(err).To(Not(HaveOccurred()))
Expect(applied).To(BeTrue())
Expect(result).To(Equal([]interface{}{
types.DelimitedBlock{
Elements: []interface{}{
Expand Down Expand Up @@ -476,11 +486,12 @@ var _ = Describe("document attribute subsititutions", func() {
},
}
// when
result, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
result, applied, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
"foo": "bar",
})
// then
Expect(err).To(Not(HaveOccurred()))
Expect(applied).To(BeTrue())
Expect(result).To(Equal([]interface{}{
types.Paragraph{
Lines: [][]interface{}{
Expand Down Expand Up @@ -524,11 +535,12 @@ var _ = Describe("document attribute subsititutions", func() {
},
}
// when
result, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
result, applied, err := applyDocumentAttributeSubstitutions(elements, types.DocumentAttributes{
"foo": "bar",
})
// then
Expect(err).To(Not(HaveOccurred()))
Expect(applied).To(BeTrue())
Expect(result).To(Equal([]interface{}{
types.DelimitedBlock{
Elements: []interface{}{
Expand Down
Loading

0 comments on commit 4b9cc03

Please sign in to comment.