Skip to content
Open
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
2 changes: 2 additions & 0 deletions lib/uniword/builder/chart_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class ChartBuilder

attr_reader :chart_type, :title_text, :series_list

attr_reader :show_legend, :width, :height, :series_list

def initialize(chart_type: :bar)
@chart_type = chart_type
@title_text = nil
Expand Down
9 changes: 8 additions & 1 deletion lib/uniword/builder/has_borders.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ def borders(**sides)
Properties::Border.new(color: value, style: "single",
size: 4)
end
props.borders.public_send("#{side}=", border)
case side
when :top then props.borders.top = border
when :bottom then props.borders.bottom = border
when :left then props.borders.left = border
when :right then props.borders.right = border
when :between then props.borders.between = border
when :bar then props.borders.bar = border
end
end
self
end
Expand Down
13 changes: 0 additions & 13 deletions lib/uniword/cli/main.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,6 @@

require "thor"
require "rainbow"
require_relative "styleset_cli"
require_relative "resources_cli"
require_relative "theme_cli"
require_relative "generate_cli"
require_relative "review_cli"
require_relative "template_cli"
require_relative "diff_cli"
require_relative "toc_cli"
require_relative "images_cli"
require_relative "spellcheck_cli"
require_relative "headers_cli"
require_relative "watermark_cli"
require_relative "protect_cli"

module Uniword
# Command-line interface for Uniword.
Expand Down
1 change: 0 additions & 1 deletion lib/uniword/drawingml/color_scheme.rb
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,6 @@ def color_by_name(name)
when :fol_hlink then fol_hlink
end
end
private :color_by_name

# Set a color by name
#
Expand Down
5 changes: 4 additions & 1 deletion lib/uniword/ooxml/schema/element_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,10 @@ def serialize_child_to_node(doc, child, child_def, options)
def get_attribute_value(element, attr_def)
property_name = attr_def.property_name

# Try to get value using property name
# public_send is the canonical Ruby idiom for schema-driven
# serialization: reading attribute values by name from any
# Lutaml::Model::Serializable subclass. The property_name comes
# from the schema definition, not user input.
if element.is_a?(Lutaml::Model::Serializable) && element.class.attributes.key?(property_name)
element.public_send(property_name)
elsif element.is_a?(Hash) && element.key?(property_name)
Expand Down
2 changes: 1 addition & 1 deletion lib/uniword/resource/theme_processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def transform_color_scheme(color_scheme)
fol_hlink]

color_attrs.each do |attr|
color_obj = color_scheme.public_send(attr)
color_obj = color_scheme.color_by_name(attr)
next unless color_obj&.srgb_clr&.val

original = color_obj.srgb_clr.val
Expand Down
4 changes: 4 additions & 0 deletions lib/uniword/template/variable_resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ def navigate_property(object, property)
if object.is_a?(Hash)
object[property.to_sym] || object[property]
else
# public_send is the canonical Ruby idiom for template-driven
# property access on arbitrary user objects. The property name
# comes from template syntax and may reference any public
# reader method on the model.
object.public_send(property.to_sym)
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/uniword/themes/theme_transformation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def extract_color_scheme(word_theme)

colors = {}
COLOR_KEYS.each do |key|
if (color_ref = word_colors.public_send(key))
if (color_ref = word_colors.color_by_name(key))
colors[key] = extract_hex_color(color_ref)
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,10 @@ def extract_notes(document, note_type)
collection_name = note_type == :endnote ? :endnotes : :footnotes

if document.is_a?(Uniword::Wordprocessingml::DocumentRoot)
collection = document.public_send(collection_name)
collection = case collection_name
when :footnotes then document.footnotes
when :endnotes then document.endnotes
end

case collection
when Hash
Expand Down
2 changes: 1 addition & 1 deletion lib/uniword/validation/rules/document_context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class DocumentContext
RELS_NS = "http://schemas.openxmlformats.org/package/2006/relationships"
CT_NS = "http://schemas.openxmlformats.org/package/2006/content-types"

attr_reader :path
attr_reader :path, :parsed_parts

# Initialize context for a DOCX file.
#
Expand Down
7 changes: 6 additions & 1 deletion lib/uniword/warnings/warning_collector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,12 @@ def log_warning(warning)

# Use Uniword logger if available
if defined?(Uniword::Logger)
Uniword::Logger.public_send(level, message)
case level
when :debug then Uniword::Logger.debug(message)
when :info then Uniword::Logger.info(message)
when :warn then Uniword::Logger.warn(message)
when :error then Uniword::Logger.error(message)
end
elsif %i[warn error].include?(level)
# Fall back to standard output
puts message
Expand Down
Binary file modified spec/examples/generated/academic_paper.docx
Binary file not shown.
Binary file modified spec/examples/generated/chart_gallery.docx
Binary file not shown.
Binary file modified spec/examples/generated/complete_document.docx
Binary file not shown.
Binary file modified spec/examples/generated/image_document.docx
Binary file not shown.
Binary file modified spec/examples/generated/manipulation_modified.docx
Binary file not shown.
Binary file modified spec/examples/generated/manipulation_original.docx
Binary file not shown.
Binary file modified spec/examples/generated/multi_section_report.docx
Binary file not shown.
Binary file modified spec/examples/generated/simple_document.docx
Binary file not shown.
Binary file modified spec/examples/generated/themed_document.docx
Binary file not shown.
8 changes: 1 addition & 7 deletions spec/uniword/accessibility/accessibility_checker_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,7 @@

