Author SHA1 Message Date
mathias234 022c52eef6 fix: Preserve bullet lists in desktop Word
CI Pipeline / build (pull_request) Successful in 35s
2026-10-08 14:50:22 +02:00
mathias234 f3e566364f Implement spacing before/after for paragraphs
CI Pipeline / build (push) Successful in 47s
2026-04-09 14:46:33 +02:00
6 changed files with 34 additions and 12 deletions
+4 -2
View File
@@ -2,8 +2,10 @@
module Notare module Notare
module Builder module Builder
def p(text = nil, style: nil, &block) def p(text = nil, style: nil, spacing_before: nil, spacing_after: nil, &block)
para = Nodes::Paragraph.new(style: resolve_style(style)) para = Nodes::Paragraph.new(style: resolve_style(style),
spacing_before: spacing_before,
spacing_after: spacing_after)
if block if block
with_target(para, &block) with_target(para, &block)
elsif text elsif text
+4 -2
View File
@@ -3,12 +3,14 @@
module Notare module Notare
module Nodes module Nodes
class Paragraph < Base class Paragraph < Base
attr_reader :runs, :style attr_reader :runs, :style, :spacing_before, :spacing_after
def initialize(runs = [], style: nil) def initialize(runs = [], style: nil, spacing_before: nil, spacing_after: nil)
super() super()
@runs = runs @runs = runs
@style = style @style = style
@spacing_before = spacing_before
@spacing_after = spacing_after
end end
def add_run(run) def add_run(run)
+1 -1
View File
@@ -1,5 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
module Notare module Notare
VERSION = "0.0.7" VERSION = "0.0.8"
end end
+11 -2
View File
@@ -52,9 +52,18 @@ module Notare
def render_paragraph(xml, para) def render_paragraph(xml, para)
xml["w"].p do xml["w"].p do
if para.style has_style = para.style
has_spacing = para.spacing_before || para.spacing_after
if has_style || has_spacing
xml["w"].pPr do xml["w"].pPr do
xml["w"].pStyle("w:val" => para.style.style_id) xml["w"].pStyle("w:val" => para.style.style_id) if has_style
if has_spacing
spacing_attrs = {}
spacing_attrs["w:before"] = para.spacing_before.to_s if para.spacing_before
spacing_attrs["w:after"] = para.spacing_after.to_s if para.spacing_after
xml["w"].spacing(spacing_attrs)
end
end end
end end
para.runs.each { |run| render_run(xml, run) } para.runs.each { |run| render_run(xml, run) }
+10 -5
View File
@@ -16,11 +16,8 @@ module Notare
xml.numbering("xmlns:w" => NAMESPACE) do xml.numbering("xmlns:w" => NAMESPACE) do
xml.parent.namespace = xml.parent.namespace_definitions.find { |ns| ns.prefix == "w" } xml.parent.namespace = xml.parent.namespace_definitions.find { |ns| ns.prefix == "w" }
@lists.each do |list| render_abstract_nums(xml)
render_abstract_num(xml, list) render_nums(xml)
render_num(xml, list)
end
end end
end end
builder.to_xml builder.to_xml
@@ -28,6 +25,14 @@ module Notare
private private
def render_abstract_nums(xml)
@lists.each { |list| render_abstract_num(xml, list) }
end
def render_nums(xml)
@lists.each { |list| render_num(xml, list) }
end
def render_abstract_num(xml, list) def render_abstract_num(xml, list)
xml["w"].abstractNum("w:abstractNumId" => list.num_id.to_s) do xml["w"].abstractNum("w:abstractNumId" => list.num_id.to_s) do
9.times do |level| 9.times do |level|
+4
View File
@@ -115,6 +115,10 @@ class ListTest < Minitest::Test
assert_includes doc_xml, "List 1 Item 1" assert_includes doc_xml, "List 1 Item 1"
assert_includes doc_xml, "List 2 Item 1" assert_includes doc_xml, "List 2 Item 1"
assert_includes doc_xml, "Separator paragraph" assert_includes doc_xml, "Separator paragraph"
numbering_xml = Nokogiri::XML(xml_files["word/numbering.xml"])
child_names = numbering_xml.root.element_children.map(&:name)
assert_equal %w[abstractNum abstractNum num num], child_names
end end
def test_mixed_list_types def test_mixed_list_types