a11yist/app/lib/docx/document.rb
david 63fc206c27
Some checks failed
/ Run tests (push) Successful in 8m56s
/ Run system tests (push) Failing after 1h0m48s
/ Build, push and deploy image (push) Successful in 7m47s
A lot :)
2024-09-05 22:54:38 +02:00

133 lines
4.1 KiB
Ruby

module Docx
class Document
include OpenXml::Docx::Elements
def initialize
end
def generate
yield(self)
tmpfile = Tempfile.new("#{Time.current.to_f}.xlsx", Rails.root.join("tmp"))
_document.save(tmpfile.path)
tmpfile.path
end
def heading1(text)
paragraph = create_paragraph(text)
paragraph.paragraph_style = "Heading 1"
_document.document << paragraph
end
def heading2(text)
paragraph = create_paragraph(text)
paragraph.paragraph_style = "Heading 2"
_document.document << paragraph
end
def heading3(text)
paragraph = create_paragraph(text)
paragraph.paragraph_style = "Heading 3"
_document.document << paragraph
end
def paragraph(text)
html = Nokogiri::HTML5.fragment(text)
html.search(".trix-content").each do |node|
node.children.each do |child|
Rails.logger.debug { "content kids: #{child.class}: #{child.name} (#{child.children.size}): #{child.text}" }
case child
when Nokogiri::XML::Text
paragraph = create_paragraph(child.text)
_document.document << paragraph
when Nokogiri::XML::Element
case child.name
when "h1"
paragraph = create_paragraph(child.text)
paragraph.paragraph_style = "Heading 3"
when "div"
paragraph = Paragraph.new
paragraph.paragraph_style = "Body Text"
child.children.each do |node|
Rails.logger.debug { "div kids: #{node.class}: #{node.name} (#{node.children.size}): #{node.text}" }
case node.name
when "strong"
paragraph << create_run(node.text, bold: true)
when "em"
paragraph << create_run(node.text, italic: true)
when "del"
paragraph << create_run(node.text, strike_through: true)
when "br"
paragraph << create_run("\n")
else
paragraph << create_run(node.text)
end
end
when "ul"
# paragraph = Paragraph.new
# paragraph.paragraph_style = "Body Text"
# # Create an abstract numbering that describes a bulleted list:
# abstract_numbering = AbstractNumbering.new(0)
# # Each numbering can have multiple levels. Define the first level as a bulleted list:
# level_0 = Level.new
# level_0.level = 0
# level_0.start = 1
# level_0.number_format = :bullet
# # This is the default bullet Word uses
# level_0.level_text = "\u00B7".encode("UTF-8")
# level_0.alignment = :left
# level_0.character_style.font.ascii = "Symbol"
# level_0.character_style.font.high_ansi = "Symbol"
# level_0.character_style.font.hint = :default
# level_0.paragraph_style.indentation.left = 720
# level_0.paragraph_style.indentation.hanging = 360
# abstract_numbering << level_0
# _document.numbering << abstract_numbering
when "ol"
else
paragraph = create_paragraph(child.text)
paragraph.paragraph_style = "Body Text"
end
_document.document << paragraph
end
end
end
end
private
def create_run(content, bold: false, italic: false, strike_through: false)
text = Text.new(content)
text.space = :preserve
run = Run.new
run.bold = bold
run.italics = italic
run.strikethrough = strike_through
run << text
run
end
def create_paragraph(content)
text = case content
when String
Text.new(content)
when ActionText::RichText
Text.new(content.to_plain_text)
else
Text.new(content.to_s)
end
run = Run.new
run << text
paragraph = Paragraph.new
paragraph << run
paragraph
end
def _document
@_document ||= OpenXml::Docx::Package.new
end
end
end