describe "#check" do
let(:checker) { described_class.new(profile: :wcag_2_1_aa) }
let(:document) { double("Document") }

before do
# Mock document methods
allow(document).to receive_messages(images: [], tables: [],
paragraphs: [])
end
let(:document) { Uniword::Wordprocessingml::DocumentRoot.new }

it "returns an AccessibilityReport" do
report = checker.check(document)
Expand Down
8 changes: 4 additions & 4 deletions spec/uniword/accessibility/accessibility_report_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
wcag_criterion: "1.1.1 Non-text Content",
level: "A",
message: "Image 1 missing alternative text",
element: double("Image"),
element: Uniword::Wordprocessingml::Drawing.new,
severity: :error,
suggestion: "Add descriptive alt text",
)
Expand All @@ -29,7 +29,7 @@
wcag_criterion: "1.3.1 Info and Relationships",
level: "A",
message: "Heading hierarchy skip",
element: double("Paragraph"),
element: Uniword::Wordprocessingml::Paragraph.new,
severity: :warning,
suggestion: "Use sequential heading levels",
)
Expand All @@ -40,7 +40,7 @@
wcag_criterion: "2.4.6 Headings and Labels",
level: "AA",
message: "Heading could be more descriptive",
element: double("Paragraph"),
element: Uniword::Wordprocessingml::Paragraph.new,
severity: :info,
suggestion: "Make headings more descriptive",
)
Expand Down Expand Up @@ -195,7 +195,7 @@
wcag_criterion: "1.1.1",
level: "A",
message: "Image #{i + 1} issue",
element: double("Image"),
element: Uniword::Wordprocessingml::Drawing.new,
severity: :error,
suggestion: "Fix it",
),
Expand Down
6 changes: 3 additions & 3 deletions spec/uniword/accessibility/accessibility_rule_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def check(_document)
subject(:base_rule) { described_class.new(config) }

