Module: Uniword::Builder::RunUtils
- Defined in:
- lib/uniword/builder/run_utils.rb
Overview
Shared run utilities used by both ParagraphBuilder (build-time) and Reconciler::Helpers (reconcile-time).
Provides canonical implementations of run classification and merging. Both modules delegate here to ensure identical behavior.
Class Method Summary collapse
-
.empty_run?(run) ⇒ Boolean
Whether a run contains no renderable content.
-
.merge_text(target, source) ⇒ Object
Merge source run's text into target run.
-
.mergeable?(existing, incoming) ⇒ Boolean
Whether two text-only runs can be merged.
-
.properties_match?(a, b) ⇒ Boolean
Whether two runs have identical formatting (RunProperties).
-
.text_only_run?(run) ⇒ Boolean
Whether a run contains only text (no structural elements).
Class Method Details
.empty_run?(run) ⇒ Boolean
Whether a run contains no renderable content.
A run is empty only if it has no text content and no structural elements (breaks, tabs, drawings, field chars, etc.).
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/uniword/builder/run_utils.rb', line 17 def empty_run?(run) return false if Array(run.break).any? return false if run.tab return false if run.drawings&.any? return false if run.pictures&.any? return false if run.alternate_content return false if run.footnote_reference return false if run.endnote_reference return false if run.field_char return false if run.instr_text return false if run.position_tab return false if run.del_text return false if run.no_break_hyphen return false if run.sym return false if run.last_rendered_page_break return false if run.separator_char return false if run.continuation_separator_char run.text_string.empty? end |
.merge_text(target, source) ⇒ Object
Merge source run's text into target run.
Handles xml:space="preserve" for whitespace-sensitive content.
83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/uniword/builder/run_utils.rb', line 83 def merge_text(target, source) if Array(source.text).any? existing = target.text_string appended = source.text_string combined = existing + appended new_text = Wordprocessingml::Text.new(content: combined) if Wordprocessingml::Text.preserve_whitespace?(combined) new_text.xml_space = "preserve" end target.text = new_text end end |
.mergeable?(existing, incoming) ⇒ Boolean
Whether two text-only runs can be merged.
Runs can be merged if both are text-only with identical formatting.
73 74 75 76 77 78 |
# File 'lib/uniword/builder/run_utils.rb', line 73 def mergeable?(existing, incoming) return false unless text_only_run?(existing) && text_only_run?(incoming) return false if incoming.text_string.empty? properties_match?(existing, incoming) end |
.properties_match?(a, b) ⇒ Boolean
Whether two runs have identical formatting (RunProperties).
61 62 63 64 65 66 67 68 |
# File 'lib/uniword/builder/run_utils.rb', line 61 def properties_match?(a, b) rpr_a = a.properties rpr_b = b.properties return true if rpr_a.nil? && rpr_b.nil? return false if rpr_a.nil? || rpr_b.nil? rpr_a.to_xml == rpr_b.to_xml end |
.text_only_run?(run) ⇒ Boolean
Whether a run contains only text (no structural elements).
Runs with drawings, breaks, tabs, field chars, etc. are NOT text-only and should never be merged with other runs.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/uniword/builder/run_utils.rb', line 42 def text_only_run?(run) return false if run.drawings&.any? return false if run.pictures&.any? return false if run.alternate_content return false if run.footnote_reference return false if run.endnote_reference return false if run.field_char return false if run.instr_text return false if run.sym return false if Array(run.break).any? return false if run.tab return false if run.position_tab return false if run.no_break_hyphen return false if run.del_text true end |