omml 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/rake.yml +22 -0
- data/.github/workflows/release.yml +23 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +25 -0
- data/.rubocop_todo.yml +19 -0
- data/CLAUDE.md +64 -0
- data/Gemfile +11 -7
- data/README.adoc +222 -4
- data/Rakefile +3 -3
- data/bin/console +3 -3
- data/lib/omml/configuration/adapter.rb +22 -0
- data/lib/omml/configuration/context_registry.rb +131 -0
- data/lib/omml/configuration/model_registry.rb +60 -0
- data/lib/omml/configuration/type_resolver.rb +47 -0
- data/lib/omml/configuration.rb +25 -0
- data/lib/omml/errors/base_error.rb +8 -0
- data/lib/omml/errors/invalid_xml_error.rb +8 -0
- data/lib/omml/errors/missing_context_error.rb +23 -0
- data/lib/omml/errors/root_element_not_found_error.rb +11 -0
- data/lib/omml/errors/unsupported_root_element_error.rb +11 -0
- data/lib/omml/errors/xml_adapter_not_configured_error.rb +11 -0
- data/lib/omml/errors.rb +15 -0
- data/lib/omml/models/ct_acc.rb +23 -0
- data/lib/omml/models/ct_acc_pr.rb +23 -0
- data/lib/omml/models/ct_anchor.rb +60 -0
- data/lib/omml/models/ct_attr.rb +23 -0
- data/lib/omml/models/ct_bar.rb +23 -0
- data/lib/omml/models/ct_bar_pr.rb +23 -0
- data/lib/omml/models/ct_bookmark.rb +19 -0
- data/lib/omml/models/ct_bookmark_range.rb +21 -0
- data/lib/omml/models/ct_border.rb +35 -0
- data/lib/omml/models/ct_border_box.rb +24 -0
- data/lib/omml/models/ct_border_box_pr.rb +37 -0
- data/lib/omml/models/ct_box.rb +23 -0
- data/lib/omml/models/ct_box_pr.rb +31 -0
- data/lib/omml/models/ct_br.rb +21 -0
- data/lib/omml/models/ct_break_bin.rb +19 -0
- data/lib/omml/models/ct_break_bin_sub.rb +19 -0
- data/lib/omml/models/ct_calendar_type.rb +19 -0
- data/lib/omml/models/ct_char.rb +19 -0
- data/lib/omml/models/ct_color.rb +25 -0
- data/lib/omml/models/ct_control.rb +23 -0
- data/lib/omml/models/ct_ctrl_pr.rb +21 -0
- data/lib/omml/models/ct_custom_xml_pr.rb +23 -0
- data/lib/omml/models/ct_custom_xml_run.rb +27 -0
- data/lib/omml/models/ct_d.rb +23 -0
- data/lib/omml/models/ct_d_pr.rb +34 -0
- data/lib/omml/models/ct_data_binding.rb +23 -0
- data/lib/omml/models/ct_decimal_number.rb +19 -0
- data/lib/omml/models/ct_drawing.rb +23 -0
- data/lib/omml/models/ct_east_asian_layout.rb +27 -0
- data/lib/omml/models/ct_effect_extent.rb +25 -0
- data/lib/omml/models/ct_em.rb +19 -0
- data/lib/omml/models/ct_empty.rb +15 -0
- data/lib/omml/models/ct_eq_arr.rb +23 -0
- data/lib/omml/models/ct_eq_arr_pr.rb +31 -0
- data/lib/omml/models/ct_f.rb +25 -0
- data/lib/omml/models/ct_f_pr.rb +23 -0
- data/lib/omml/models/ct_f_type.rb +19 -0
- data/lib/omml/models/ct_ff_check_box.rb +29 -0
- data/lib/omml/models/ct_ff_data.rb +41 -0
- data/lib/omml/models/ct_ff_help_text.rb +21 -0
- data/lib/omml/models/ct_ff_name.rb +19 -0
- data/lib/omml/models/ct_ff_status_text.rb +21 -0
- data/lib/omml/models/ct_ff_text_input.rb +27 -0
- data/lib/omml/models/ct_ff_text_type.rb +19 -0
- data/lib/omml/models/ct_ffdd_list.rb +25 -0
- data/lib/omml/models/ct_fit_text.rb +21 -0
- data/lib/omml/models/ct_fld_char.rb +32 -0
- data/lib/omml/models/ct_fonts.rb +35 -0
- data/lib/omml/models/ct_ftn_edn_ref.rb +21 -0
- data/lib/omml/models/ct_func.rb +26 -0
- data/lib/omml/models/ct_func_pr.rb +21 -0
- data/lib/omml/models/ct_graphical_object.rb +21 -0
- data/lib/omml/models/ct_graphical_object_data.rb +19 -0
- data/lib/omml/models/ct_graphical_object_frame_locking.rb +33 -0
- data/lib/omml/models/ct_group_chr.rb +23 -0
- data/lib/omml/models/ct_group_chr_pr.rb +27 -0
- data/lib/omml/models/ct_highlight.rb +19 -0
- data/lib/omml/models/ct_hps_measure.rb +19 -0
- data/lib/omml/models/ct_hyperlink.rb +31 -0
- data/lib/omml/models/ct_inline.rb +38 -0
- data/lib/omml/models/ct_integer2.rb +19 -0
- data/lib/omml/models/ct_integer255.rb +19 -0
- data/lib/omml/models/ct_lang.rb +19 -0
- data/lib/omml/models/ct_language.rb +23 -0
- data/lib/omml/models/ct_lim_loc.rb +19 -0
- data/lib/omml/models/ct_lim_low.rb +26 -0
- data/lib/omml/models/ct_lim_low_pr.rb +21 -0
- data/lib/omml/models/ct_lim_upp.rb +25 -0
- data/lib/omml/models/ct_lim_upp_pr.rb +21 -0
- data/lib/omml/models/ct_lock.rb +19 -0
- data/lib/omml/models/ct_m.rb +23 -0
- data/lib/omml/models/ct_m_pr.rb +37 -0
- data/lib/omml/models/ct_macro_name.rb +19 -0
- data/lib/omml/models/ct_manual_break.rb +19 -0
- data/lib/omml/models/ct_markup.rb +19 -0
- data/lib/omml/models/ct_markup_range.rb +19 -0
- data/lib/omml/models/ct_math_pr.rb +53 -0
- data/lib/omml/models/ct_mc.rb +21 -0
- data/lib/omml/models/ct_mc_pr.rb +23 -0
- data/lib/omml/models/ct_mcs.rb +21 -0
- data/lib/omml/models/ct_move_bookmark.rb +21 -0
- data/lib/omml/models/ct_mr.rb +21 -0
- data/lib/omml/models/ct_nary.rb +27 -0
- data/lib/omml/models/ct_nary_pr.rb +31 -0
- data/lib/omml/models/ct_non_visual_drawing_props.rb +33 -0
- data/lib/omml/models/ct_non_visual_graphic_frame_properties.rb +24 -0
- data/lib/omml/models/ct_o_math.rb +22 -0
- data/lib/omml/models/ct_o_math_arg.rb +28 -0
- data/lib/omml/models/ct_o_math_arg_pr.rb +21 -0
- data/lib/omml/models/ct_o_math_jc.rb +19 -0
- data/lib/omml/models/ct_o_math_para.rb +26 -0
- data/lib/omml/models/ct_o_math_para_pr.rb +21 -0
- data/lib/omml/models/ct_object.rb +25 -0
- data/lib/omml/models/ct_office_art_extension.rb +19 -0
- data/lib/omml/models/ct_office_art_extension_list.rb +21 -0
- data/lib/omml/models/ct_on_off.rb +19 -0
- data/lib/omml/models/ct_p_tab.rb +23 -0
- data/lib/omml/models/ct_perm.rb +21 -0
- data/lib/omml/models/ct_perm_start.rb +25 -0
- data/lib/omml/models/ct_phant.rb +23 -0
- data/lib/omml/models/ct_phant_pr.rb +31 -0
- data/lib/omml/models/ct_picture.rb +23 -0
- data/lib/omml/models/ct_picture_base.rb +15 -0
- data/lib/omml/models/ct_placeholder.rb +21 -0
- data/lib/omml/models/ct_point2_d.rb +21 -0
- data/lib/omml/models/ct_pos_h.rb +27 -0
- data/lib/omml/models/ct_pos_v.rb +27 -0
- data/lib/omml/models/ct_positive_size2_d.rb +21 -0
- data/lib/omml/models/ct_proof_err.rb +19 -0
- data/lib/omml/models/ct_r.rb +27 -0
- data/lib/omml/models/ct_r_pr.rb +21 -0
- data/lib/omml/models/ct_r_pr_change.rb +21 -0
- data/lib/omml/models/ct_r_pr_original.rb +21 -0
- data/lib/omml/models/ct_rad.rb +25 -0
- data/lib/omml/models/ct_rad_pr.rb +23 -0
- data/lib/omml/models/ct_rel.rb +19 -0
- data/lib/omml/models/ct_rpr.rb +33 -0
- data/lib/omml/models/ct_ruby.rb +25 -0
- data/lib/omml/models/ct_ruby_align.rb +19 -0
- data/lib/omml/models/ct_ruby_content.rb +19 -0
- data/lib/omml/models/ct_ruby_pr.rb +31 -0
- data/lib/omml/models/ct_run_track_change.rb +23 -0
- data/lib/omml/models/ct_s_pre.rb +28 -0
- data/lib/omml/models/ct_s_pre_pr.rb +21 -0
- data/lib/omml/models/ct_s_sub.rb +25 -0
- data/lib/omml/models/ct_s_sub_pr.rb +21 -0
- data/lib/omml/models/ct_s_sub_sup.rb +28 -0
- data/lib/omml/models/ct_s_sub_sup_pr.rb +23 -0
- data/lib/omml/models/ct_s_sup.rb +25 -0
- data/lib/omml/models/ct_s_sup_pr.rb +21 -0
- data/lib/omml/models/ct_script.rb +19 -0
- data/lib/omml/models/ct_sdt_combo_box.rb +23 -0
- data/lib/omml/models/ct_sdt_content_run.rb +19 -0
- data/lib/omml/models/ct_sdt_date.rb +30 -0
- data/lib/omml/models/ct_sdt_date_mapping_type.rb +19 -0
- data/lib/omml/models/ct_sdt_doc_part.rb +25 -0
- data/lib/omml/models/ct_sdt_drop_down_list.rb +23 -0
- data/lib/omml/models/ct_sdt_end_pr.rb +21 -0
- data/lib/omml/models/ct_sdt_list_item.rb +21 -0
- data/lib/omml/models/ct_sdt_pr.rb +63 -0
- data/lib/omml/models/ct_sdt_run.rb +25 -0
- data/lib/omml/models/ct_sdt_text.rb +19 -0
- data/lib/omml/models/ct_shd.rb +35 -0
- data/lib/omml/models/ct_shp.rb +19 -0
- data/lib/omml/models/ct_signed_hps_measure.rb +19 -0
- data/lib/omml/models/ct_signed_twips_measure.rb +19 -0
- data/lib/omml/models/ct_simple_field.rb +29 -0
- data/lib/omml/models/ct_smart_tag_pr.rb +21 -0
- data/lib/omml/models/ct_smart_tag_run.rb +27 -0
- data/lib/omml/models/ct_spacing_rule.rb +19 -0
- data/lib/omml/models/ct_string.rb +19 -0
- data/lib/omml/models/ct_style.rb +19 -0
- data/lib/omml/models/ct_sym.rb +21 -0
- data/lib/omml/models/ct_text.rb +19 -0
- data/lib/omml/models/ct_text_effect.rb +19 -0
- data/lib/omml/models/ct_text_scale.rb +19 -0
- data/lib/omml/models/ct_top_bot.rb +19 -0
- data/lib/omml/models/ct_track_change.rb +21 -0
- data/lib/omml/models/ct_track_change_numbering.rb +19 -0
- data/lib/omml/models/ct_twips_measure.rb +19 -0
- data/lib/omml/models/ct_un_signed_integer.rb +19 -0
- data/lib/omml/models/ct_underline.rb +27 -0
- data/lib/omml/models/ct_vertical_align_run.rb +19 -0
- data/lib/omml/models/ct_wordprocessing_on_off.rb +19 -0
- data/lib/omml/models/ct_wrap_none.rb +15 -0
- data/lib/omml/models/ct_wrap_path.rb +25 -0
- data/lib/omml/models/ct_wrap_square.rb +31 -0
- data/lib/omml/models/ct_wrap_through.rb +27 -0
- data/lib/omml/models/ct_wrap_tight.rb +27 -0
- data/lib/omml/models/ct_wrap_top_bottom.rb +25 -0
- data/lib/omml/models/ct_x_align.rb +19 -0
- data/lib/omml/models/ct_y_align.rb +19 -0
- data/lib/omml/models/groups/eg_content_run_content.rb +26 -0
- data/lib/omml/models/groups/eg_math_content.rb +20 -0
- data/lib/omml/models/groups/eg_o_math_elements.rb +20 -0
- data/lib/omml/models/groups/eg_o_math_math_elements.rb +56 -0
- data/lib/omml/models/groups/eg_office_art_extension_list.rb +16 -0
- data/lib/omml/models/groups/eg_p_content.rb +24 -0
- data/lib/omml/models/groups/eg_r_pr.rb +17 -0
- data/lib/omml/models/groups/eg_r_pr_base.rb +93 -0
- data/lib/omml/models/groups/eg_r_pr_content.rb +19 -0
- data/lib/omml/models/groups/eg_r_pr_math.rb +23 -0
- data/lib/omml/models/groups/eg_range_markup_elements.rb +60 -0
- data/lib/omml/models/groups/eg_ruby_content.rb +20 -0
- data/lib/omml/models/groups/eg_run_inner_content.rb +83 -0
- data/lib/omml/models/groups/eg_run_level_elts.rb +34 -0
- data/lib/omml/models/groups/eg_script_style.rb +18 -0
- data/lib/omml/models/groups/eg_word_r_pr.rb +17 -0
- data/lib/omml/models/groups/eg_wrap_type.rb +27 -0
- data/lib/omml/models/groups.rb +19 -0
- data/lib/omml/models/o_math.rb +21 -0
- data/lib/omml/models/o_math_para.rb +25 -0
- data/lib/omml/models/simple_types/enum_string.rb +42 -0
- data/lib/omml/models/simple_types/hex_binary.rb +15 -0
- data/lib/omml/models/simple_types/st_adj_coordinate.rb +24 -0
- data/lib/omml/models/simple_types/st_align_h.rb +17 -0
- data/lib/omml/models/simple_types/st_align_v.rb +17 -0
- data/lib/omml/models/simple_types/st_border.rb +203 -0
- data/lib/omml/models/simple_types/st_br_clear.rb +16 -0
- data/lib/omml/models/simple_types/st_br_type.rb +15 -0
- data/lib/omml/models/simple_types/st_break_bin.rb +15 -0
- data/lib/omml/models/simple_types/st_break_bin_sub.rb +15 -0
- data/lib/omml/models/simple_types/st_calendar_type.rb +22 -0
- data/lib/omml/models/simple_types/st_combine_brackets.rb +17 -0
- data/lib/omml/models/simple_types/st_coordinate.rb +16 -0
- data/lib/omml/models/simple_types/st_displaced_by_custom_xml.rb +14 -0
- data/lib/omml/models/simple_types/st_ed_grp.rb +19 -0
- data/lib/omml/models/simple_types/st_em.rb +17 -0
- data/lib/omml/models/simple_types/st_f_type.rb +16 -0
- data/lib/omml/models/simple_types/st_ff_text_type.rb +18 -0
- data/lib/omml/models/simple_types/st_fld_char_type.rb +15 -0
- data/lib/omml/models/simple_types/st_geom_guide_name.rb +10 -0
- data/lib/omml/models/simple_types/st_hex_color.rb +24 -0
- data/lib/omml/models/simple_types/st_highlight_color.rb +29 -0
- data/lib/omml/models/simple_types/st_hint.rb +15 -0
- data/lib/omml/models/simple_types/st_info_text_type.rb +14 -0
- data/lib/omml/models/simple_types/st_integer2.rb +15 -0
- data/lib/omml/models/simple_types/st_integer255.rb +15 -0
- data/lib/omml/models/simple_types/st_jc.rb +16 -0
- data/lib/omml/models/simple_types/st_lang.rb +24 -0
- data/lib/omml/models/simple_types/st_lim_loc.rb +14 -0
- data/lib/omml/models/simple_types/st_lock.rb +16 -0
- data/lib/omml/models/simple_types/st_on_off.rb +18 -0
- data/lib/omml/models/simple_types/st_p_tab_alignment.rb +15 -0
- data/lib/omml/models/simple_types/st_p_tab_leader.rb +17 -0
- data/lib/omml/models/simple_types/st_p_tab_relative_to.rb +14 -0
- data/lib/omml/models/simple_types/st_positive_coordinate.rb +15 -0
- data/lib/omml/models/simple_types/st_proof_err.rb +16 -0
- data/lib/omml/models/simple_types/st_rel_from_h.rb +20 -0
- data/lib/omml/models/simple_types/st_rel_from_v.rb +20 -0
- data/lib/omml/models/simple_types/st_ruby_align.rb +18 -0
- data/lib/omml/models/simple_types/st_script.rb +18 -0
- data/lib/omml/models/simple_types/st_sdt_date_mapping_type.rb +15 -0
- data/lib/omml/models/simple_types/st_shd.rb +50 -0
- data/lib/omml/models/simple_types/st_shp.rb +14 -0
- data/lib/omml/models/simple_types/st_spacing_rule.rb +15 -0
- data/lib/omml/models/simple_types/st_style.rb +16 -0
- data/lib/omml/models/simple_types/st_text_effect.rb +19 -0
- data/lib/omml/models/simple_types/st_text_scale.rb +15 -0
- data/lib/omml/models/simple_types/st_theme.rb +20 -0
- data/lib/omml/models/simple_types/st_theme_color.rb +29 -0
- data/lib/omml/models/simple_types/st_top_bot.rb +14 -0
- data/lib/omml/models/simple_types/st_underline.rb +30 -0
- data/lib/omml/models/simple_types/st_vertical_align_run.rb +15 -0
- data/lib/omml/models/simple_types/st_wrap_text.rb +16 -0
- data/lib/omml/models/simple_types/st_x_align.rb +15 -0
- data/lib/omml/models/simple_types/st_y_align.rb +15 -0
- data/lib/omml/models/simple_types/token.rb +35 -0
- data/lib/omml/models/simple_types/unsigned_int.rb +15 -0
- data/lib/omml/models/simple_types/unsigned_long.rb +15 -0
- data/lib/omml/models/simple_types.rb +60 -0
- data/lib/omml/models.rb +183 -0
- data/lib/omml/namespace.rb +9 -0
- data/lib/omml/parser.rb +39 -0
- data/lib/omml/type_substitutions.rb +89 -0
- data/lib/omml/version.rb +2 -2
- data/lib/omml/wordprocessing_namespace.rb +9 -0
- data/lib/omml.rb +39 -3
- data/omml.gemspec +18 -14
- data/sig/omml.rbs +1 -1
- metadata +335 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 601a769419b5024287dbaf137b26684b871295bd560e9a8e48c46c11293893aa
|
|
4
|
+
data.tar.gz: 004b46f3db7b23ecf117d67a8d8dadf20aede7a7ca3fc17477dec6027127cec5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c290b2273ca8bfc569fae9a7bb42a8b00cd58ca94638308a275f1adef89e44462493101e26ab5f5b8dfcc68ab601311851413e9a253ae60187aca13d7655ebda
|
|
7
|
+
data.tar.gz: aacf63d8d5c2b9ff51fba1f2f6da289ac435899c3c8ba6e9ff03430bb61a0347888cd8367693ab717bcf268aaa8a17a89acb47fe5b2161c40e3e93a645f40184
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
name: rake
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
tags: [ v* ]
|
|
7
|
+
pull_request:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
rake:
|
|
11
|
+
uses: metanorma/ci/.github/workflows/generic-rake.yml@main
|
|
12
|
+
with:
|
|
13
|
+
# This is to fix Ruby 3.4 on Windows, as per lutaml/lutaml-model#447
|
|
14
|
+
before-setup-ruby: |
|
|
15
|
+
mkdir -p .bundle
|
|
16
|
+
touch .bundle/config
|
|
17
|
+
cat .bundle/config
|
|
18
|
+
echo "---" >> .bundle/config
|
|
19
|
+
echo 'BUNDLE_BUILD__RUBY___LL: "--with-cflags=-std=gnu17"' >> .bundle/config
|
|
20
|
+
cat .bundle/config
|
|
21
|
+
secrets:
|
|
22
|
+
pat_token: ${{ secrets.PLURIMATH_CI_PAT_TOKEN }}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
next_version:
|
|
7
|
+
description: |
|
|
8
|
+
Next release version. Possible values: x.y.z, major, minor, patch or pre|rc|etc
|
|
9
|
+
required: true
|
|
10
|
+
default: 'skip'
|
|
11
|
+
push:
|
|
12
|
+
tags: [ v* ]
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
release:
|
|
16
|
+
permissions:
|
|
17
|
+
contents: write
|
|
18
|
+
id-token: write
|
|
19
|
+
uses: metanorma/ci/.github/workflows/rubygems-release.yml@main
|
|
20
|
+
with:
|
|
21
|
+
next_version: ${{ github.event.inputs.next_version }}
|
|
22
|
+
secrets:
|
|
23
|
+
rubygems-api-key: ${{ secrets.PLURIMATH_CI_RUBYGEMS_API_KEY }}
|
data/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.rspec_status
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
inherit_from:
|
|
2
|
+
- https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
|
|
3
|
+
- .rubocop_todo.yml
|
|
4
|
+
|
|
5
|
+
plugins:
|
|
6
|
+
- rubocop-performance
|
|
7
|
+
- rubocop-rake
|
|
8
|
+
- rubocop-rspec
|
|
9
|
+
|
|
10
|
+
AllCops:
|
|
11
|
+
TargetRubyVersion: 3.0
|
|
12
|
+
NewCops: enable
|
|
13
|
+
Exclude:
|
|
14
|
+
- 'vendor/**/*'
|
|
15
|
+
|
|
16
|
+
Metrics/BlockLength:
|
|
17
|
+
AllowedMethods:
|
|
18
|
+
- choice
|
|
19
|
+
- xml
|
|
20
|
+
|
|
21
|
+
RSpec/ExampleLength:
|
|
22
|
+
Max: 20
|
|
23
|
+
|
|
24
|
+
RSpec/MultipleExpectations:
|
|
25
|
+
Max: 10
|
data/.rubocop_todo.yml
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# This configuration was generated by
|
|
2
|
+
# `rubocop --auto-gen-config`
|
|
3
|
+
# on 2026-05-01 11:14:00 UTC using RuboCop version 1.86.1.
|
|
4
|
+
# The point is for the user to remove these configuration records
|
|
5
|
+
# one by one as the offenses are removed from the code base.
|
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
|
8
|
+
|
|
9
|
+
# Offense count: 1
|
|
10
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
|
11
|
+
Metrics/AbcSize:
|
|
12
|
+
Exclude:
|
|
13
|
+
- 'spec/omml_fixture_round_trip_spec.rb'
|
|
14
|
+
|
|
15
|
+
# Offense count: 1
|
|
16
|
+
# Configuration parameters: .
|
|
17
|
+
# SupportedStyles: have_received, receive
|
|
18
|
+
RSpec/MessageSpies:
|
|
19
|
+
EnforcedStyle: receive
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
`omml` is a Ruby gem that parses and serializes OMML (Office Math Markup Language), the XML format used by Microsoft Word for mathematical equations. It is part of the [Plurimath](https://github.com/plurimath) ecosystem. Models are defined using `lutaml-model` (declarative XML serialization) with `ox` as the XML backend.
|
|
8
|
+
|
|
9
|
+
## Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bundle install # Install dependencies
|
|
13
|
+
bundle exec rake # Run specs + rubocop (default task)
|
|
14
|
+
bundle exec rspec # Run all specs
|
|
15
|
+
bundle exec rspec spec/omml_spec.rb # Run a single spec file
|
|
16
|
+
bundle exec rspec spec/omml_spec.rb:77 # Run a single test by line number
|
|
17
|
+
bundle exec rubocop # Lint
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Architecture
|
|
21
|
+
|
|
22
|
+
### Entry point and parsing flow
|
|
23
|
+
|
|
24
|
+
`Omml.parse(xml_string)` → `Parser.parse` → parses XML via the adapter → resolves the root class (`OMath` or `OMathPara` based on root element name) → calls `.of_xml` to deserialize into a Lutaml model tree.
|
|
25
|
+
|
|
26
|
+
The top-level API is in `lib/omml.rb`. `Parser` in `lib/omml/parser.rb` handles the parsing pipeline.
|
|
27
|
+
|
|
28
|
+
### Type context system (`Omml::Configuration`)
|
|
29
|
+
|
|
30
|
+
`Configuration` manages a Lutaml `GlobalContext` (context ID `:omml`) that holds a registry of all model classes. Models are registered via `Omml::Configuration.register_model(Class)` at load time, and the context is populated lazily on first parse. Custom contexts can be created for downstream libraries (e.g., Plurimath) that fall back to the OMML context.
|
|
31
|
+
|
|
32
|
+
Model IDs are derived from class names: prefix `CT`/`EG`/`ST` is stripped and snake-cased with the prefix (e.g., `CTOMath` → `:ct_o_math`).
|
|
33
|
+
|
|
34
|
+
### Model layer (`lib/omml/models/`)
|
|
35
|
+
|
|
36
|
+
Three categories of models, all extending `Lutaml::Model::Serializable`:
|
|
37
|
+
|
|
38
|
+
- **Complex types** (`ct_*.rb`) — represent OMML schema complex types. Each defines attributes and XML element mappings, and self-registers via `Omml::Configuration.register_model`.
|
|
39
|
+
- **Simple types** (`simple_types/*.rb`) — enum/value types like `STJc`, `STOnOff`. These wrap string values with validation.
|
|
40
|
+
- **Group models** (`groups/*.rb`) — shared compositional groups (e.g., `EGOMathElements`). These use `import_model_attributes` / `import_model_mappings` to compose attributes from other groups, implementing the OMML schema's choice/sequence patterns.
|
|
41
|
+
|
|
42
|
+
Root element wrappers (`o_math.rb`, `o_math_para.rb`) extend `CommonCode::RootModel` and use `omml_root_element` to declare themselves as XML root elements with the OMML namespace.
|
|
43
|
+
|
|
44
|
+
### Namespaces
|
|
45
|
+
|
|
46
|
+
- `Omml::Namespace` — the OMML namespace (`http://schemas.openxmlformats.org/officeDocument/2006/math`, prefix `m`)
|
|
47
|
+
- `Omml::WordprocessingNamespace` — the Word ML namespace (prefix `w`), used for elements like `w:rPr` that appear inside OMML
|
|
48
|
+
|
|
49
|
+
### Type substitutions (`TypeSubstitutions`)
|
|
50
|
+
|
|
51
|
+
Many OMML simple types are aliases for built-in Lutaml types (e.g., `STString` → `Lutaml::Model::Type::String`). These are registered as aliases in the context rather than as separate model classes.
|
|
52
|
+
|
|
53
|
+
## Testing
|
|
54
|
+
|
|
55
|
+
- `spec/omml_spec.rb` — unit tests for parsing, context management, and error handling
|
|
56
|
+
- `spec/fixture_round_trip_spec.rb` — parses 279 OMML fixture files from `spec/fixtures/omml/`, round-trips them through parse → serialize, and compares the XML trees structurally (not string-equality). This is the primary correctness check.
|
|
57
|
+
- The round-trip spec expects exact XML structural fidelity: same elements, attributes, namespaces, text content, and child ordering.
|
|
58
|
+
|
|
59
|
+
## Key conventions
|
|
60
|
+
|
|
61
|
+
- All models are in the `Omml::Models` module namespace
|
|
62
|
+
- The XML adapter defaults to `:ox` (MRI) or `:oga` (Opal)
|
|
63
|
+
- Models use `ordered` and `sequence` blocks for XML mapping to preserve element order
|
|
64
|
+
- `render_empty: true` is used on elements that must be emitted even when empty
|
data/Gemfile
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
source
|
|
3
|
+
source "https://rubygems.org"
|
|
4
4
|
|
|
5
5
|
gemspec
|
|
6
6
|
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
gem
|
|
10
|
-
|
|
11
|
-
gem
|
|
12
|
-
gem
|
|
13
|
-
gem
|
|
8
|
+
# TODO: remove this override once lutaml-model 0.8.0 is released.
|
|
9
|
+
gem "lutaml-model", github: "lutaml/lutaml-model", branch: "main"
|
|
10
|
+
|
|
11
|
+
gem "pry"
|
|
12
|
+
gem "rake", "~> 12.0"
|
|
13
|
+
gem "rspec", "~> 3.0"
|
|
14
|
+
gem "rubocop"
|
|
15
|
+
gem "rubocop-performance"
|
|
16
|
+
gem "rubocop-rake"
|
|
17
|
+
gem "rubocop-rspec"
|
data/README.adoc
CHANGED
|
@@ -1,9 +1,227 @@
|
|
|
1
|
-
=
|
|
1
|
+
= Omml: OMML parser and builder for Ruby
|
|
2
|
+
|
|
3
|
+
:toc:
|
|
4
|
+
:toclevels: 2
|
|
2
5
|
|
|
3
6
|
== Purpose
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
Omml provides OMML (Office Math Markup Language) XML parsing and serialization
|
|
9
|
+
for Ruby. It maps the full OMML element set into Ruby model classes using the
|
|
10
|
+
https://github.com/lutaml/lutaml-model[lutaml-model] framework and is used by
|
|
11
|
+
https://github.com/plurimath/plurimath[Plurimath] for mathematical formula
|
|
12
|
+
representation.
|
|
13
|
+
|
|
14
|
+
Key features:
|
|
15
|
+
|
|
16
|
+
* **Round-trip fidelity**: Parse XML to an object graph, modify, and serialize back
|
|
17
|
+
* **Full schema coverage**: 172 complex types, 53 simple types, and 17 group models
|
|
18
|
+
generated from the OOXML Shared Math schema (`shared-math.xsd`)
|
|
19
|
+
* **Namespace handling**: OMML namespace with `m:` prefix, plus Word ML namespace
|
|
20
|
+
for embedded `w:rPr` run properties
|
|
21
|
+
* **Opal support**: Runs in the browser via Ruby-to-JavaScript compilation
|
|
22
|
+
|
|
23
|
+
== Installation
|
|
24
|
+
|
|
25
|
+
[source,ruby]
|
|
26
|
+
----
|
|
27
|
+
gem 'omml'
|
|
28
|
+
----
|
|
29
|
+
|
|
30
|
+
[source,bash]
|
|
31
|
+
----
|
|
32
|
+
$ bundle install
|
|
33
|
+
# or
|
|
34
|
+
$ gem install omml
|
|
35
|
+
----
|
|
36
|
+
|
|
37
|
+
== Quick start
|
|
38
|
+
|
|
39
|
+
[source,ruby]
|
|
40
|
+
----
|
|
41
|
+
require "omml"
|
|
42
|
+
|
|
43
|
+
# Parse OMML XML
|
|
44
|
+
math = Omml.parse('<m:oMath xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"><m:r><m:t>x</m:t></m:r></m:oMath>')
|
|
45
|
+
# => #<Omml::Models::OMath:...>
|
|
46
|
+
|
|
47
|
+
# Serialize back to XML
|
|
48
|
+
math.to_xml(prefix: 'm')
|
|
49
|
+
# => "<m:oMath xmlns:m=\"...\">...</m:oMath>"
|
|
50
|
+
----
|
|
51
|
+
|
|
52
|
+
== Parsing and serialization
|
|
53
|
+
|
|
54
|
+
=== Parsing
|
|
55
|
+
|
|
56
|
+
`Omml.parse` accepts an XML string and returns a model tree. The root element
|
|
57
|
+
determines the wrapper class:
|
|
58
|
+
|
|
59
|
+
* `<m:oMath>` → `Omml::Models::OMath`
|
|
60
|
+
* `<m:oMathPara>` → `Omml::Models::OMathPara`
|
|
61
|
+
|
|
62
|
+
[source,ruby]
|
|
63
|
+
----
|
|
64
|
+
# oMath root
|
|
65
|
+
math = Omml.parse('<m:oMath xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"><m:r><m:t>x</m:t></m:r></m:oMath>')
|
|
66
|
+
math.class # => Omml::Models::OMath
|
|
67
|
+
|
|
68
|
+
# oMathPara root
|
|
69
|
+
para = Omml.parse('<m:oMathPara xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"><m:oMath><m:r><m:t>y</m:t></m:r></m:oMath></m:oMathPara>')
|
|
70
|
+
para.class # => Omml::Models::OMathPara
|
|
71
|
+
----
|
|
72
|
+
|
|
73
|
+
=== Serialization
|
|
74
|
+
|
|
75
|
+
[source,ruby]
|
|
76
|
+
----
|
|
77
|
+
math.to_xml # Default serialization
|
|
78
|
+
math.to_xml(prefix: 'm') # With m: prefix on all elements
|
|
79
|
+
----
|
|
80
|
+
|
|
81
|
+
=== Round-trip (parse, modify, serialize)
|
|
82
|
+
|
|
83
|
+
[source,ruby]
|
|
84
|
+
----
|
|
85
|
+
math = Omml.parse(xml_string)
|
|
86
|
+
# Access and modify the model tree
|
|
87
|
+
math.r.first.t.content = "new value"
|
|
88
|
+
math.to_xml(prefix: 'm')
|
|
89
|
+
----
|
|
90
|
+
|
|
91
|
+
== Internal architecture
|
|
92
|
+
|
|
93
|
+
=== Parsing flow
|
|
94
|
+
|
|
95
|
+
`Omml.parse(xml_string)` delegates to `Parser.parse`, which:
|
|
96
|
+
|
|
97
|
+
1. Configures the XML adapter (`:ox` on MRI, `:oga` on Opal)
|
|
98
|
+
2. Parses the XML string into a document
|
|
99
|
+
3. Resolves the root class from the root element name (`OMath` or `OMathPara`)
|
|
100
|
+
4. Calls `.of_xml` to deserialize into a Lutaml model tree
|
|
101
|
+
|
|
102
|
+
=== Type context system
|
|
103
|
+
|
|
104
|
+
`Omml::Configuration` manages a `Lutaml::Model::GlobalContext` (context ID `:omml`)
|
|
105
|
+
that holds a registry of all model classes. Models register themselves at load
|
|
106
|
+
time via `Omml::Configuration.register_model`. The context is populated lazily on
|
|
107
|
+
first parse.
|
|
108
|
+
|
|
109
|
+
Custom contexts can be created for downstream libraries (e.g., Plurimath) that
|
|
110
|
+
fall back to the OMML context:
|
|
111
|
+
|
|
112
|
+
[source,ruby]
|
|
113
|
+
----
|
|
114
|
+
# Create a custom context with OMML fallback
|
|
115
|
+
Omml::Configuration.create_context(id: :custom_omml)
|
|
116
|
+
|
|
117
|
+
# Parse using the custom context
|
|
118
|
+
Omml.parse(xml, context: :custom_omml)
|
|
119
|
+
----
|
|
120
|
+
|
|
121
|
+
Model IDs are derived from class names by stripping the `CT`/`EG`/`ST` prefix
|
|
122
|
+
and snake-casing with the prefix (e.g., `CTOMath` → `:ct_o_math`,
|
|
123
|
+
`EGOMathElements` → `:eg_o_math_elements`).
|
|
124
|
+
|
|
125
|
+
=== Model layer (`lib/omml/models/`)
|
|
126
|
+
|
|
127
|
+
Three categories of models, all extending `Lutaml::Model::Serializable`:
|
|
128
|
+
|
|
129
|
+
*Complex types* (`ct_*.rb`): Represent OMML schema complex types. Each defines
|
|
130
|
+
attributes and XML element mappings, and self-registers via
|
|
131
|
+
`Omml::Configuration.register_model`.
|
|
132
|
+
|
|
133
|
+
*Simple types* (`simple_types/st_*.rb`): Enum/value types like `STJc`, `STOnOff`.
|
|
134
|
+
These wrap string values with validation.
|
|
135
|
+
|
|
136
|
+
*Group models* (`groups/eg_*.rb`): Shared compositional groups (e.g.,
|
|
137
|
+
`EGOMathElements`). These use `import_model_attributes` /
|
|
138
|
+
`import_model_mappings` to compose attributes from other groups, implementing
|
|
139
|
+
the OMML schema's choice/sequence patterns.
|
|
140
|
+
|
|
141
|
+
Root element wrappers (`o_math.rb`, `o_math_para.rb`) extend
|
|
142
|
+
`CommonCode::RootModel` and use `omml_root_element` to declare themselves as XML
|
|
143
|
+
root elements with the OMML namespace.
|
|
144
|
+
|
|
145
|
+
=== Namespaces
|
|
146
|
+
|
|
147
|
+
* `Omml::Namespace` — OMML namespace
|
|
148
|
+
(`http://schemas.openxmlformats.org/officeDocument/2006/math`, prefix `m`)
|
|
149
|
+
* `Omml::WordprocessingNamespace` — Word ML namespace (prefix `w`), used for
|
|
150
|
+
elements like `w:rPr` that appear inside OMML `ctrlPr` elements
|
|
151
|
+
|
|
152
|
+
=== Type substitutions
|
|
153
|
+
|
|
154
|
+
Many OMML simple types are aliases for built-in Lutaml types (e.g., `STString`
|
|
155
|
+
→ `Lutaml::Model::Type::String`). These are registered as aliases in the
|
|
156
|
+
context rather than as separate model classes, via `Omml::TypeSubstitutions`.
|
|
157
|
+
|
|
158
|
+
== Configuration
|
|
159
|
+
|
|
160
|
+
[source,ruby]
|
|
161
|
+
----
|
|
162
|
+
# XML adapter (default: :ox, :oga on Opal)
|
|
163
|
+
Omml.configure_adapter!
|
|
164
|
+
Omml::Configuration.adapter = :oga
|
|
165
|
+
|
|
166
|
+
# Access the built-in context
|
|
167
|
+
Omml::Configuration.context_id # => :omml
|
|
168
|
+
Omml::Configuration.context
|
|
169
|
+
|
|
170
|
+
# Rebuild after a reset
|
|
171
|
+
Omml::Configuration.populate_context!
|
|
172
|
+
|
|
173
|
+
# Resolve a model class by its context ID
|
|
174
|
+
Omml::Configuration.resolve_type(:ct_o_math)
|
|
175
|
+
# => Omml::Models::CTOMath
|
|
176
|
+
----
|
|
177
|
+
|
|
178
|
+
== Test Suite and Fixtures
|
|
179
|
+
|
|
180
|
+
The gem uses 279 OMML fixture files from `spec/fixtures/omml/` for round-trip
|
|
181
|
+
validation. Each fixture is parsed, serialized, and the output is compared
|
|
182
|
+
structurally against the original.
|
|
183
|
+
|
|
184
|
+
=== Running Tests
|
|
185
|
+
|
|
186
|
+
[source,bash]
|
|
187
|
+
----
|
|
188
|
+
bundle exec rake # Run all specs + rubocop
|
|
189
|
+
bundle exec rspec # Run all tests
|
|
190
|
+
bundle exec rspec spec/omml_spec.rb # Run specific test file
|
|
191
|
+
bundle exec rspec spec/omml_spec.rb:77 # Run single test by line
|
|
192
|
+
bundle exec rspec --only-failures # Re-run failures
|
|
193
|
+
----
|
|
194
|
+
|
|
195
|
+
=== XSD Validation
|
|
196
|
+
|
|
197
|
+
The fixture round-trips are validated against the OOXML `shared-math.xsd`
|
|
198
|
+
schema. Some fixtures contain Word-specific deviations from the strict XSD:
|
|
199
|
+
|
|
200
|
+
* Element ordering differences (Word may output children in a different order
|
|
201
|
+
than the schema sequence)
|
|
202
|
+
* Numeric `val` values (`1`/`0`) on `CT_OnOff` elements where the XSD specifies
|
|
203
|
+
`on`/`off` enumeration
|
|
204
|
+
* `r` elements directly under `oMathPara` (Word output, not in the XSD sequence)
|
|
205
|
+
|
|
206
|
+
These are well-known Word compatibilities and do not represent parser bugs.
|
|
207
|
+
|
|
208
|
+
== Development
|
|
209
|
+
|
|
210
|
+
[source,bash]
|
|
211
|
+
----
|
|
212
|
+
bundle install # Install dependencies
|
|
213
|
+
bundle exec rake # Run specs + rubocop
|
|
214
|
+
bundle exec rspec # Run tests
|
|
215
|
+
bundle exec rubocop # Lint
|
|
216
|
+
----
|
|
217
|
+
|
|
218
|
+
== Contributing
|
|
219
|
+
|
|
220
|
+
Bug reports and pull requests are welcome on GitHub at
|
|
221
|
+
https://github.com/plurimath/omml.
|
|
222
|
+
|
|
223
|
+
== Copyright and license
|
|
6
224
|
|
|
7
|
-
|
|
225
|
+
Copyright Ribose Inc.
|
|
8
226
|
|
|
9
|
-
|
|
227
|
+
https://opensource.org/licenses/BSD-2-Clause[BSD-2-Clause License].
|
data/Rakefile
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require "bundler/gem_tasks"
|
|
4
|
+
require "rspec/core/rake_task"
|
|
5
5
|
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
|
7
7
|
|
|
8
|
-
require
|
|
8
|
+
require "rubocop/rake_task"
|
|
9
9
|
|
|
10
10
|
RuboCop::RakeTask.new
|
|
11
11
|
|
data/bin/console
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
require
|
|
5
|
-
require
|
|
4
|
+
require "bundler/setup"
|
|
5
|
+
require "omml"
|
|
6
6
|
|
|
7
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
|
8
8
|
# with your gem easier. You can also use a different console, if you like.
|
|
9
9
|
|
|
10
|
-
require
|
|
10
|
+
require "irb"
|
|
11
11
|
IRB.start(__FILE__)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omml
|
|
4
|
+
module Configuration
|
|
5
|
+
# Extended only by Omml::Configuration together with the sibling modules.
|
|
6
|
+
module Adapter
|
|
7
|
+
def adapter
|
|
8
|
+
Lutaml::Model::Config.xml_adapter_type
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def adapter=(adapter)
|
|
12
|
+
Lutaml::Model::Config.xml_adapter_type = adapter
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def xml_adapter
|
|
16
|
+
self.adapter = Omml.default_adapter unless adapter
|
|
17
|
+
|
|
18
|
+
Lutaml::Model::Config.adapter_for(:xml)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omml
|
|
4
|
+
module Configuration
|
|
5
|
+
# Extended only by Omml::Configuration together with the sibling modules.
|
|
6
|
+
module ContextRegistry
|
|
7
|
+
def context(id = context_id)
|
|
8
|
+
Lutaml::Model::GlobalContext.context(id.to_sym)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def create_context(id:, registry: nil, fallback_to: [context_id],
|
|
12
|
+
substitutions: [])
|
|
13
|
+
normalized_id = normalize_context_id(id)
|
|
14
|
+
if default_context_id?(normalized_id)
|
|
15
|
+
return create_default_context(registry, fallback_to,
|
|
16
|
+
substitutions)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
create_custom_context(
|
|
20
|
+
id: normalized_id, registry: registry,
|
|
21
|
+
fallback_to: fallback_to, substitutions: substitutions
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def populate_context!
|
|
26
|
+
# Trigger the model manifest autoload before replaying registrations.
|
|
27
|
+
Omml.const_get(:Models)
|
|
28
|
+
reset_context!
|
|
29
|
+
register_models_in(populate_base_context)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def require_context!(id = context_id)
|
|
33
|
+
normalized_id = id.to_sym
|
|
34
|
+
type_context = context(normalized_id)
|
|
35
|
+
return type_context if type_context
|
|
36
|
+
|
|
37
|
+
raise Omml::Errors::MissingContextError, normalized_id
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def reset_context!(id: context_id)
|
|
41
|
+
normalized_id = normalize_context_id(id)
|
|
42
|
+
existing_context = Lutaml::Model::GlobalContext.context(normalized_id)
|
|
43
|
+
return unless existing_context
|
|
44
|
+
|
|
45
|
+
Lutaml::Model::GlobalContext.unregister_context(normalized_id)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def default_context_id?(id)
|
|
51
|
+
id == context_id
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def create_default_context(registry, fallback_to, substitutions)
|
|
55
|
+
unless default_context_options?(registry, fallback_to, substitutions)
|
|
56
|
+
raise ArgumentError,
|
|
57
|
+
"create_context cannot customize the default " \
|
|
58
|
+
":#{context_id} context; use populate_context! to rebuild it."
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
populate_context!
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def default_context_options?(registry, fallback_to, substitutions)
|
|
65
|
+
registry.nil? &&
|
|
66
|
+
normalize_fallbacks(fallback_to) == [context_id] &&
|
|
67
|
+
Array(substitutions).empty?
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def create_custom_context(id:, registry:, fallback_to:, substitutions:)
|
|
71
|
+
reset_context!(id: id)
|
|
72
|
+
create_type_context(
|
|
73
|
+
id: id,
|
|
74
|
+
registry: registry || Lutaml::Model::TypeRegistry.new,
|
|
75
|
+
fallback_to: prepare_fallback_contexts(fallback_to),
|
|
76
|
+
substitutions: substitutions,
|
|
77
|
+
)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def populate_base_context
|
|
81
|
+
base_type_context.tap { bind_namespace!(context_id) }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def create_type_context(id:, registry:, fallback_to:, substitutions: [])
|
|
85
|
+
Lutaml::Model::GlobalContext.create_context(
|
|
86
|
+
id: id,
|
|
87
|
+
registry: registry,
|
|
88
|
+
fallback_to: Array(fallback_to),
|
|
89
|
+
substitutions: substitutions,
|
|
90
|
+
).tap do
|
|
91
|
+
Lutaml::Model::GlobalContext.clear_caches
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def base_type_context
|
|
96
|
+
create_type_context(
|
|
97
|
+
id: context_id,
|
|
98
|
+
registry: Lutaml::Model::TypeRegistry.new,
|
|
99
|
+
fallback_to: [:default],
|
|
100
|
+
)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def prepare_fallback_contexts(fallback_to)
|
|
104
|
+
normalize_fallbacks(fallback_to).tap do |fallbacks|
|
|
105
|
+
populate_context! if populate_fallback_context?(fallbacks)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def populate_fallback_context?(fallbacks)
|
|
110
|
+
fallbacks.include?(context_id) && !context(context_id)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def normalize_fallbacks(fallback_to)
|
|
114
|
+
Array(fallback_to).map do |fallback|
|
|
115
|
+
normalize_context_id(fallback)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def normalize_context_id(id)
|
|
120
|
+
id.to_sym
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def bind_namespace!(id)
|
|
124
|
+
Lutaml::Model::GlobalContext.bind_register_to_namespace(
|
|
125
|
+
id,
|
|
126
|
+
Omml::Namespace.uri,
|
|
127
|
+
)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omml
|
|
4
|
+
module Configuration
|
|
5
|
+
# Extended only by Omml::Configuration together with the sibling modules.
|
|
6
|
+
module ModelRegistry
|
|
7
|
+
def register_model(klass, id: nil)
|
|
8
|
+
model_id = (id || model_id_for(klass)).to_sym
|
|
9
|
+
registered_models[model_id] = klass
|
|
10
|
+
|
|
11
|
+
if (type_context = context(context_id))
|
|
12
|
+
type_context.registry.register(model_id, klass)
|
|
13
|
+
clear_cache(klass, type_context.id)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
klass
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def model_id_for(klass)
|
|
20
|
+
class_name = klass.name.split("::").last
|
|
21
|
+
prefix = SCHEMA_MODEL_PREFIXES.find do |candidate|
|
|
22
|
+
class_name.start_with?(candidate) && class_name != candidate
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
if prefix
|
|
26
|
+
model_name = class_name.delete_prefix(prefix)
|
|
27
|
+
return :"#{prefix.downcase}_#{Lutaml::Model::Utils.snake_case(model_name)}"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
Lutaml::Model::Utils.snake_case(class_name).to_sym
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def registered_models
|
|
34
|
+
@registered_models ||= {}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def register_models_in(type_context)
|
|
40
|
+
register_id = type_context.id
|
|
41
|
+
registered_models.each do |model_id, klass|
|
|
42
|
+
type_context.registry.register(model_id, klass)
|
|
43
|
+
clear_cache(klass, register_id)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
Omml::TypeSubstitutions.each_alias do |type_name, klass|
|
|
47
|
+
type_context.registry.register(type_name, klass)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
Lutaml::Model::GlobalContext.clear_caches
|
|
51
|
+
type_context
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def clear_cache(klass, register_id)
|
|
55
|
+
klass.instance_variable_set(:@register, register_id)
|
|
56
|
+
klass.clear_cache(register_id) if klass.respond_to?(:clear_cache)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|