Skip to content

Commit

Permalink
fix: senny#198 WordML MergeFields remove parent and crashes if multip…
Browse files Browse the repository at this point in the history
…le fields share parent
  • Loading branch information
Amnesthesia committed Jan 16, 2025
1 parent a301dd3 commit 491ac8f
Showing 1 changed file with 39 additions and 3 deletions.
42 changes: 39 additions & 3 deletions lib/sablon/content.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,44 @@ def append_to(paragraph, display_node, env)
add_siblings_to(display_node.parent, pr_tag)
display_node.parent.remove
else
add_siblings_to(paragraph)
paragraph.remove
# Insert a new paragraph before this paragraph
# and add nodes to that paragraph instead. It's inserted
# before so that the order is preserved, otherwise when
# fields are processed, they will be in reverse order if
# each is added as the next sibling of the paragraph.
dummy_paragraph = Nokogiri::XML::Node.new("w:p", display_node.document)

paragraph.add_previous_sibling dummy_paragraph

# Copy rPr tag if any
pr_tag = display_node.parent.at_xpath('./w:rPr')
add_siblings_to(dummy_paragraph, pr_tag)

# Get all merge fields for the parent paragraph
merge_fields = get_merge_fields(paragraph)

# Find merge field this belongs to:
current_field_idx = merge_fields.find_index { |child| child.any? { display_node.ancestors.include?(_1) } }

# Only remove the paragraph parent if it doesn't contain any more merge fields,
# otherwise leave it in place so those merge fields dont lose their parent
paragraph.remove if current_field_idx == merge_fields.length - 1
end
end

# Get all merge fields in a node
def get_merge_fields(node)
merge_fields = []

inside_field = false
node.children.each do |field|
if field.children.any? { |child| child.name == 'fldChar' && child['w:fldCharType'] == 'begin' }
merge_fields << [field]
inside_field = true
elsif inside_field
merge_fields.last << field
inside_field = false if field.children.any? { |child| child.name == 'fldChar' && child['w:fldCharType'] == 'end' }
end
end
end

Expand Down Expand Up @@ -143,7 +179,7 @@ def add_siblings_to(node, rpr_tag = nil)
end
end

# Merges the provided properties into the run properties of the
# Merges the provided properties into the run proprties of the
# node passed in. Properties are only added if they are not already
# defined on the node itself.
def merge_rpr_tags(node, props)
Expand Down

0 comments on commit 491ac8f

Please sign in to comment.