lens_protocol 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/.rubocop.yml +98 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +106 -0
- data/Guardfile +42 -0
- data/LICENSE.txt +21 -0
- data/README.md +69 -0
- data/Rakefile +6 -0
- data/bin/console +11 -0
- data/bin/setup +8 -0
- data/examples/images/R360_1.png +0 -0
- data/examples/oma/R1000_1.oma +213 -0
- data/examples/oma/R1000_2.oma +213 -0
- data/examples/oma/R1000_3.oma +217 -0
- data/examples/oma/R360_1.oma +78 -0
- data/examples/oma/R360_2.oma +75 -0
- data/examples/oma/R360_3.oma +276 -0
- data/examples/oma/TRCFMT6.oma +28 -0
- data/examples/public/styles.css +22 -0
- data/examples/svg.rb +10 -0
- data/examples/views/index.erb +26 -0
- data/lens_protocol.gemspec +33 -0
- data/lib/lens_protocol.rb +18 -0
- data/lib/lens_protocol/errors.rb +10 -0
- data/lib/lens_protocol/oma.rb +14 -0
- data/lib/lens_protocol/oma/formatter.rb +22 -0
- data/lib/lens_protocol/oma/message.rb +138 -0
- data/lib/lens_protocol/oma/parser.rb +24 -0
- data/lib/lens_protocol/oma/record.rb +19 -0
- data/lib/lens_protocol/oma/type/base.rb +97 -0
- data/lib/lens_protocol/oma/type/integer.rb +15 -0
- data/lib/lens_protocol/oma/type/numeric.rb +24 -0
- data/lib/lens_protocol/oma/type/r.rb +17 -0
- data/lib/lens_protocol/oma/type/text.rb +8 -0
- data/lib/lens_protocol/oma/type/trcfmt.rb +30 -0
- data/lib/lens_protocol/oma/types.rb +84 -0
- data/lib/lens_protocol/svg.rb +45 -0
- data/lib/lens_protocol/version.rb +3 -0
- metadata +213 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
REQ=FIL
|
2
|
+
DO=B
|
3
|
+
BEVM=0.00;0.00
|
4
|
+
BEVP=4;4
|
5
|
+
CIRC=151.860;151.860
|
6
|
+
DBL=17.00
|
7
|
+
ETYP=3
|
8
|
+
FCSGIN=1.50;1.50
|
9
|
+
FCSGUP=4.00;4.00
|
10
|
+
FPINB=0.00;0.00
|
11
|
+
FTYP=3
|
12
|
+
GDEPTH=0.50;0.50
|
13
|
+
GWIDTH=0.60;0.60
|
14
|
+
HBOX=53.99;53.99
|
15
|
+
NPD=34.00;34.00
|
16
|
+
IPD=34.00;34.00
|
17
|
+
SEGHT=22.00;22.00
|
18
|
+
OCHT=22.00;22.00
|
19
|
+
PINB=0.20;0.20
|
20
|
+
POLISH=1
|
21
|
+
TRCFMT=6;360;E;R;F
|
22
|
+
R=6167514141436D71764D2B7958762F524C337855574A4939485372724B525553742B3733737151776F5A554871777046704B39455452706378337A4744544C4F48397961556D33657938627A63394D6B4E415A766E7A46626F4B462B586962644874692F435071432F445670717044755936734274304E797536472F356D4E44305474302F56584D4D75614441743566346662484B474C6A4C314E67433765703562424B7474584D495945753730534A6A45776A4575384A783930624F326D782B67715A6E6F466A4E6D51724C325A3334467945614646615A2B423264793066505A4D6B64585968584E3259504E6744713235574D634B353233494A304D746B5865347A346E776D6E6B6136635649576357475A32454133634A68624D2F63616C494F38724B4C7556584F7176634A4B567768336A387762767430422F636633766537502F31784173694F366173424134695A727970324249757657495051756C5364684F4B327043387A75344C534367544F54424A6F42384B41356449674A506B523678697146796B52464230686E4142594C684E2B73385059636D5A4E675362494F454542514D745A664A75395145743957674C4149754E32737A42494872384B302F376C375965792F364C7131597661416C4D4E3954345853595138685964624F617571674E7843554C4634736458635469485272354D2B5533712F6D477A6E656F6B5673654B7245517A675754625248474A667A3341593242576C6E733169466D6A53516F485335586863597854676274435955666B376A36466E32576136464D6572736E44516874374379656D44615441782F314A47377A526E716777504C506F4D6F6D422F54766D63324B4757306933746C4750386E4A614A684D6549636E504145433761534A347A35516353666A50442F4448385855764431424A4456304D387A6E4871636C32614B346B4B7754444D39317264514B3148526A6A695A69773942774E69484878583246475641582F4F2B752F666467375574784E7A6B7159573841437177327741304D3976322B3032694B66755A7A534856576E4E656941382F384148714F76494B646136692B53634F6B4F6A6A7478777975697767724752386833613677314C444D666255443157707544354C795867554D3651637274463963784D497547674374387563334B48786F57567738472F484A3961625731506B624749473173524D4C346255556D4F684678766F75434E637879314C314F4E703331445530655979726F654C357849444B5937426C51415872464A564A336F6B4A32632B4A76587A2B4576552F67446944457749665177735A34596556306253422F567151546B6A786A584C6D6574336D714B4775477A61697063326F75332B617637567A3753424C567835396F667878646741666F5854657A473949306F5A31485A7057314B35556331762F435743705A38784C395569316E34575936393757612F336C69416B7447386D6D55336E5465486F6134344379696A617073537078716A344D344678454F755763375336635A4E6454502B476A543570415935633037396A4D69493636713931445033472B5669347A5833306B797565342B5A486D646B4A69366349694275506A49786755723849494438746B5258303751644F2F496F6F556A716B6E735455416E472F526D6E41764332434C515257704D7A4D6930454D6E5866574B636E6D6F487552504A63374D5235535744396D444D54393274786655753949436E3045435761755933386E374663553436526F51376564687235346431615166507044786A6552756F6468303144745267647A4A7661506630596D534270636E486137723769317036526D6D7637574A61624747516965796A6C32424D494A785373632F3762746D302F745A6D6237723974675A2B6D6F515A7A6B4C53536A45576F385A356A324D4D58446E586C2B316B5A7462497174653875726F7A7773724A43386F7A6D595259443273346750346F4A5A374B3970364A636D75644D665633496762554B706F6E716C56505469497076762F71494C375231356349582B322F3538494732736D35427236657044572F4C7759616D51514867794D55636B
|
23
|
+
TRCFMT=6;360;E;L;F
|
24
|
+
R=61675141414D4E6C4D58334355662F61433866447949556F7A747534612B36753438664A634F5967394F7137657A625A5052714652573954624B5572744852493458362B756951372F544A6441424673366C2F464B3143714E62664B30396D583939512B54346C644E3967563173657948302F7938614D62586B67756553396E3171474D6C54766E48666844334E3070365A4E414C6441694E4D685A6E43373851594E4B495533794C37553331434B4E44585251426C46763063484B6248437476664B58794E6A75584362634665396A596C30786A3366596C4C5466414D6F5A706F73536F484D44563072455A7663352F7334594954494B5A432B635237684941427874526633746430757571573058762B48615432736C2F4366397642343174574959536B575A4C366E2B634E6A706468722B46357468573068637A6F396845705472516C43304D717077776C683535646F4C514E31625041704D3175724D4F6937483052594178517734674645754E5441666B307056695A4D4E2B73467A584A5434436A654E7961676D6C4E3843694E6C674A35316A544E33566E5756554E6645634C4F7059752F73314E53445A7869733973626970642F593277635751467975627175394D5954764E666977653655704D514A6D5038537879372F726973593570435969303245722F424D7A525A564B6262437356314D646134446C4A38316F4D45614C617044656A2B4F4F6C7550774D70704E5245696D5862587346505159335549645872564864624375302B30333353654F574443336E6C6E336F6B4E506A45485739686D48564F493454456B6B65786F4C6C506C69394F454C2B476D53536832757A526B62795550525975697A5673417559763638655A775548556245555A6C4753594436646770733659766B726C524532793278644C3451556F55534368305678442B577149686D31705843764D4E4656616848643157336641514F57344E6D335452624B47594A786C6F326A4A46344557565A5A452F425844655230396555414968424567736B474E794B657731765A78384F7949646443486A726670457367337A4F6F734A677755685765436E466A51763571413069696F56507468726F67466568583668457351754635507A526E677047574A746A5059652F446E79764476386530685869346A744E4F4D377657394B744B696D6E76324E744C71387358794F6535494B723261773845746E766D78626867367A43685342767A74585A5238337838796A7367344B7675304B535663547763656A5777735A4277457A482B58484966416F7366584D5A363065705053697746304F3359317349394C75693149534F396B58537577684A41435A6D767A71655167304D6456414C36476433564B6A5853355658547A7071793054307A69452F5235483636326C763151636B436F36724B44502B4D505163446567486B5744502B4E702B426175677A6F31564742353271634441777741494168566E71307356694153474E732B2F66644D4237544239576F797A4444584F55665A4C717068796F6E536556467448376D70482F4E786669485439483878465950346265665061332F624661466D2B797359616B546450555255785A67487869443872784F385678314C6B56303035737045776E39537278334A513077765977715150387A5555793234426C3355567A356977497331794A494762502B73574148417255705254566575697A5149536A347538314C524E6974576F5356363742466C426E7473324D624465336869684D36394939652F53596C4255696A6D4F3949706959336D377A6137425933716D504E694561395A71676C463434776E48574F74336D6E4730697476363948536F324752336F7352474F545266687A616C6E6C4B68544C613746674B443639796A6A2F376934326630547153366F56595A747264386A6844687963657773564E6A787873386350665851664F6A2B4C636C3358796E7A69726E45437071785A484332714B305653506A452F676670796F4547756E4756723946674F64706779304359496F69315A576B3936522F717457366567336B51344C4274646962562F4676796D6C79637274356865364251
|
25
|
+
VBOX=36.00;36.00
|
26
|
+
VEN=NDKVCA
|
27
|
+
HVER=4.0
|
28
|
+
FED=57.18;57.18
|
@@ -0,0 +1,22 @@
|
|
1
|
+
body {
|
2
|
+
display: grid;
|
3
|
+
grid-template-columns: repeat(auto-fit, minmax(450px, 1fr));
|
4
|
+
grid-gap: 1em;
|
5
|
+
}
|
6
|
+
|
7
|
+
.lenses-container {
|
8
|
+
vertical-align: top;
|
9
|
+
white-space: nowrap;
|
10
|
+
text-align: center;
|
11
|
+
}
|
12
|
+
|
13
|
+
.lens {
|
14
|
+
width: 200px;
|
15
|
+
display: inline-block;
|
16
|
+
padding: 10px;
|
17
|
+
}
|
18
|
+
|
19
|
+
.lens svg {
|
20
|
+
stroke: black;
|
21
|
+
fill: #eee;
|
22
|
+
}
|
data/examples/svg.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'lens_protocol'
|
3
|
+
|
4
|
+
get '/' do
|
5
|
+
files_and_messages = Dir['examples/oma/*.oma'].map do |file|
|
6
|
+
[File.basename(file), LensProtocol::OMA.parse(File.read(file))]
|
7
|
+
end
|
8
|
+
|
9
|
+
erb :index, locals: {files_and_messages: files_and_messages}
|
10
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<link rel="stylesheet" href="styles.css">
|
5
|
+
<title>SVG Demo</title>
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<% files_and_messages.each do |(filename, message)| %>
|
9
|
+
<div class="lenses-container">
|
10
|
+
<div class="filename"><%= filename %></div>
|
11
|
+
|
12
|
+
<% if (svgs = message.to_svg).any? %>
|
13
|
+
<% svgs.map do |svg| %>
|
14
|
+
<div class="lens">
|
15
|
+
<%= svg %>
|
16
|
+
</div>
|
17
|
+
<% end %>
|
18
|
+
<% else %>
|
19
|
+
<div>
|
20
|
+
Could not recognize tracing data.
|
21
|
+
</div>
|
22
|
+
<% end %>
|
23
|
+
</div>
|
24
|
+
<% end %>
|
25
|
+
</body>
|
26
|
+
</html>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
lib = File.expand_path("lib", __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "lens_protocol/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "lens_protocol"
|
7
|
+
spec.version = LensProtocol::VERSION
|
8
|
+
spec.authors = ["Emmanuel Nicolau"]
|
9
|
+
spec.email = ["emmanicolau@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = %q{LensProtocol is a Ruby parser and builder for the OMA protocol.}
|
12
|
+
spec.description = %q{A Ruby parser and builder for the OMA protocol (a.k.a. Data Communication Standard) that was developed by the Lens Processing & Technology Division of The Vision Council for interconnection of optical laboratory equipment.}
|
13
|
+
spec.homepage = "https://github.com/eeng/lens_protocol"
|
14
|
+
|
15
|
+
# Specify which files should be added to the gem when it is released.
|
16
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
17
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
18
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
19
|
+
end
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_dependency 'activesupport', '>= 4.0'
|
25
|
+
spec.add_dependency 'nokogiri'
|
26
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
27
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
28
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
29
|
+
spec.add_development_dependency "guard-rspec"
|
30
|
+
spec.add_development_dependency 'pry'
|
31
|
+
spec.add_development_dependency 'pry-byebug'
|
32
|
+
spec.add_development_dependency 'sinatra'
|
33
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext/object/blank'
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'lens_protocol/version'
|
5
|
+
require 'lens_protocol/errors'
|
6
|
+
require 'lens_protocol/oma/record'
|
7
|
+
require 'lens_protocol/oma/message'
|
8
|
+
require 'lens_protocol/oma/type/base'
|
9
|
+
require 'lens_protocol/oma/type/text'
|
10
|
+
require 'lens_protocol/oma/type/integer'
|
11
|
+
require 'lens_protocol/oma/type/numeric'
|
12
|
+
require 'lens_protocol/oma/type/trcfmt'
|
13
|
+
require 'lens_protocol/oma/type/r'
|
14
|
+
require 'lens_protocol/oma/types'
|
15
|
+
require 'lens_protocol/oma/parser'
|
16
|
+
require 'lens_protocol/oma/formatter'
|
17
|
+
require 'lens_protocol/oma'
|
18
|
+
require 'lens_protocol/svg'
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module LensProtocol
|
2
|
+
module OMA
|
3
|
+
class Formatter
|
4
|
+
# Generates the OMA string from a Message
|
5
|
+
def format message, line_separator: "\r\n", start_of_message: '', end_of_message: '', **opts
|
6
|
+
[
|
7
|
+
start_of_message,
|
8
|
+
format_lines(message, **opts).join(line_separator),
|
9
|
+
line_separator,
|
10
|
+
end_of_message
|
11
|
+
].join
|
12
|
+
end
|
13
|
+
|
14
|
+
def format_lines message, types: {}
|
15
|
+
types = TYPES.merge(types)
|
16
|
+
message.records.values.flat_map do |record|
|
17
|
+
types[record.label].format(record, message)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
module LensProtocol
|
2
|
+
module OMA
|
3
|
+
class Message
|
4
|
+
attr_reader :records
|
5
|
+
|
6
|
+
# Builds a message from a hash of record labels to record value.
|
7
|
+
def self.from_hash hash
|
8
|
+
hash.reduce new do |message, (label, value)|
|
9
|
+
message.add_record(label, value)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize records: {}, context: {}
|
14
|
+
@records = records
|
15
|
+
@context = context
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_record label, value
|
19
|
+
@records[label] ||= Record.new(label: label, value: value)
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_record_or_insert_values label, values
|
24
|
+
@records[label] ||= Record.new(label: label, value: [])
|
25
|
+
@records[label].value << values
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def add_record_or_concat_values label, values
|
30
|
+
@records[label] ||= Record.new(label: label, value: [])
|
31
|
+
@records[label].value.concat values
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_record_side_values label, side, values
|
36
|
+
@records[label] ||= Record.new(label: label, value: [[], []])
|
37
|
+
@records[label].value[side].concat values
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def set_context key, value
|
42
|
+
@context[key] = value
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def value_of label, default = nil
|
47
|
+
if include? label
|
48
|
+
@records[label].value
|
49
|
+
else
|
50
|
+
default
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns +true+ if the message contains a record with the given label
|
55
|
+
def include? label
|
56
|
+
@records.key? label
|
57
|
+
end
|
58
|
+
|
59
|
+
def empty?
|
60
|
+
@records.empty?
|
61
|
+
end
|
62
|
+
|
63
|
+
def context key
|
64
|
+
@context[key]
|
65
|
+
end
|
66
|
+
|
67
|
+
def to_hash
|
68
|
+
Hash[*@records.flat_map { |label, record| [label, record.value] }]
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns the "R" reconds decoded radiuses according to the tracing format.
|
72
|
+
def radius_data
|
73
|
+
return [] unless value_of('TRCFMT') && value_of('R')
|
74
|
+
[0, 1].map do |side|
|
75
|
+
format_number, = value_of('TRCFMT')[side]
|
76
|
+
case format_number.to_i
|
77
|
+
when 0 # side not present
|
78
|
+
[]
|
79
|
+
when 1 # ASCII format
|
80
|
+
value_of('R')[side]
|
81
|
+
else # unknown format
|
82
|
+
return []
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Converts the "R" record values to polar coordinates.
|
88
|
+
def tracing_in_polar_coordinates
|
89
|
+
radius_data.map { |radiuses| radiuses_to_polar radiuses }
|
90
|
+
end
|
91
|
+
|
92
|
+
def radiuses_to_polar radiuses
|
93
|
+
radiuses.map.with_index { |r, i| [i * 2 * Math::PI / radiuses.size, r] }
|
94
|
+
end
|
95
|
+
|
96
|
+
# Converts the "R" record values to rectangular coordinates.
|
97
|
+
def tracing_in_rectangular_coordinates
|
98
|
+
radius_data.map { |radiuses| radiuses_to_rectangular radiuses }
|
99
|
+
end
|
100
|
+
|
101
|
+
def radiuses_to_rectangular radiuses
|
102
|
+
radiuses_to_polar(radiuses).map { |(a, r)| [r * Math.cos(a), r * Math.sin(a)].map { |v| v.round 2 } }
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns an array of SVG strings, one for each side. If the tracing format is not recognized
|
106
|
+
# or there is no tracing data, returns an empty array.
|
107
|
+
def to_svg **opts
|
108
|
+
SVG.from_message self, **opts
|
109
|
+
end
|
110
|
+
|
111
|
+
# Similarly to +Hash#merge+ returns a new message containing the records of +this+ and the records of +other+
|
112
|
+
# keeping the ones in +other+ if the labels colides.
|
113
|
+
def merge other
|
114
|
+
Message.new records: @records.merge(other.records)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Returns a new message without the records of the given labels.
|
118
|
+
# @param labels [Array]
|
119
|
+
def except labels
|
120
|
+
Message.new records: @records.reject { |label, _| labels.include? label }
|
121
|
+
end
|
122
|
+
|
123
|
+
# Returns a new message with only the records of the given labels.
|
124
|
+
# @param labels [Array]
|
125
|
+
def only labels
|
126
|
+
Message.new records: @records.slice(*labels)
|
127
|
+
end
|
128
|
+
|
129
|
+
def remove_empty_records
|
130
|
+
Message.new records: @records.reject { |_, r| r.empty? }
|
131
|
+
end
|
132
|
+
|
133
|
+
def to_s
|
134
|
+
OMA.format self
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module LensProtocol
|
2
|
+
module OMA
|
3
|
+
class Parser
|
4
|
+
def parse oma_str, types: {}
|
5
|
+
types = TYPES.merge(types)
|
6
|
+
normalize_line_endings(oma_str)
|
7
|
+
.split("\n")
|
8
|
+
.reduce(Message.new) { |message, line| parse_line line, message, types }
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def parse_line line, message, types
|
14
|
+
raise ParsingError.new('The label separator is missing', line) unless line.include?('=')
|
15
|
+
label, = line.split('=')
|
16
|
+
types[label].parse(line, message)
|
17
|
+
end
|
18
|
+
|
19
|
+
def normalize_line_endings str
|
20
|
+
str.to_s.gsub /\r\n?/, "\n"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module LensProtocol
|
2
|
+
module OMA
|
3
|
+
class Record
|
4
|
+
attr_reader :label
|
5
|
+
|
6
|
+
# May hold a single value, an array of values (on multi-value and chiral records), or an array of array of values (in R records for example)
|
7
|
+
attr_reader :value
|
8
|
+
|
9
|
+
def initialize label:, value:
|
10
|
+
@label = label
|
11
|
+
@value = value
|
12
|
+
end
|
13
|
+
|
14
|
+
def empty?
|
15
|
+
Array(value).select(&:present?).empty?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module LensProtocol
|
2
|
+
module OMA
|
3
|
+
module Type
|
4
|
+
class Base
|
5
|
+
def initialize mode: :single_value
|
6
|
+
@mode = mode
|
7
|
+
end
|
8
|
+
|
9
|
+
# Given a line and a message produces a new message with the record(s) corresponding to that line added to the message
|
10
|
+
# @return [Message]
|
11
|
+
def parse line, message
|
12
|
+
label, data = label_and_data line
|
13
|
+
case @mode
|
14
|
+
when :single_value
|
15
|
+
message.add_record label, parse_value(data)
|
16
|
+
when :array_of_values
|
17
|
+
message.add_record_or_concat_values label, parse_values(data)
|
18
|
+
when :chiral
|
19
|
+
message.add_record label, parse_chiral(data)
|
20
|
+
when :matrix_of_values
|
21
|
+
message.add_record_or_insert_values label, parse_values(data)
|
22
|
+
else
|
23
|
+
raise ArgumentError, "Mode #{@mode} not supported"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Array of lines or a single one]
|
28
|
+
def format record, _message
|
29
|
+
case @mode
|
30
|
+
when :single_value
|
31
|
+
format_line record.label, [format_value(record.value)]
|
32
|
+
when :array_of_values
|
33
|
+
format_line record.label, format_values(record.value)
|
34
|
+
when :chiral
|
35
|
+
format_line record.label, format_chiral(record.value)
|
36
|
+
when :matrix_of_values
|
37
|
+
record.value.map do |value|
|
38
|
+
format_line record.label, format_values(value)
|
39
|
+
end
|
40
|
+
else
|
41
|
+
raise ArgumentError, "Mode #{@mode} not supported"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def label_and_data line
|
48
|
+
label, data = line.split('=', -1)
|
49
|
+
[label, data]
|
50
|
+
end
|
51
|
+
|
52
|
+
def label_and_values line
|
53
|
+
label, data = label_and_data line
|
54
|
+
[label, parse_values(data)]
|
55
|
+
end
|
56
|
+
|
57
|
+
def parse_values data
|
58
|
+
data.split(';', -1).map { |value| parse_value value }
|
59
|
+
end
|
60
|
+
|
61
|
+
def parse_value value
|
62
|
+
value if value != '?'
|
63
|
+
end
|
64
|
+
|
65
|
+
def parse_chiral values
|
66
|
+
make_chiral parse_values values
|
67
|
+
end
|
68
|
+
|
69
|
+
def make_chiral values
|
70
|
+
if values.size <= 1
|
71
|
+
[values[0], values[0]]
|
72
|
+
else
|
73
|
+
values[0..1]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def format_line label, values
|
78
|
+
"#{label}=#{values.join(';')}"
|
79
|
+
end
|
80
|
+
|
81
|
+
def format_value value
|
82
|
+
value
|
83
|
+
end
|
84
|
+
|
85
|
+
def format_values values
|
86
|
+
values = values.is_a?(Array) ? values : [values]
|
87
|
+
values.map { |v| format_value(v) }
|
88
|
+
end
|
89
|
+
|
90
|
+
def format_chiral value
|
91
|
+
return [] if Array(value).select(&:present?).empty?
|
92
|
+
make_chiral format_values value
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|