All checks were successful
CI Pipeline / build (pull_request) Successful in 13s
72 lines
2.0 KiB
Ruby
72 lines
2.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Notare
|
|
module Xml
|
|
class Numbering
|
|
NAMESPACE = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
|
BULLET_CHARS = ["•", "○", "■"].freeze
|
|
NUMBER_FORMATS = %w[decimal lowerLetter lowerRoman].freeze
|
|
|
|
def initialize(lists)
|
|
@lists = lists
|
|
end
|
|
|
|
def to_xml
|
|
builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
|
|
xml.numbering("xmlns:w" => NAMESPACE) do
|
|
xml.parent.namespace = xml.parent.namespace_definitions.find { |ns| ns.prefix == "w" }
|
|
|
|
@lists.each do |list|
|
|
render_abstract_num(xml, list)
|
|
|
|
render_num(xml, list)
|
|
end
|
|
end
|
|
end
|
|
builder.to_xml
|
|
end
|
|
|
|
private
|
|
|
|
def render_abstract_num(xml, list)
|
|
xml["w"].abstractNum("w:abstractNumId" => list.num_id.to_s) do
|
|
9.times do |level|
|
|
xml["w"].lvl("w:ilvl" => level.to_s) do
|
|
xml["w"].start("w:val" => "1")
|
|
xml["w"].numFmt("w:val" => num_format_for_level(list.type, level))
|
|
xml["w"].lvlText("w:val" => lvl_text_for_level(list.type, level))
|
|
xml["w"].lvlJc("w:val" => "left")
|
|
xml["w"].pPr do
|
|
left = 720 * (level + 1)
|
|
xml["w"].ind("w:left" => left.to_s, "w:hanging" => "360")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def render_num(xml, list)
|
|
xml["w"].num("w:numId" => list.num_id.to_s) do
|
|
xml["w"].abstractNumId("w:val" => list.num_id.to_s)
|
|
end
|
|
end
|
|
|
|
def num_format_for_level(type, level)
|
|
if type == :bullet
|
|
"bullet"
|
|
else
|
|
NUMBER_FORMATS[level % NUMBER_FORMATS.length]
|
|
end
|
|
end
|
|
|
|
def lvl_text_for_level(type, level)
|
|
if type == :bullet
|
|
BULLET_CHARS[level % BULLET_CHARS.length]
|
|
else
|
|
"%#{level + 1}."
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|