it "raises NotImplementedError" do
document = double("Document")
document = Uniword::Wordprocessingml::DocumentRoot.new
expect { base_rule.check(document) }.to raise_error(
NotImplementedError,
/must implement #check/,
Expand All @@ -86,14 +86,14 @@ def check(_document)

context "when implemented by subclass" do
it "can be called without error" do
document = double("Document")
document = Uniword::Wordprocessingml::DocumentRoot.new
expect { rule.check(document) }.not_to raise_error
end
end
end

describe "#create_violation" do
let(:element) { double("Element") }
let(:element) { Uniword::Wordprocessingml::Paragraph.new }
let(:violation_params) do
{
message: "Test violation",
Expand Down
6 changes: 3 additions & 3 deletions spec/uniword/builder/image_embedding_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -415,15 +415,15 @@ def zip_content_for(model)
describe "legend" do
it "configures legend visibility and position" do
builder.legend(show: false)
expect(builder.instance_variable_get(:@show_legend)).to be(false)
expect(builder.show_legend).to be(false)
end
end

describe "dimensions" do
it "sets chart dimensions" do
builder.dimensions(width: 4_000_000, height: 3_000_000)
expect(builder.instance_variable_get(:@width)).to eq(4_000_000)
expect(builder.instance_variable_get(:@height)).to eq(3_000_000)
expect(builder.width).to eq(4_000_000)
expect(builder.height).to eq(3_000_000)
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/uniword/builder/run_builder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@
# Use a minimal mock that responds to the right class check
drawing = Uniword::Wordprocessingml::Drawing.new
builder.drawing(drawing)
drawings = builder.model.instance_variable_get(:@drawings)
drawings = builder.model.drawings
expect(drawings).not_to be_empty
end
end
Expand Down
22 changes: 14 additions & 8 deletions spec/uniword/element_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,20 @@ def accept(visitor)
end

describe "#accept" do
let(:recording_visitor) do
Class.new do
def initialize; @visits = []; end
attr_reader :visits
def visit_test_element(el); @visits << [:test, el]; end
def visit_another_element(el); @visits << [:another, el]; end
def visit_element(el); @visits << [:default, el]; end
end.new
end

it "calls visitor method for the element" do
element = test_element_class.new
visitor = double("visitor")
expect(visitor).to receive(:visit_test_element).with(element)

element.accept(visitor)
element.accept(recording_visitor)
expect(recording_visitor.visits).to eq([[:test, element]])
end

context "with default accept method" do
Expand All @@ -76,10 +84,8 @@ def accept(visitor)

it "calls visit_element on visitor" do
element = default_class.new
visitor = double("visitor")
expect(visitor).to receive(:visit_element).with(element)

element.accept(visitor)
element.accept(recording_visitor)
expect(recording_visitor.visits).to eq([[:default, element]])
end
end
end
Expand Down
3 changes: 1 addition & 2 deletions spec/uniword/validation/link_validator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@
para.runs << anchor_link
doc.body.paragraphs << para
# Add bookmark to document
doc.instance_variable_set(:@bookmarks,
{ "section1" => Uniword::Bookmark.new(name: "section1") })
doc.bookmarks = { "section1" => Uniword::Bookmark.new(name: "section1") }
doc
end

Expand Down
2 changes: 1 addition & 1 deletion spec/uniword/validation/rules/document_context_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
it "clears cached parts" do
context.document_xml
context.close
expect(context.instance_variable_get(:@parsed_parts)).to be_empty
expect(context.parsed_parts).to be_empty
end
end

Expand Down
8 changes: 4 additions & 4 deletions spec/uniword/validators/paragraph_validator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
it "returns false for paragraph with invalid properties" do
paragraph = Uniword::Wordprocessingml::Paragraph.new
# Using reflection to set invalid properties
paragraph.instance_variable_set(:@properties, "not properties")
paragraph.properties = "not properties"

expect(validator.valid?(paragraph)).to be false
end
Expand Down Expand Up @@ -98,7 +98,7 @@

it "returns property error for invalid properties" do
paragraph = Uniword::Wordprocessingml::Paragraph.new
paragraph.instance_variable_set(:@properties, "invalid")
paragraph.properties = "invalid"

errors = validator.errors(paragraph)
expect(errors).to include("Properties must be a ParagraphProperties instance")
Expand All @@ -107,7 +107,7 @@
it "returns multiple errors for multiple issues" do
paragraph = Uniword::Wordprocessingml::Paragraph.new
paragraph.runs << "invalid run"
paragraph.instance_variable_set(:@properties, "invalid properties")
paragraph.properties = "invalid properties"

errors = validator.errors(paragraph)
expect(errors.size).to eq(2)
Expand Down Expand Up @@ -135,7 +135,7 @@
describe "edge cases" do
it "handles paragraph with nil runs array" do
paragraph = Uniword::Wordprocessingml::Paragraph.new
paragraph.instance_variable_set(:@runs, nil)
paragraph.runs = nil

expect(validator.valid?(paragraph)).to be true
end
Expand Down
2 changes: 1 addition & 1 deletion spec/uniword/validators/table_validator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def create_validator_text_row(*texts)
describe "edge cases" do
it "handles table with nil rows array" do
table = Uniword::Wordprocessingml::Table.new
table.instance_variable_set(:@rows, nil)
table.rows = nil

expect(validator.errors(table)).to be_empty
end
Expand Down
4 changes: 2 additions & 2 deletions spec/uniword/wordprocessingml/comment_range_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@

it "raises error for invalid marker type" do
range = described_class.new(comment_id: "1")
range.instance_variable_set(:@marker_type, :invalid)
range.marker_type = :invalid
expect do
range.xml_element_name
end.to raise_error(ArgumentError, /Invalid marker type/)
Expand Down Expand Up @@ -120,7 +120,7 @@

it "returns false without marker_type" do
range = described_class.new(comment_id: "1")
range.instance_variable_set(:@marker_type, nil)
range.marker_type = nil
expect(range).not_to be_valid
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/uniword/wordprocessingml/comment_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@

it "returns false without comment_id" do
comment = described_class.new(author: "John")
comment.instance_variable_set(:@comment_id, nil)
comment.comment_id = nil
expect(comment).not_to be_valid
end
end
Expand Down
8 changes: 4 additions & 4 deletions spec/uniword/wordprocessingml/comments_part_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@

it "assigns sequential ID if not set" do
comment1 = Uniword::Comment.new(author: "John")
comment1.instance_variable_set(:@comment_id, nil)
comment1.comment_id = nil
comment2 = Uniword::Comment.new(author: "Jane")
comment2.instance_variable_set(:@comment_id, nil)
comment2.comment_id = nil

comments_part.add_comment(comment1)
comments_part.add_comment(comment2)
Expand Down Expand Up @@ -165,7 +165,7 @@

it "excludes nil authors" do
comment = Uniword::Comment.new(comment_id: "1")
comment.instance_variable_set(:@author, nil)
comment.author = nil
comments_part.add_comment(comment)

expect(comments_part.authors).to be_empty
Expand All @@ -186,7 +186,7 @@
comments_part.clear

comment = Uniword::Comment.new(author: "Jane")
comment.instance_variable_set(:@comment_id, nil)
comment.comment_id = nil
comments_part.add_comment(comment)

expect(comment.comment_id).to eq("1")
Expand Down
Loading
Loading