stupidedi 1.1.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.
- data/README.md +215 -0
- data/Rakefile +108 -0
- data/bin/edi-ed +71 -0
- data/bin/edi-pp +81 -0
- data/doc/Defining.md +0 -0
- data/doc/Generating.md +321 -0
- data/doc/LICENSE.md +0 -0
- data/doc/Navigating.md +645 -0
- data/doc/Parsing.md +0 -0
- data/doc/Serializing.md +7 -0
- data/doc/Tokenizing.md +0 -0
- data/doc/Validating.md +0 -0
- data/doc/design/Parser.md +0 -0
- data/doc/design/Reader.md +0 -0
- data/lib/ruby/array.rb +164 -0
- data/lib/ruby/blank.rb +67 -0
- data/lib/ruby/enumerable.rb +35 -0
- data/lib/ruby/exception.rb +33 -0
- data/lib/ruby/hash.rb +4 -0
- data/lib/ruby/instance_exec.rb +26 -0
- data/lib/ruby/module.rb +79 -0
- data/lib/ruby/object.rb +63 -0
- data/lib/ruby/string.rb +73 -0
- data/lib/ruby/symbol.rb +24 -0
- data/lib/ruby/to_d.rb +81 -0
- data/lib/ruby/to_date.rb +33 -0
- data/lib/ruby/to_time.rb +24 -0
- data/lib/ruby/try.rb +43 -0
- data/lib/stupidedi/blank_slate.rb +11 -0
- data/lib/stupidedi/builder/builder_dsl.rb +281 -0
- data/lib/stupidedi/builder/constraint_table.rb +418 -0
- data/lib/stupidedi/builder/generation.rb +112 -0
- data/lib/stupidedi/builder/instruction.rb +102 -0
- data/lib/stupidedi/builder/instruction_table.rb +204 -0
- data/lib/stupidedi/builder/navigation.rb +655 -0
- data/lib/stupidedi/builder/state_machine.rb +55 -0
- data/lib/stupidedi/builder/states/abstract_state.rb +332 -0
- data/lib/stupidedi/builder/states/failure_state.rb +69 -0
- data/lib/stupidedi/builder/states/functional_group_state.rb +97 -0
- data/lib/stupidedi/builder/states/initial_state.rb +63 -0
- data/lib/stupidedi/builder/states/interchange_state.rb +94 -0
- data/lib/stupidedi/builder/states/loop_state.rb +79 -0
- data/lib/stupidedi/builder/states/table_state.rb +96 -0
- data/lib/stupidedi/builder/states/transaction_set_state.rb +112 -0
- data/lib/stupidedi/builder/states/transmission_state.rb +59 -0
- data/lib/stupidedi/builder/tokenization.rb +196 -0
- data/lib/stupidedi/builder.rb +23 -0
- data/lib/stupidedi/color.rb +93 -0
- data/lib/stupidedi/config/code_list_config.rb +42 -0
- data/lib/stupidedi/config/editor_config.rb +51 -0
- data/lib/stupidedi/config/functional_group_config.rb +62 -0
- data/lib/stupidedi/config/interchange_config.rb +79 -0
- data/lib/stupidedi/config/transaction_set_config.rb +91 -0
- data/lib/stupidedi/config.rb +101 -0
- data/lib/stupidedi/editor/00501.rb +341 -0
- data/lib/stupidedi/editor/005010/N2.rb +0 -0
- data/lib/stupidedi/editor/005010/N3.rb +0 -0
- data/lib/stupidedi/editor/005010/N4.rb +63 -0
- data/lib/stupidedi/editor/005010/NM1.rb +0 -0
- data/lib/stupidedi/editor/005010.rb +469 -0
- data/lib/stupidedi/editor/X222-HC837.rb +195 -0
- data/lib/stupidedi/editor/abstract_ed.rb +36 -0
- data/lib/stupidedi/editor/claim_ack.rb +9 -0
- data/lib/stupidedi/editor/implementation_ack.rb +213 -0
- data/lib/stupidedi/editor/interchange_ack.rb +9 -0
- data/lib/stupidedi/editor/result.rb +100 -0
- data/lib/stupidedi/editor/result_set.rb +69 -0
- data/lib/stupidedi/editor/transaction_set_ed.rb +275 -0
- data/lib/stupidedi/editor/transmission_ed.rb +90 -0
- data/lib/stupidedi/editor.rb +37 -0
- data/lib/stupidedi/either.rb +287 -0
- data/lib/stupidedi/exceptions/invalid_element_error.rb +8 -0
- data/lib/stupidedi/exceptions/invalid_schema_error.rb +8 -0
- data/lib/stupidedi/exceptions/output_error.rb +8 -0
- data/lib/stupidedi/exceptions/parse_error.rb +8 -0
- data/lib/stupidedi/exceptions/stupidedi_error.rb +8 -0
- data/lib/stupidedi/exceptions/tokenize_error.rb +8 -0
- data/lib/stupidedi/exceptions/zipper_error.rb +8 -0
- data/lib/stupidedi/exceptions.rb +11 -0
- data/lib/stupidedi/guides/005010/X214-HN277.rb +409 -0
- data/lib/stupidedi/guides/005010/X221-HP835.rb +613 -0
- data/lib/stupidedi/guides/005010/X221A1-HP835.rb +613 -0
- data/lib/stupidedi/guides/005010/X222-HC837P.rb +2291 -0
- data/lib/stupidedi/guides/005010/X222A1-HC837P.rb +2297 -0
- data/lib/stupidedi/guides/005010/X231-FA999.rb +123 -0
- data/lib/stupidedi/guides/005010/X231A1-FA999.rb +119 -0
- data/lib/stupidedi/guides/005010/element_reqs.rb +38 -0
- data/lib/stupidedi/guides/005010/guide_builder.rb +180 -0
- data/lib/stupidedi/guides/005010/segment_reqs.rb +32 -0
- data/lib/stupidedi/guides/005010.rb +64 -0
- data/lib/stupidedi/guides.rb +5 -0
- data/lib/stupidedi/inspect.rb +26 -0
- data/lib/stupidedi/reader/input/abstract_input.rb +133 -0
- data/lib/stupidedi/reader/input/delegated_input.rb +111 -0
- data/lib/stupidedi/reader/input/file_input.rb +155 -0
- data/lib/stupidedi/reader/input.rb +30 -0
- data/lib/stupidedi/reader/position.rb +69 -0
- data/lib/stupidedi/reader/result.rb +168 -0
- data/lib/stupidedi/reader/segment_dict.rb +175 -0
- data/lib/stupidedi/reader/separators.rb +85 -0
- data/lib/stupidedi/reader/stream_reader.rb +172 -0
- data/lib/stupidedi/reader/token_reader.rb +466 -0
- data/lib/stupidedi/reader/tokens/component_element_tok.rb +56 -0
- data/lib/stupidedi/reader/tokens/composite_element_tok.rb +64 -0
- data/lib/stupidedi/reader/tokens/repeated_element_tok.rb +64 -0
- data/lib/stupidedi/reader/tokens/segment_tok.rb +51 -0
- data/lib/stupidedi/reader/tokens/simple_element_tok.rb +63 -0
- data/lib/stupidedi/reader.rb +121 -0
- data/lib/stupidedi/schema/abstract_def.rb +74 -0
- data/lib/stupidedi/schema/abstract_use.rb +73 -0
- data/lib/stupidedi/schema/code_list.rb +94 -0
- data/lib/stupidedi/schema/element_def.rb +173 -0
- data/lib/stupidedi/schema/element_req.rb +56 -0
- data/lib/stupidedi/schema/element_use.rb +251 -0
- data/lib/stupidedi/schema/functional_group_def.rb +114 -0
- data/lib/stupidedi/schema/interchange_def.rb +93 -0
- data/lib/stupidedi/schema/loop_def.rb +152 -0
- data/lib/stupidedi/schema/repeat_count.rb +85 -0
- data/lib/stupidedi/schema/segment_def.rb +108 -0
- data/lib/stupidedi/schema/segment_req.rb +43 -0
- data/lib/stupidedi/schema/segment_use.rb +98 -0
- data/lib/stupidedi/schema/syntax_note.rb +63 -0
- data/lib/stupidedi/schema/table_def.rb +139 -0
- data/lib/stupidedi/schema/transaction_set_def.rb +88 -0
- data/lib/stupidedi/schema.rb +28 -0
- data/lib/stupidedi/sets/absolute_set.rb +297 -0
- data/lib/stupidedi/sets/abstract_set.rb +174 -0
- data/lib/stupidedi/sets/null_set.rb +125 -0
- data/lib/stupidedi/sets/relative_complement.rb +137 -0
- data/lib/stupidedi/sets/relative_set.rb +269 -0
- data/lib/stupidedi/sets/universal_set.rb +104 -0
- data/lib/stupidedi/sets.rb +57 -0
- data/lib/stupidedi/tail_call.rb +109 -0
- data/lib/stupidedi/thread_local.rb +174 -0
- data/lib/stupidedi/values/abstract_element_val.rb +19 -0
- data/lib/stupidedi/values/abstract_val.rb +130 -0
- data/lib/stupidedi/values/composite_element_val.rb +95 -0
- data/lib/stupidedi/values/functional_group_val.rb +102 -0
- data/lib/stupidedi/values/interchange_val.rb +86 -0
- data/lib/stupidedi/values/invalid_envelope_val.rb +61 -0
- data/lib/stupidedi/values/invalid_segment_val.rb +78 -0
- data/lib/stupidedi/values/loop_val.rb +70 -0
- data/lib/stupidedi/values/repeated_element_val.rb +105 -0
- data/lib/stupidedi/values/segment_val.rb +104 -0
- data/lib/stupidedi/values/segment_val_group.rb +20 -0
- data/lib/stupidedi/values/simple_element_val.rb +80 -0
- data/lib/stupidedi/values/table_val.rb +66 -0
- data/lib/stupidedi/values/transaction_set_val.rb +66 -0
- data/lib/stupidedi/values/transmission_val.rb +52 -0
- data/lib/stupidedi/values.rb +21 -0
- data/lib/stupidedi/version.rb +3 -0
- data/lib/stupidedi/versions/functional_groups/004010/element_defs.rb +54 -0
- data/lib/stupidedi/versions/functional_groups/004010/element_reqs.rb +18 -0
- data/lib/stupidedi/versions/functional_groups/004010/element_types/date_val.rb +527 -0
- data/lib/stupidedi/versions/functional_groups/004010/element_types/fixnum_val.rb +335 -0
- data/lib/stupidedi/versions/functional_groups/004010/element_types/float_val.rb +299 -0
- data/lib/stupidedi/versions/functional_groups/004010/element_types/identifier_val.rb +287 -0
- data/lib/stupidedi/versions/functional_groups/004010/element_types/string_val.rb +338 -0
- data/lib/stupidedi/versions/functional_groups/004010/element_types/time_val.rb +309 -0
- data/lib/stupidedi/versions/functional_groups/004010/element_types.rb +124 -0
- data/lib/stupidedi/versions/functional_groups/004010/functional_group_def.rb +30 -0
- data/lib/stupidedi/versions/functional_groups/004010/segment_defs/GE.rb +20 -0
- data/lib/stupidedi/versions/functional_groups/004010/segment_defs/GS.rb +27 -0
- data/lib/stupidedi/versions/functional_groups/004010/segment_defs/SE.rb +20 -0
- data/lib/stupidedi/versions/functional_groups/004010/segment_defs/ST.rb +20 -0
- data/lib/stupidedi/versions/functional_groups/004010/segment_defs.rb +23 -0
- data/lib/stupidedi/versions/functional_groups/004010/segment_reqs.rb +18 -0
- data/lib/stupidedi/versions/functional_groups/004010/syntax_notes.rb +174 -0
- data/lib/stupidedi/versions/functional_groups/004010.rb +38 -0
- data/lib/stupidedi/versions/functional_groups/005010/element_defs.rb +1405 -0
- data/lib/stupidedi/versions/functional_groups/005010/element_reqs.rb +18 -0
- data/lib/stupidedi/versions/functional_groups/005010/element_types/date_val.rb +577 -0
- data/lib/stupidedi/versions/functional_groups/005010/element_types/fixnum_val.rb +322 -0
- data/lib/stupidedi/versions/functional_groups/005010/element_types/float_val.rb +354 -0
- data/lib/stupidedi/versions/functional_groups/005010/element_types/identifier_val.rb +368 -0
- data/lib/stupidedi/versions/functional_groups/005010/element_types/operators.rb +117 -0
- data/lib/stupidedi/versions/functional_groups/005010/element_types/string_val.rb +398 -0
- data/lib/stupidedi/versions/functional_groups/005010/element_types/time_val.rb +327 -0
- data/lib/stupidedi/versions/functional_groups/005010/element_types.rb +132 -0
- data/lib/stupidedi/versions/functional_groups/005010/functional_group_def.rb +30 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AK1.rb +21 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AK2.rb +21 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AK9.rb +28 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AMT.rb +21 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/BHT.rb +24 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/BPR.rb +49 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CAS.rb +56 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CL1.rb +22 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CLM.rb +41 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CLP.rb +34 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CN1.rb +24 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CR1.rb +32 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CR2.rb +35 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CR3.rb +25 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CRC.rb +26 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CTP.rb +36 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CTX.rb +24 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CUR.rb +57 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DMG.rb +34 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DN1.rb +22 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DN2.rb +24 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DTM.rb +24 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DTP.rb +21 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/FRM.rb +25 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/GE.rb +20 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/GS.rb +27 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/HCP.rb +39 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/HI.rb +31 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/HL.rb +22 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/IK3.rb +22 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/IK4.rb +22 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/IK5.rb +24 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/K3.rb +21 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/LIN.rb +69 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/LQ.rb +22 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/LX.rb +19 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/MEA.rb +39 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/MIA.rb +45 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/MOA.rb +28 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N1.rb +24 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N2.rb +20 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N3.rb +20 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N4.rb +30 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/NM1.rb +35 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/NTE.rb +20 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/OI.rb +24 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PAT.rb +31 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PER.rb +32 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PLB.rb +40 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PRV.rb +26 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PS1.rb +21 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PWK.rb +30 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/QTY.rb +25 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/RDM.rb +23 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/REF.rb +23 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SBR.rb +28 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SE.rb +20 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/ST.rb +21 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/STC.rb +30 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV1.rb +44 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV2.rb +29 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV3.rb +30 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV5.rb +29 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SVC.rb +26 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SVD.rb +24 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TOO.rb +21 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TRN.rb +22 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TS2.rb +40 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TS3.rb +45 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_defs.rb +227 -0
- data/lib/stupidedi/versions/functional_groups/005010/segment_reqs.rb +18 -0
- data/lib/stupidedi/versions/functional_groups/005010/syntax_notes.rb +165 -0
- data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/FA999.rb +38 -0
- data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HB271.rb +85 -0
- data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HC837.rb +163 -0
- data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HI278.rb +64 -0
- data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HN277.rb +74 -0
- data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HP835.rb +68 -0
- data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HR276.rb +57 -0
- data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HS270.rb +53 -0
- data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/RA820.rb +240 -0
- data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs.rb +68 -0
- data/lib/stupidedi/versions/functional_groups/005010.rb +38 -0
- data/lib/stupidedi/versions/functional_groups.rb +8 -0
- data/lib/stupidedi/versions/interchanges/00401/element_defs.rb +224 -0
- data/lib/stupidedi/versions/interchanges/00401/interchange_def.rb +45 -0
- data/lib/stupidedi/versions/interchanges/00401/segment_defs/IEA.rb +20 -0
- data/lib/stupidedi/versions/interchanges/00401/segment_defs/ISA.rb +34 -0
- data/lib/stupidedi/versions/interchanges/00401/segment_defs/TA1.rb +23 -0
- data/lib/stupidedi/versions/interchanges/00401/segment_defs.rb +28 -0
- data/lib/stupidedi/versions/interchanges/00401.rb +23 -0
- data/lib/stupidedi/versions/interchanges/00501/element_defs.rb +269 -0
- data/lib/stupidedi/versions/interchanges/00501/interchange_def.rb +47 -0
- data/lib/stupidedi/versions/interchanges/00501/segment_defs/IEA.rb +20 -0
- data/lib/stupidedi/versions/interchanges/00501/segment_defs/ISA.rb +34 -0
- data/lib/stupidedi/versions/interchanges/00501/segment_defs/ISB.rb +18 -0
- data/lib/stupidedi/versions/interchanges/00501/segment_defs/ISE.rb +18 -0
- data/lib/stupidedi/versions/interchanges/00501/segment_defs/TA1.rb +23 -0
- data/lib/stupidedi/versions/interchanges/00501/segment_defs/TA3.rb +18 -0
- data/lib/stupidedi/versions/interchanges/00501/segment_defs.rb +37 -0
- data/lib/stupidedi/versions/interchanges/00501.rb +23 -0
- data/lib/stupidedi/versions/interchanges.rb +8 -0
- data/lib/stupidedi/versions.rb +6 -0
- data/lib/stupidedi/writer/claredi.rb +142 -0
- data/lib/stupidedi/writer/default.rb +124 -0
- data/lib/stupidedi/writer.rb +6 -0
- data/lib/stupidedi/zipper/abstract_cursor.rb +351 -0
- data/lib/stupidedi/zipper/dangling_cursor.rb +103 -0
- data/lib/stupidedi/zipper/edited_cursor.rb +157 -0
- data/lib/stupidedi/zipper/memoized_cursor.rb +131 -0
- data/lib/stupidedi/zipper/path.rb +124 -0
- data/lib/stupidedi/zipper/root_cursor.rb +120 -0
- data/lib/stupidedi/zipper.rb +25 -0
- data/lib/stupidedi.rb +66 -0
- data/spec/examples/integration/generating.example +551 -0
- data/spec/examples/integration/navigating.example +214 -0
- data/spec/examples/integration/parsing.example +445 -0
- data/spec/examples/ruby/array.example +476 -0
- data/spec/examples/ruby/blank.example +62 -0
- data/spec/examples/ruby/count.example +68 -0
- data/spec/examples/ruby/object.example +99 -0
- data/spec/examples/ruby/string.example +111 -0
- data/spec/examples/ruby/symbol.example +117 -0
- data/spec/examples/ruby/to_d.example +90 -0
- data/spec/examples/ruby/try.example +50 -0
- data/spec/examples/stupidedi/either.example +375 -0
- data/spec/examples/stupidedi/reader/failure.example +68 -0
- data/spec/examples/stupidedi/reader/input/delegated_input.example +292 -0
- data/spec/examples/stupidedi/reader/separators.example +73 -0
- data/spec/examples/stupidedi/reader/stream_reader.example +48 -0
- data/spec/examples/stupidedi/reader/success.example +34 -0
- data/spec/examples/stupidedi/reader/token_reader.example +775 -0
- data/spec/examples/stupidedi/reader.example +168 -0
- data/spec/examples/stupidedi/sets/absolute_set.example +1577 -0
- data/spec/examples/stupidedi/sets/null_set.example +2 -0
- data/spec/examples/stupidedi/sets/relative_set.example +2 -0
- data/spec/examples/stupidedi/sets/universal_set.example +1 -0
- data/spec/examples/stupidedi/versions/005010/element_types/an.example +201 -0
- data/spec/examples/stupidedi/versions/005010/element_types/dt.example +258 -0
- data/spec/examples/stupidedi/versions/005010/element_types/id.example +192 -0
- data/spec/examples/stupidedi/versions/005010/element_types/nn.example +177 -0
- data/spec/examples/stupidedi/versions/005010/element_types/r.example +178 -0
- data/spec/examples/stupidedi/versions/005010/element_types/tm.example +2 -0
- data/spec/examples/stupidedi/zipper/abstract_cursor.example +417 -0
- data/spec/examples/stupidedi/zipper.example +9 -0
- data/spec/fixtures/X186-AG824/1-bad.txt +21 -0
- data/spec/fixtures/X186-AG824/1-good.txt +17 -0
- data/spec/fixtures/X186-AG824/2-bad.txt +26 -0
- data/spec/fixtures/X186-AG824/2-good.txt +21 -0
- data/spec/fixtures/X186-AG824/3-bad.txt +87 -0
- data/spec/fixtures/X186-AG824/3-good.txt +61 -0
- data/spec/fixtures/X212-HN277/1-bad.txt +54 -0
- data/spec/fixtures/X212-HN277/1-good.txt +46 -0
- data/spec/fixtures/X212-HN277/2-bad.txt +37 -0
- data/spec/fixtures/X212-HN277/2-good.txt +29 -0
- data/spec/fixtures/X212-HN277/3-bad.txt +22 -0
- data/spec/fixtures/X212-HN277/3-good.txt +17 -0
- data/spec/fixtures/X212-HN277/4-bad.txt +30 -0
- data/spec/fixtures/X212-HN277/4-good.txt +24 -0
- data/spec/fixtures/X212-HR276/1-bad.txt +53 -0
- data/spec/fixtures/X212-HR276/1-good.txt +46 -0
- data/spec/fixtures/X212-HR276/2-bad.txt +45 -0
- data/spec/fixtures/X212-HR276/2-good.txt +38 -0
- data/spec/fixtures/X212-HR276/3-bad.txt +32 -0
- data/spec/fixtures/X212-HR276/3-good.txt +26 -0
- data/spec/fixtures/X212-HR276/4-bad.txt +32 -0
- data/spec/fixtures/X212-HR276/4-good.txt +26 -0
- data/spec/fixtures/X214-HN277/1-bad.txt +58 -0
- data/spec/fixtures/X214-HN277/1-good.txt +47 -0
- data/spec/fixtures/X214-HN277/2-bad.txt +34 -0
- data/spec/fixtures/X214-HN277/2-good.txt +22 -0
- data/spec/fixtures/X214-HN277/3-bad.txt +64 -0
- data/spec/fixtures/X214-HN277/3-good.txt +54 -0
- data/spec/fixtures/X214-HN277/4-bad.txt +77 -0
- data/spec/fixtures/X214-HN277/4-good.txt +63 -0
- data/spec/fixtures/X216-HI278/1-bad.txt +42 -0
- data/spec/fixtures/X216-HI278/1-good.txt +27 -0
- data/spec/fixtures/X216-HI278/2-bad.txt +43 -0
- data/spec/fixtures/X216-HI278/2-good.txt +29 -0
- data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-1.txt +24 -0
- data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-1_Clean.txt +20 -0
- data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-2.txt +46 -0
- data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-2_Clean.txt +30 -0
- data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-3.txt +38 -0
- data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-3_Clean.txt +24 -0
- data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4a.txt +39 -0
- data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4a_Clean.txt +24 -0
- data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4b.txt +43 -0
- data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4b_Clean.txt +25 -0
- data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-5.txt +63 -0
- data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-5_Clean.txt +41 -0
- data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-6.txt +36 -0
- data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-6_Clean.txt +20 -0
- data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-1r.txt +34 -0
- data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-1r_Clean.txt +23 -0
- data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-2r.txt +46 -0
- data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-2r_Clean.txt +31 -0
- data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-3r.txt +44 -0
- data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-3r_Clean.txt +26 -0
- data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-4ar_Clean.txt +28 -0
- data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-4br_Clean.txt +35 -0
- data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-5r.txt +60 -0
- data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-5r_Clean.txt +42 -0
- data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-6r.txt +40 -0
- data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-6r_Clean.txt +24 -0
- data/spec/fixtures/X218-RA820/1-bad.txt +31 -0
- data/spec/fixtures/X218-RA820/1-good.txt +25 -0
- data/spec/fixtures/X218-RA820/2-bad.txt +37 -0
- data/spec/fixtures/X218-RA820/2-good.txt +29 -0
- data/spec/fixtures/X218-RA820/3-bad.txt +29 -0
- data/spec/fixtures/X218-RA820/3-good.txt +23 -0
- data/spec/fixtures/X218-RA820/4-bad.txt +36 -0
- data/spec/fixtures/X218-RA820/4-good.txt +27 -0
- data/spec/fixtures/X220-BE834/1-bad.txt +35 -0
- data/spec/fixtures/X220-BE834/1-good.txt +29 -0
- data/spec/fixtures/X220-BE834/10-bad.txt +26 -0
- data/spec/fixtures/X220-BE834/10-good.txt +19 -0
- data/spec/fixtures/X220-BE834/2-bad.txt +31 -0
- data/spec/fixtures/X220-BE834/2-good.txt +23 -0
- data/spec/fixtures/X220-BE834/3-bad.txt +36 -0
- data/spec/fixtures/X220-BE834/3-good.txt +26 -0
- data/spec/fixtures/X220-BE834/4-bad.txt +27 -0
- data/spec/fixtures/X220-BE834/4-good.txt +21 -0
- data/spec/fixtures/X220-BE834/5-bad.txt +26 -0
- data/spec/fixtures/X220-BE834/5-good.txt +17 -0
- data/spec/fixtures/X220-BE834/6-bad.txt +25 -0
- data/spec/fixtures/X220-BE834/6-good.txt +20 -0
- data/spec/fixtures/X220-BE834/7-bad.txt +25 -0
- data/spec/fixtures/X220-BE834/7-good.txt +20 -0
- data/spec/fixtures/X220-BE834/8-bad.txt +25 -0
- data/spec/fixtures/X220-BE834/8-good.txt +20 -0
- data/spec/fixtures/X220-BE834/9-bad.txt +27 -0
- data/spec/fixtures/X220-BE834/9-good.txt +21 -0
- data/spec/fixtures/X221-HP835/1-bad.txt +58 -0
- data/spec/fixtures/X221-HP835/1-good.txt +40 -0
- data/spec/fixtures/X221-HP835/2-bad.txt +51 -0
- data/spec/fixtures/X221-HP835/2-good.txt +40 -0
- data/spec/fixtures/X221-HP835/3a-bad.txt +78 -0
- data/spec/fixtures/X221-HP835/3a-good.txt +49 -0
- data/spec/fixtures/X221-HP835/3b-bad.txt +60 -0
- data/spec/fixtures/X221-HP835/3b-good.txt +32 -0
- data/spec/fixtures/X221-HP835/3c-bad.txt +55 -0
- data/spec/fixtures/X221-HP835/3c-good.txt +34 -0
- data/spec/fixtures/X222-HC837/1-bad.txt +60 -0
- data/spec/fixtures/X222-HC837/1-good.txt +53 -0
- data/spec/fixtures/X222-HC837/10a-bad.txt +52 -0
- data/spec/fixtures/X222-HC837/10a-good.txt +40 -0
- data/spec/fixtures/X222-HC837/10b-bad.txt +99 -0
- data/spec/fixtures/X222-HC837/10b-good.txt +80 -0
- data/spec/fixtures/X222-HC837/10c-bad.txt +105 -0
- data/spec/fixtures/X222-HC837/10c-good.txt +80 -0
- data/spec/fixtures/X222-HC837/11-bad.txt +69 -0
- data/spec/fixtures/X222-HC837/11-good.txt +45 -0
- data/spec/fixtures/X222-HC837/12-bad.txt +73 -0
- data/spec/fixtures/X222-HC837/12-good.txt +51 -0
- data/spec/fixtures/X222-HC837/13-bad.txt +64 -0
- data/spec/fixtures/X222-HC837/13-good.txt +46 -0
- data/spec/fixtures/X222-HC837/3a-bad.txt +83 -0
- data/spec/fixtures/X222-HC837/3a-good.txt +59 -0
- data/spec/fixtures/X222-HC837/3b-bad.txt +97 -0
- data/spec/fixtures/X222-HC837/3b-good.txt +70 -0
- data/spec/fixtures/X222-HC837/3c-bad.txt +95 -0
- data/spec/fixtures/X222-HC837/3c-good.txt +74 -0
- data/spec/fixtures/X222-HC837/4-bad.txt +67 -0
- data/spec/fixtures/X222-HC837/4-good.txt +48 -0
- data/spec/fixtures/X222-HC837/5-bad.txt +73 -0
- data/spec/fixtures/X222-HC837/5-good.txt +60 -0
- data/spec/fixtures/X222-HC837/6-bad.txt +50 -0
- data/spec/fixtures/X222-HC837/6-good.txt +39 -0
- data/spec/fixtures/X222-HC837/7-bad.txt +93 -0
- data/spec/fixtures/X222-HC837/7-good.txt +78 -0
- data/spec/fixtures/X222-HC837/8-bad.txt +64 -0
- data/spec/fixtures/X222-HC837/8-good.txt +52 -0
- data/spec/fixtures/X222-HC837/9-bad.txt +56 -0
- data/spec/fixtures/X222-HC837/9-good.txt +38 -0
- data/spec/fixtures/X223-HC837/1-bad.txt +66 -0
- data/spec/fixtures/X223-HC837/1-good.txt +53 -0
- data/spec/fixtures/X223-HC837/2-bad.txt +69 -0
- data/spec/fixtures/X223-HC837/2-good.txt +60 -0
- data/spec/fixtures/X223-HC837/3-bad.txt +89 -0
- data/spec/fixtures/X223-HC837/3-good.txt +61 -0
- data/spec/fixtures/X223-HC837/4-bad.txt +60 -0
- data/spec/fixtures/X223-HC837/4-good.txt +40 -0
- data/spec/fixtures/X223-HC837/5-bad.txt +75 -0
- data/spec/fixtures/X223-HC837/5-good.txt +58 -0
- data/spec/fixtures/X224-HC837/1-bad.txt +54 -0
- data/spec/fixtures/X224-HC837/1-good.txt +44 -0
- data/spec/fixtures/X224-HC837/2a-bad.txt +52 -0
- data/spec/fixtures/X224-HC837/2a-good.txt +42 -0
- data/spec/fixtures/X224-HC837/2b-bad.txt +67 -0
- data/spec/fixtures/X224-HC837/2b-good.txt +52 -0
- data/spec/fixtures/X224-HC837/3-bad.txt +67 -0
- data/spec/fixtures/X224-HC837/3-good.txt +51 -0
- data/spec/fixtures/X224-HC837/4-bad.txt +49 -0
- data/spec/fixtures/X224-HC837/4-good.txt +40 -0
- data/spec/fixtures/X230-FA997/1-bad.txt +19 -0
- data/spec/fixtures/X230-FA997/1-good.txt +16 -0
- data/spec/fixtures/X231-FA999/1-bad.txt +20 -0
- data/spec/fixtures/X231-FA999/1-good.txt +20 -0
- data/spec/fixtures/X279-HB271/1-bad.txt +36 -0
- data/spec/fixtures/X279-HB271/1-good.txt +30 -0
- data/spec/fixtures/X279-HB271/2-bad.txt +22 -0
- data/spec/fixtures/X279-HB271/2-good.txt +16 -0
- data/spec/fixtures/X279-HB271/3-bad.txt +44 -0
- data/spec/fixtures/X279-HB271/3-good.txt +36 -0
- data/spec/fixtures/X279-HS270/1-bad.txt +29 -0
- data/spec/fixtures/X279-HS270/1-good.txt +23 -0
- data/spec/fixtures/X279-HS270/2-bad.txt +32 -0
- data/spec/fixtures/X279-HS270/2-good.txt +25 -0
- data/spec/spec_helper.rb +34 -0
- data/spec/support/fixtures.rb +26 -0
- data/spec/support/matchers/either_matchers.rb +26 -0
- data/spec/support/matchers/navigation_matchers.rb +247 -0
- data/spec/support/node.rb +41 -0
- data/spec/support/quickcheck/characters.rb +28 -0
- data/spec/support/quickcheck/property.rb +105 -0
- data/spec/support/quickcheck/serialized_edi.rb +399 -0
- data/spec/support/quickcheck.rb +302 -0
- data/spec/support/rcov.rb +34 -0
- metadata +577 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
module Stupidedi
|
|
2
|
+
module Writer
|
|
3
|
+
|
|
4
|
+
class Claredi
|
|
5
|
+
|
|
6
|
+
def initialize(node)
|
|
7
|
+
@node = node
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# @return [String]
|
|
11
|
+
def write(out = "")
|
|
12
|
+
out << "<html><head>\n#{style}</head>\n<body>\n"
|
|
13
|
+
build(@node, out)
|
|
14
|
+
out << "</body></html>"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
# @return [String]
|
|
20
|
+
def style
|
|
21
|
+
<<-CSS
|
|
22
|
+
<style>
|
|
23
|
+
body { font-size: 0.75em; }
|
|
24
|
+
|
|
25
|
+
.interchange, .functionalgr, .table, .loop > .label {
|
|
26
|
+
font-weight: bold;
|
|
27
|
+
font-family: Georgia;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.interchange, .functionalgr, .transaction {
|
|
31
|
+
margin-left: 1em;
|
|
32
|
+
margin-top: 1em;
|
|
33
|
+
margin-bottom: 1em;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.transaction > .label {
|
|
37
|
+
font-weight: bold;
|
|
38
|
+
font-size: 1.5em;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.table, .loop {
|
|
42
|
+
margin-top: 0.5em;
|
|
43
|
+
margin-bottom: 0.5em;
|
|
44
|
+
margin-right: 0.5em;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.table { margin-left: 1em; margin-bottom: 2em; }
|
|
48
|
+
.table > .label {
|
|
49
|
+
font-size: 1.25em;
|
|
50
|
+
border-bottom: 3px solid black;
|
|
51
|
+
margin-top: 1em;
|
|
52
|
+
margin-bottom: 0.5em;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.loop { border: 1px solid grey; border-left: 0; }
|
|
56
|
+
.loop > .label {
|
|
57
|
+
padding: 3px;
|
|
58
|
+
background-color: #ddd;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.segment {
|
|
62
|
+
display: inline;
|
|
63
|
+
margin-top: 0.25em;
|
|
64
|
+
background-color: #fff;
|
|
65
|
+
font-weight: normal;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.segment > .label {
|
|
69
|
+
font-weight: normal;
|
|
70
|
+
font-family: Consolas, Monospace, monospace;
|
|
71
|
+
}
|
|
72
|
+
</style>
|
|
73
|
+
CSS
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# @return [void]
|
|
77
|
+
def build(node, out = "")
|
|
78
|
+
if node.element?
|
|
79
|
+
|
|
80
|
+
if node.composite?
|
|
81
|
+
out << "*"
|
|
82
|
+
tmp = ""
|
|
83
|
+
node.children.each{|e| build(e, tmp) }
|
|
84
|
+
tmp.gsub!(/:*$/, "")
|
|
85
|
+
out << tmp
|
|
86
|
+
elsif node.component?
|
|
87
|
+
out << "#{node}:"
|
|
88
|
+
elsif node.repeated?
|
|
89
|
+
out << "^"
|
|
90
|
+
node.children.each{|e| build(e, out) }
|
|
91
|
+
else
|
|
92
|
+
out << "*#{node}"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
elsif node.segment?
|
|
96
|
+
out << "<div class=segment><div class=label title='#{node.definition.name}'>"
|
|
97
|
+
out << '% 3s' % node.definition.id
|
|
98
|
+
# out << ": #{node.definition.name}</div></div>\n"
|
|
99
|
+
tmp = ""
|
|
100
|
+
node.children.each{|e| build(e, tmp) }
|
|
101
|
+
tmp.gsub!(/\**$/, "")
|
|
102
|
+
out << "#{tmp}~</div></div>\n"
|
|
103
|
+
|
|
104
|
+
elsif node.loop?
|
|
105
|
+
m = /^(\w+) (.+)$/.match(node.definition.id)
|
|
106
|
+
id, name = m.captures
|
|
107
|
+
name = name.split(/\s+/).map(&:capitalize).join(" ")
|
|
108
|
+
|
|
109
|
+
out << "<div class=loop><div class=label>#{name} (#{id})</div>\n"
|
|
110
|
+
node.children.each{|c| build(c, out) }
|
|
111
|
+
out << "</div>\n"
|
|
112
|
+
|
|
113
|
+
elsif node.table?
|
|
114
|
+
out << "<div class=table><div class=label>#{node.definition.id}</div>\n"
|
|
115
|
+
node.children.each{|c| build(c, out) }
|
|
116
|
+
out << "</div>\n"
|
|
117
|
+
|
|
118
|
+
elsif node.transaction_set?
|
|
119
|
+
out << "<div class=transaction><div class=label>Transaction Set #{node.definition.id}</div>\n"
|
|
120
|
+
node.children.each{|c| build(c, out) }
|
|
121
|
+
out << "</div>\n"
|
|
122
|
+
|
|
123
|
+
elsif node.functional_group?
|
|
124
|
+
out << "<div class=functionalgr><div class=label>Functional Group #{node.definition.id}</div>\n"
|
|
125
|
+
node.children.each{|c| build(c, out) }
|
|
126
|
+
out << "</div>\n"
|
|
127
|
+
|
|
128
|
+
elsif node.interchange?
|
|
129
|
+
out << "<div class=interchange><div class=label>Interchange #{node.definition.id}</div>\n"
|
|
130
|
+
node.children.each{|c| build(c, out) }
|
|
131
|
+
out << "</div>\n"
|
|
132
|
+
|
|
133
|
+
elsif node.transmission?
|
|
134
|
+
out << "<div class=transmission>\n"
|
|
135
|
+
node.children.each{|c| build(c, out) }
|
|
136
|
+
out << "</div>\n"
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
end
|
|
142
|
+
end
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
module Stupidedi
|
|
2
|
+
module Writer
|
|
3
|
+
|
|
4
|
+
class Default
|
|
5
|
+
|
|
6
|
+
# @return [Reader::Separators]
|
|
7
|
+
attr_reader :separators
|
|
8
|
+
|
|
9
|
+
def initialize(zipper, separators = Reader::Separators.empty)
|
|
10
|
+
@zipper, @separators =
|
|
11
|
+
zipper, separators
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
#
|
|
15
|
+
# @return out
|
|
16
|
+
def write(out = "")
|
|
17
|
+
common = @separators.characters & @zipper.node.characters
|
|
18
|
+
message = common.to_a.map(&:inspect).join(", ")
|
|
19
|
+
|
|
20
|
+
if common.present?
|
|
21
|
+
raise Exceptions::OutputError,
|
|
22
|
+
"separators #{message} occur as data"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
recurse(@zipper.node, @separators, out)
|
|
26
|
+
return out
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def recurse(value, separators, out)
|
|
32
|
+
return if value.invalid?
|
|
33
|
+
|
|
34
|
+
if value.segment?
|
|
35
|
+
segment(value, separators, out)
|
|
36
|
+
else
|
|
37
|
+
if value.interchange?
|
|
38
|
+
separators = value.separators.merge(@separators)
|
|
39
|
+
|
|
40
|
+
raise Exceptions::OutputError,
|
|
41
|
+
"separators.segment cannot be blank" if separators.segment.empty?
|
|
42
|
+
|
|
43
|
+
raise Exceptions::OutputError,
|
|
44
|
+
"separators.element cannot be blank" if separators.element.blank?
|
|
45
|
+
|
|
46
|
+
unless separators == @separators
|
|
47
|
+
# We've inherited some separators from the interchange,
|
|
48
|
+
# so we need to re-check this condition. Note that we
|
|
49
|
+
# can't optimize this by caching @zipper.node.characters
|
|
50
|
+
# the first time (in #write), because we're only interested
|
|
51
|
+
# in conflicts between _this_ subtree (value) and the
|
|
52
|
+
# separators... not the entire tree (@zipper.node)
|
|
53
|
+
common = separators.characters & @zipper.node.characters
|
|
54
|
+
message = common.to_a.map(&:inspect).join(", ")
|
|
55
|
+
|
|
56
|
+
if common.present?
|
|
57
|
+
raise Exceptions::OutputError,
|
|
58
|
+
"separator characters #{message} occur as data"
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
value.children.each{|c| recurse(c, separators, out) }
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def segment(s, separators, out)
|
|
68
|
+
# It's likely annoying for the user to need to check for at least
|
|
69
|
+
# one non-blank element before generating a segment. Instead, we
|
|
70
|
+
# can check that after the segment was generated and supress any
|
|
71
|
+
# empty segments here.
|
|
72
|
+
return if s.empty?
|
|
73
|
+
|
|
74
|
+
out << s.id.to_s
|
|
75
|
+
|
|
76
|
+
# Trailing empty elements (including component elements) can be omitted,
|
|
77
|
+
# so "NM1*XX*1:2::::*****~" should be abbreviated to "NM1*XX*1:2~".
|
|
78
|
+
elements = s.children.
|
|
79
|
+
reverse.drop_while(&:empty?).reverse # Remove the trailing empties
|
|
80
|
+
|
|
81
|
+
elements.each do |e|
|
|
82
|
+
out << separators.element
|
|
83
|
+
element(e, separators, out)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
out << separators.segment
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def element(e, separators, out)
|
|
90
|
+
if e.simple?
|
|
91
|
+
out << e.to_x12
|
|
92
|
+
|
|
93
|
+
elsif e.composite?
|
|
94
|
+
components = e.children.
|
|
95
|
+
reverse.drop_while(&:empty?).reverse
|
|
96
|
+
|
|
97
|
+
unless components.empty?
|
|
98
|
+
out << components.head.to_x12
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
components.tail.each do |c|
|
|
102
|
+
out << separators.component
|
|
103
|
+
out << c.to_x12
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
elsif e.repeated?
|
|
107
|
+
occurrences = e.children.
|
|
108
|
+
reverse.drop_while(&:empty?).reverse
|
|
109
|
+
|
|
110
|
+
unless occurrences.empty?
|
|
111
|
+
element(occurrences.head, separators, out)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
occurrences.tail.each do |o|
|
|
115
|
+
out << separators.repetition
|
|
116
|
+
element(occurrences.head, separators, out)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
module Stupidedi
|
|
2
|
+
module Zipper
|
|
3
|
+
|
|
4
|
+
class AbstractCursor
|
|
5
|
+
|
|
6
|
+
# @return [#leaf?, #children, #copy]
|
|
7
|
+
abstract :node
|
|
8
|
+
|
|
9
|
+
# @return [AbstractPath]
|
|
10
|
+
abstract :path
|
|
11
|
+
|
|
12
|
+
# @group Querying the Tree Location
|
|
13
|
+
#########################################################################
|
|
14
|
+
|
|
15
|
+
# (see AbstractPath#depth)
|
|
16
|
+
def depth
|
|
17
|
+
path.depth
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# (see AbstractPath#first?)
|
|
21
|
+
def first?
|
|
22
|
+
path.first?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# (see AbstractPath#last?)
|
|
26
|
+
def last?
|
|
27
|
+
path.last?
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# True if the node has no children
|
|
31
|
+
abstract :leaf?
|
|
32
|
+
|
|
33
|
+
# True if the node has no parent
|
|
34
|
+
abstract :root?
|
|
35
|
+
|
|
36
|
+
# Returns nodes between this zipper and the other, including `self.node`
|
|
37
|
+
# and `other.node` as end points. When this and the other zipper point to
|
|
38
|
+
# the same node within the tree, a single node is returned. Otherwise, the
|
|
39
|
+
# nodes are returned in order according to a left-to-right depth-first
|
|
40
|
+
# pre-order traversal.
|
|
41
|
+
#
|
|
42
|
+
# @note This method assumes `other` is a zipper for the same tree as the
|
|
43
|
+
# tree wrapped by `this`. In general, there is no way to know if that is
|
|
44
|
+
# or isn't the case, without comparing the entire tree. If this method
|
|
45
|
+
# is called on two different trees, the results are undefined.
|
|
46
|
+
#
|
|
47
|
+
# @return [Array]
|
|
48
|
+
def between(other)
|
|
49
|
+
# Collect ancestors of self, sorted oldest first (deepest last). This
|
|
50
|
+
# forms a boundary of nodes, which is called a "spine" below
|
|
51
|
+
zipper = self
|
|
52
|
+
lspine = [self]
|
|
53
|
+
|
|
54
|
+
until zipper.root?
|
|
55
|
+
zipper = zipper.up
|
|
56
|
+
lspine.unshift(zipper)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Collect ancestors of self, sorted oldest first (deepest last). This
|
|
60
|
+
# forms a list of boundary nodes, which is called a "spine" below
|
|
61
|
+
zipper = other
|
|
62
|
+
rspine = [other]
|
|
63
|
+
|
|
64
|
+
until zipper.root?
|
|
65
|
+
zipper = zipper.up
|
|
66
|
+
rspine.unshift(zipper)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Now we have two spines, both beginning with the root node. We remove
|
|
70
|
+
# the prefix common to both spines.
|
|
71
|
+
while a = lspine.first and b = rspine.first
|
|
72
|
+
if a.path == b.path
|
|
73
|
+
lspine.shift
|
|
74
|
+
rspine.shift
|
|
75
|
+
else
|
|
76
|
+
break
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
if lspine.empty?
|
|
81
|
+
# The other node is a child of self's node, and rspine contains all
|
|
82
|
+
# the nodes along the path between the two nodes, not including the
|
|
83
|
+
# self node.
|
|
84
|
+
return node.cons(rspine.map(&:node))
|
|
85
|
+
|
|
86
|
+
elsif rspine.empty?
|
|
87
|
+
# Self's node is a child of other's node, and lspine contains all
|
|
88
|
+
# the nodes along the path between the two nodes, not including the
|
|
89
|
+
# other node
|
|
90
|
+
return other.node.cons(lspine.map(&:node))
|
|
91
|
+
|
|
92
|
+
elsif lspine.head.path.position > rspine.head.path.position
|
|
93
|
+
# The first elements of lspine and rspine are siblings that share a
|
|
94
|
+
# common parent. Arrange them such that lspine is on the left, and
|
|
95
|
+
# so rspine is on the right
|
|
96
|
+
lspine, rspine = rspine, lspine
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
between = []
|
|
100
|
+
|
|
101
|
+
# Starting at the bottom of the left spine working upward, accumulate
|
|
102
|
+
# all the nodes to the right of the spine. Remember this is contained
|
|
103
|
+
# within the subtree under lspine.head
|
|
104
|
+
lspine.each{|z| between << z.node }
|
|
105
|
+
lspine.tail.reverse.each do |zipper|
|
|
106
|
+
until zipper.last?
|
|
107
|
+
zipper = zipper.next
|
|
108
|
+
between.concat(zipper.flatten)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# For the sibling nodes directly between (not including) lspine.head
|
|
113
|
+
# and rspine.head, we can accumulate the entire subtrees.
|
|
114
|
+
count = rspine.head.path.position - lspine.head.path.position - 1
|
|
115
|
+
zipper = lspine.head
|
|
116
|
+
|
|
117
|
+
count.times do
|
|
118
|
+
zipper = zipper.next
|
|
119
|
+
between.concat(zipper.flatten)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
between << rspine.head.node
|
|
123
|
+
|
|
124
|
+
rspine.tail.each do |zipper|
|
|
125
|
+
count = zipper.path.position
|
|
126
|
+
zipper = zipper.first
|
|
127
|
+
|
|
128
|
+
# We have to do a bit more work to traverse the siblings in left-to-
|
|
129
|
+
# right order, because `zipper` is now the left spine. We start on
|
|
130
|
+
# the first sibling and move left a fixed number of times
|
|
131
|
+
count.times do
|
|
132
|
+
between.concat(zipper.flatten)
|
|
133
|
+
zipper = zipper.next
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Now zipper is along the left spine. We don't expand it here, but the
|
|
137
|
+
# next item in rspine is the next child along the left spine
|
|
138
|
+
between << zipper.node
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
between
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Flattens the subtree into an Array of nodes. The nodes are arranged
|
|
145
|
+
# according to a depth-first left-to-right preorder traversal.
|
|
146
|
+
#
|
|
147
|
+
# @return [Array]
|
|
148
|
+
def flatten
|
|
149
|
+
nodes = []
|
|
150
|
+
queue = [node]
|
|
151
|
+
|
|
152
|
+
while node = queue.shift
|
|
153
|
+
nodes << node
|
|
154
|
+
queue.unshift(*node.children) unless node.leaf?
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
nodes
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# @group Traversing the Tree
|
|
161
|
+
#########################################################################
|
|
162
|
+
|
|
163
|
+
# Navigate to the first child node
|
|
164
|
+
#
|
|
165
|
+
# @return [MemoizedCursor]
|
|
166
|
+
def down
|
|
167
|
+
@__down ||= begin
|
|
168
|
+
if leaf?
|
|
169
|
+
raise Exceptions::ZipperError,
|
|
170
|
+
"cannot descend into leaf node"
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
head, *tail = @node.children
|
|
174
|
+
|
|
175
|
+
MemoizedCursor.new(head,
|
|
176
|
+
Hole.new([], @path, tail), self)
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Navigate to the first child node, or if there are no children,
|
|
181
|
+
# create a placeholder where the first child node will be placed
|
|
182
|
+
#
|
|
183
|
+
# @return [AbstractCursor]
|
|
184
|
+
def dangle
|
|
185
|
+
if node.leaf?
|
|
186
|
+
raise Exceptions::ZipperError,
|
|
187
|
+
"cannot descend into leaf node"
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
if leaf?
|
|
191
|
+
DanglingCursor.new(self)
|
|
192
|
+
else
|
|
193
|
+
down
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Navigate to the `nth` child node
|
|
198
|
+
#
|
|
199
|
+
# @return [AbstractCursor]
|
|
200
|
+
def child(n)
|
|
201
|
+
if n < 0
|
|
202
|
+
raise Exceptions::ZipperError,
|
|
203
|
+
"child index cannot be negative"
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
cursor = down
|
|
207
|
+
until n.zero?
|
|
208
|
+
cursor = cursor.next
|
|
209
|
+
n -= 1
|
|
210
|
+
end
|
|
211
|
+
cursor
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# Returns a list of cursors, one pointing to each child node.
|
|
215
|
+
#
|
|
216
|
+
# @return [Array<MemoizedCursor>]
|
|
217
|
+
def children
|
|
218
|
+
children = []
|
|
219
|
+
|
|
220
|
+
unless leaf?
|
|
221
|
+
zipper = down
|
|
222
|
+
children << zipper
|
|
223
|
+
|
|
224
|
+
until zipper.last?
|
|
225
|
+
zipper = zipper.next
|
|
226
|
+
children << zipper
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
children
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# Recursively descend to each node's `nth` child
|
|
234
|
+
#
|
|
235
|
+
# @return [AbstractCursor]
|
|
236
|
+
def descendant(n, *ns)
|
|
237
|
+
cursor = self
|
|
238
|
+
|
|
239
|
+
n.cons(ns).each do |n|
|
|
240
|
+
cursor = cursor.child(n)
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
cursor
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# Navigate to the parent node
|
|
247
|
+
#
|
|
248
|
+
# @return [AbstractCursor]
|
|
249
|
+
abstract :up
|
|
250
|
+
|
|
251
|
+
# Navigate to the next (rightward) sibling node
|
|
252
|
+
#
|
|
253
|
+
# @return [AbstractCursor]
|
|
254
|
+
abstract :next
|
|
255
|
+
|
|
256
|
+
# Navigate to the previous (leftward) sibling node
|
|
257
|
+
#
|
|
258
|
+
# @return [AbstractCursor]
|
|
259
|
+
abstract :prev
|
|
260
|
+
|
|
261
|
+
# Navigate to the first (leftmost) sibling node
|
|
262
|
+
#
|
|
263
|
+
# @return [AbstractCursor]
|
|
264
|
+
abstract :first
|
|
265
|
+
|
|
266
|
+
# Navigate to the last (rightmost) sibling node
|
|
267
|
+
#
|
|
268
|
+
# @return [AbstractCursor]
|
|
269
|
+
abstract :last
|
|
270
|
+
|
|
271
|
+
# Navigate to the root node
|
|
272
|
+
#
|
|
273
|
+
# @return [RootCursor]
|
|
274
|
+
def root
|
|
275
|
+
cursor = self
|
|
276
|
+
cursor = cursor.up until cursor.root?
|
|
277
|
+
cursor
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
# @group Editing the Tree
|
|
281
|
+
#########################################################################
|
|
282
|
+
|
|
283
|
+
# Insert a new sibling node after (to the right of) the current node,
|
|
284
|
+
# and navigate to the new sibling node
|
|
285
|
+
#
|
|
286
|
+
# @return [EditedCursor]
|
|
287
|
+
abstract :append, :args => %w(sibling)
|
|
288
|
+
|
|
289
|
+
# Insert a new sibling node before (to the left of) the current node,
|
|
290
|
+
# and navigate to the new sibling node
|
|
291
|
+
#
|
|
292
|
+
# @return [EditedCursor]
|
|
293
|
+
abstract :prepend, :args => %w(sibling)
|
|
294
|
+
|
|
295
|
+
# (see #append)
|
|
296
|
+
def insert_right(sibling)
|
|
297
|
+
append(sibling)
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# (see #prepend)
|
|
301
|
+
def insert_left(sibling)
|
|
302
|
+
prepend(sibling)
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# Insert a new child node before (to the left of) any existing children
|
|
306
|
+
# nodes and navigate to the new child node
|
|
307
|
+
#
|
|
308
|
+
# @return [EditedCursor]
|
|
309
|
+
def prepend_child(child)
|
|
310
|
+
if node.leaf?
|
|
311
|
+
raise Exceptions::ZipperError,
|
|
312
|
+
"cannot add child to leaf node"
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
EditedCursor.new(child,
|
|
316
|
+
Hole.new([], path, node.children), self)
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
# Insert a new child node after (to the right of) any existing children
|
|
320
|
+
# nodes and navigate to the new child node
|
|
321
|
+
#
|
|
322
|
+
# @return [EditedCursor]
|
|
323
|
+
def append_child(child)
|
|
324
|
+
if node.leaf?
|
|
325
|
+
raise Exceptions::ZipperError,
|
|
326
|
+
"cannot add child to leaf node"
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
EditedCursor.new(child,
|
|
330
|
+
Hole.new(node.children.reverse, path, []), self)
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
# Replace the current node with the given node
|
|
334
|
+
#
|
|
335
|
+
# @return [AbstractCursor]
|
|
336
|
+
abstract :replace, :args => %w(node)
|
|
337
|
+
|
|
338
|
+
# Remove the current node, and navigate to the next (rightward) node if
|
|
339
|
+
# one exists. Otherwise, navigate to the previous (leftward) node if one
|
|
340
|
+
# exists. Otherwise, create a placeholder where the next sibling node will
|
|
341
|
+
# be created.
|
|
342
|
+
#
|
|
343
|
+
# @return [EditedCursor]
|
|
344
|
+
abstract :delete
|
|
345
|
+
|
|
346
|
+
# @endgroup
|
|
347
|
+
#########################################################################
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
end
|
|
351
|
+
end
|