Skip to content
Open

V1.6 #31

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions asciidoc/anchor.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

type AnchorAttribute struct {
attribute
child

ID Elements `json:"id"`
Label Elements
Expand Down Expand Up @@ -65,12 +66,16 @@ func (aa *AnchorAttribute) AsciiDocString() string {
return sb.String()
}

func (aa *AnchorAttribute) Traverse(parent Parent) iter.Seq2[Parent, Parent] {
return func(yield func(Parent, Parent) bool) {
if !yield(parent, &aa.Label) {
return
}
}
func (aa *AnchorAttribute) Append(el ...Element) {
aa.Label.Append(el...)
}

func (aa *AnchorAttribute) Children() Elements {
return aa.ID
}
Comment on lines +73 to +75

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The Children() method returns aa.ID, while the Append() method modifies aa.Label. This is inconsistent. The Parent interface, which Children() is part of, implies that Children() should return the elements that can be modified by Append(). To maintain consistency, Children() should probably return aa.Label.

Suggested change
func (aa *AnchorAttribute) Children() Elements {
return aa.ID
}
func (aa *AnchorAttribute) Children() Elements {
return aa.Label
}


func (aa *AnchorAttribute) Clone() Attribute {
return &AnchorAttribute{attribute: aa.attribute, ID: aa.ID.Clone(), Label: aa.Label.Clone()}
}

type Anchor struct {
Expand Down Expand Up @@ -103,6 +108,18 @@ func (a *Anchor) Equals(o Element) bool {
return a.Elements.Equals(oa.Elements)
}

func (a *Anchor) Clone() Element {
return &Anchor{position: a.position, ID: a.ID, Elements: a.Elements.Clone()}
}

func NewAnchor(id Elements, label Elements) *Anchor {
return &Anchor{ID: id, Elements: label}
}

func (aa *Anchor) Traverse(parent Parent) iter.Seq2[Parent, Parent] {
return func(yield func(Parent, Parent) bool) {
if !yield(parent, &aa.ID) {
return
}
}
}
Comment on lines +119 to +125

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The Traverse method for Anchor only traverses the ID field and omits the Elements field, which holds the label. This is inconsistent with other parts of the code, such as Equals and NewAnchor, where the label is also considered part of the content. To ensure the entire content of an Anchor is processed during traversal, the Elements field should also be yielded.

Suggested change
func (aa *Anchor) Traverse(parent Parent) iter.Seq2[Parent, Parent] {
return func(yield func(Parent, Parent) bool) {
if !yield(parent, &aa.ID) {
return
}
}
}
func (aa *Anchor) Traverse(parent Parent) iter.Seq2[Parent, Parent] {
return func(yield func(Parent, Parent) bool) {
if !yield(parent, &aa.ID) {
return
}
if !yield(parent, &aa.Elements) {
return
}
}
}

41 changes: 35 additions & 6 deletions asciidoc/attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ func (uar *AttributeEntry) Equals(e Element) bool {
return uar.Elements.Equals(ouar.Elements)
}

func (uar *AttributeEntry) Clone() Element {
return &AttributeEntry{position: uar.position, raw: uar.raw, Name: uar.Name, Elements: uar.Elements.Clone()}
}

type AttributeReset struct {
position
raw
Expand All @@ -55,6 +59,10 @@ func (uar *AttributeReset) Equals(e Element) bool {
return uar.Name == ouar.Name
}

func (uar *AttributeReset) Clone() Element {
return &AttributeReset{position: uar.position, raw: uar.raw, Name: uar.Name}
}

type Attribute interface {
HasPosition
Value() any
Expand All @@ -63,6 +71,7 @@ type Attribute interface {
Equals(o Attribute) bool
AttributeType() AttributeType
QuoteType() AttributeQuoteType
Clone() Attribute
}

type attribute struct {
Expand Down Expand Up @@ -120,6 +129,10 @@ func (na *NamedAttribute) AsciiDocString() string {
return AttributeAsciiDocString(na.Val)
}

func (na *NamedAttribute) Clone() Attribute {
return &NamedAttribute{attribute: na.attribute, Name: na.Name, Val: na.Val.Clone(), Quote: na.Quote}
}

func (na *NamedAttribute) Equals(oa Attribute) bool {
ona, ok := oa.(*NamedAttribute)
if !ok {
Expand Down Expand Up @@ -193,6 +206,10 @@ func (pa *PositionalAttribute) AsciiDocString() string {
return AttributeAsciiDocString(pa.Val)
}

func (pa *PositionalAttribute) Clone() Attribute {
return &PositionalAttribute{attribute: pa.attribute, Offset: pa.Offset, ImpliedName: pa.ImpliedName, Val: pa.Val.Clone()}
}

type TitleAttribute struct {
attribute

Expand Down Expand Up @@ -243,6 +260,10 @@ func (ta *TitleAttribute) AsciiDocString() string {
return AttributeAsciiDocString(ta.Val)
}

func (ta *TitleAttribute) Clone() Attribute {
return &TitleAttribute{attribute: ta.attribute, Val: ta.Val.Clone()}
}

type AttributeReference interface {
HasPosition
Element
Expand Down Expand Up @@ -272,6 +293,10 @@ func (UserAttributeReference) Type() ElementType {
return ElementTypeInline
}

func (uaf UserAttributeReference) Clone() Element {
return &UserAttributeReference{position: uaf.position, raw: uaf.raw, Value: uaf.Value}
}

func NewAttributeReference(name string) AttributeReference {
if isCharacterReplacement(name) {
return &CharacterReplacementReference{Value: name}
Expand Down Expand Up @@ -335,24 +360,28 @@ var characterReplacementAttributes = map[string]string{

type CharacterReplacementReference UserAttributeReference

func (uar *CharacterReplacementReference) Name() string {
return uar.Value
func (crr *CharacterReplacementReference) Name() string {
return crr.Value
}

func (CharacterReplacementReference) Type() ElementType {
return ElementTypeInline
}

func (uar *CharacterReplacementReference) Equals(e Element) bool {
func (crr *CharacterReplacementReference) Equals(e Element) bool {
ouar, ok := e.(*CharacterReplacementReference)
if !ok {
return false
}
return ouar.Value == uar.Value
return ouar.Value == crr.Value
}

func (crr CharacterReplacementReference) ReplacementValue() string {
return characterReplacementAttributes[crr.Value]
}

func (uar CharacterReplacementReference) ReplacementValue() string {
return characterReplacementAttributes[uar.Value]
func (crr CharacterReplacementReference) Clone() Element {
return &CharacterReplacementReference{position: crr.position, raw: crr.raw, Value: crr.Value}
}

func isCharacterReplacement(s string) bool {
Expand Down
6 changes: 6 additions & 0 deletions asciidoc/attribute_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ func (an AttributeNames) Equals(oan AttributeNames) bool {
return true
}

func (an AttributeNames) Clone() []AttributeName {
oa := make([]AttributeName, len(an))
copy(oa, an)
return oa
}

func attributeNameToType(name AttributeName) AttributeType {
switch name {
case AttributeNameAlternateText:
Expand Down
14 changes: 12 additions & 2 deletions asciidoc/attributes.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,16 @@ func (a *AttributeList) GetAttributeByName(name AttributeName) *NamedAttribute {
return nil
}

func (a AttributeList) traverse(parent Parent, yield func(Parent, Parent) bool) bool {
func (a AttributeList) traverse(parent ParentElement, yield func(ParentElement, Parent) bool) bool {
for _, attr := range a.Attributes() {
switch attr := attr.(type) {
case *AnchorAttribute:
if !yield(parent, &attr.ID) {
return false
}
if !yield(parent, &attr.Label) {
return false
}

case *NamedAttribute:
if !yield(parent, attr) {
return false
Expand All @@ -145,3 +147,11 @@ func (a AttributeList) traverse(parent Parent, yield func(Parent, Parent) bool)
}
return true
}

func (a AttributeList) Clone() (oa AttributeList) {
oa = make(AttributeList, len(a))
for i, attr := range a {
oa[i] = attr.Clone()
}
return
}
9 changes: 7 additions & 2 deletions asciidoc/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@ func (BlockAttributes) Type() ElementType {
return ElementTypeAttributes
}

func (uar *BlockAttributes) Equals(e Element) bool {
func (ba *BlockAttributes) Equals(e Element) bool {
ouar, ok := e.(*BlockAttributes)
if !ok {
return false
}
return uar.AttributeList.Equals(ouar.AttributeList)
return ba.AttributeList.Equals(ouar.AttributeList)
}

func (ba *BlockAttributes) Clone() Element {
return &BlockAttributes{AttributeList: ba.AttributeList.Clone()}

}
22 changes: 18 additions & 4 deletions asciidoc/bold.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,21 @@ func (b *Bold) Equals(e Element) bool {
return b.Elements.Equals(ob.Elements)
}

func (b *Bold) Traverse(parent Parent) iter.Seq2[Parent, Parent] {
return func(yield func(Parent, Parent) bool) {
func (b *Bold) Traverse(parent ParentElement) iter.Seq2[ParentElement, Parent] {
return func(yield func(ParentElement, Parent) bool) {
if !b.AttributeList.traverse(b, yield) {
return
}
}
}

var _ ParentElement = &Bold{}
var _ Traverser = &Bold{}

func (b *Bold) Clone() Element {
return &Bold{position: b.position, raw: b.raw, AttributeList: b.AttributeList.Clone(), Elements: b.Elements.Clone()}
}

type DoubleBold struct {
position
raw
Expand Down Expand Up @@ -72,10 +79,17 @@ func (db *DoubleBold) Equals(e Element) bool {
return db.Elements.Equals(ob.Elements)
}

func (db *DoubleBold) Traverse(parent Parent) iter.Seq2[Parent, Parent] {
return func(yield func(Parent, Parent) bool) {
func (db *DoubleBold) Traverse(parent ParentElement) iter.Seq2[ParentElement, Parent] {
return func(yield func(ParentElement, Parent) bool) {
if !db.AttributeList.traverse(db, yield) {
return
}
}
}

func (db *DoubleBold) Clone() Element {
return &Bold{position: db.position, raw: db.raw, AttributeList: db.AttributeList.Clone(), Elements: db.Elements.Clone()}
}
Comment on lines +90 to +92

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The Clone() method for DoubleBold incorrectly returns a *Bold instance instead of a *DoubleBold instance. This will lead to type errors and unexpected behavior when cloning DoubleBold elements.

Suggested change
func (db *DoubleBold) Clone() Element {
return &Bold{position: db.position, raw: db.raw, AttributeList: db.AttributeList.Clone(), Elements: db.Elements.Clone()}
}
func (db *DoubleBold) Clone() Element {
return &DoubleBold{position: db.position, raw: db.raw, AttributeList: db.AttributeList.Clone(), Elements: db.Elements.Clone()}
}


var _ ParentElement = &DoubleBold{}
var _ Traverser = &DoubleBold{}
8 changes: 8 additions & 0 deletions asciidoc/break.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ func (tb *ThematicBreak) Equals(e Element) bool {
return tb.AttributeList.Equals(otb.AttributeList)
}

func (tb *ThematicBreak) Clone() Element {
return &ThematicBreak{position: tb.position, raw: tb.raw, AttributeList: tb.AttributeList.Clone()}
}

type PageBreak struct {
position
raw
Expand All @@ -45,3 +49,7 @@ func (pb *PageBreak) Equals(e Element) bool {
}
return pb.AttributeList.Equals(opb.AttributeList)
}

func (pb *PageBreak) Clone() Element {
return &PageBreak{position: pb.position, raw: pb.raw, AttributeList: pb.AttributeList.Clone()}
}
18 changes: 18 additions & 0 deletions asciidoc/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ func (tcf *TableColumn) Equals(otcf *TableColumn) bool {
func (tcf *TableColumn) IsDefault() bool {
return tcf.HorizontalAlign.Value == TableCellHorizontalAlignLeft && tcf.VerticalAlign.Value == TableCellVerticalAlignTop && tcf.Width.Value == 1 && tcf.Percentage.Value == 0 && tcf.Style.Value == TableCellStyleDefault
}
func (tcf *TableColumn) Clone() *TableColumn {
return &TableColumn{
Multiplier: tcf.Multiplier,
HorizontalAlign: tcf.HorizontalAlign,
VerticalAlign: tcf.VerticalAlign,
Width: tcf.Width,
Percentage: tcf.Percentage,
Style: tcf.Style,
}
}

func NewTableColumn() *TableColumn {
return &TableColumn{
Expand Down Expand Up @@ -145,6 +155,14 @@ func (TableColumnsAttribute) QuoteType() AttributeQuoteType {
return AttributeQuoteTypeDouble
}

func (ta *TableColumnsAttribute) Clone() Attribute {
cols := make([]*TableColumn, len(ta.Columns))
for i, col := range ta.Columns {
cols[i] = col.Clone()
}
return &TableColumnsAttribute{attribute: ta.attribute, Columns: cols}
}

func parseColumnAttribute(a *NamedAttribute) (*TableColumnsAttribute, error) {
cs := strings.TrimSpace(ValueToString(a.Value()))
if len(cs) == 0 { // An empty cols attribute should be ignored
Expand Down
8 changes: 8 additions & 0 deletions asciidoc/comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ func (slc *SingleLineComment) Equals(e Element) bool {
return slc.Value == oslc.Value
}

func (slc *SingleLineComment) Clone() Element {
return &SingleLineComment{position: slc.position, raw: slc.raw, Value: slc.Value}
}

type MultiLineComment struct {
position
raw
Expand All @@ -49,3 +53,7 @@ func (mlc *MultiLineComment) Equals(e Element) bool {
}
return omlc.LineList.Equals(mlc.LineList)
}

func (mlc *MultiLineComment) Clone() Element {
return &MultiLineComment{position: mlc.position, raw: mlc.raw, Delimiter: mlc.Delimiter, LineList: mlc.LineList.Clone()}
}
Loading