asciichem 0.4.1 → 0.5.1
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/lib/asciichem/cml/extensions.rb +34 -3
- data/lib/asciichem/formatter/text.rb +41 -1
- data/lib/asciichem/grammar.rb +40 -1
- data/lib/asciichem/model/calculation.rb +34 -0
- data/lib/asciichem/model/mechanism.rb +34 -0
- data/lib/asciichem/model/zmatrix.rb +36 -0
- data/lib/asciichem/model.rb +3 -0
- data/lib/asciichem/transform.rb +156 -0
- data/lib/asciichem/version.rb +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1edf476bb3d979641172de761d1b2ac906cb4eaf8565e56b0e083e146c09eb1d
|
|
4
|
+
data.tar.gz: b3394a0709a475df222d6369eac92a1cc6d02fc756a7d3a45ca038c5d6f5155c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5a1ce9a990e507a6f70c91939841766e228b02ae674af39c5fa356b4911f20d0ef3b5aa2f2ec4799663d21da54752ed9b68c6660db23e1b2da9cacd4cc50b2ad
|
|
7
|
+
data.tar.gz: 6d68778aca7042fce958026033e990e51b87290c24ed3028cf224aa34bd5e03418ef6209b72072d06a14ab3352e2d20290c939b4002a82fdcdbe5c267a17d087
|
|
@@ -245,9 +245,40 @@ module AsciiChem
|
|
|
245
245
|
TopLevelHandler.new(
|
|
246
246
|
node_class: AsciiChem::Model::Text,
|
|
247
247
|
element_name: 'text',
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
248
|
+
serialize: ->(node) { text_render(node) },
|
|
249
|
+
deserialize: ->(content) { AsciiChem.parse(content).nodes.first }
|
|
250
|
+
),
|
|
251
|
+
# -- beyond-formulas constructs (Phase 1-5) -------------------
|
|
252
|
+
# Each carries its text representation inside an aci: element.
|
|
253
|
+
# On parse, the text is re-parsed to rebuild the construct.
|
|
254
|
+
# DRY: all five share the same serialize/deserialize pattern.
|
|
255
|
+
TopLevelHandler.new(
|
|
256
|
+
node_class: AsciiChem::Model::Crystal,
|
|
257
|
+
element_name: 'crystal',
|
|
258
|
+
serialize: ->(node) { text_render(node) },
|
|
259
|
+
deserialize: ->(content) { AsciiChem.parse(content).nodes.first }
|
|
260
|
+
),
|
|
261
|
+
TopLevelHandler.new(
|
|
262
|
+
node_class: AsciiChem::Model::Spectrum,
|
|
263
|
+
element_name: 'spectrum',
|
|
264
|
+
serialize: ->(node) { text_render(node) },
|
|
265
|
+
deserialize: ->(content) { AsciiChem.parse(content).nodes.first }
|
|
266
|
+
),
|
|
267
|
+
TopLevelHandler.new(
|
|
268
|
+
node_class: AsciiChem::Model::Calculation,
|
|
269
|
+
element_name: 'calculation',
|
|
270
|
+
serialize: ->(node) { text_render(node) },
|
|
271
|
+
deserialize: ->(content) { AsciiChem.parse(content).nodes.first }
|
|
272
|
+
),
|
|
273
|
+
TopLevelHandler.new(
|
|
274
|
+
node_class: AsciiChem::Model::ZMatrix,
|
|
275
|
+
element_name: 'zmatrix',
|
|
276
|
+
serialize: ->(node) { text_render(node) },
|
|
277
|
+
deserialize: ->(content) { AsciiChem.parse(content).nodes.first }
|
|
278
|
+
),
|
|
279
|
+
TopLevelHandler.new(
|
|
280
|
+
node_class: AsciiChem::Model::Mechanism,
|
|
281
|
+
element_name: 'mechanism',
|
|
251
282
|
serialize: ->(node) { text_render(node) },
|
|
252
283
|
deserialize: ->(content) { AsciiChem.parse(content).nodes.first }
|
|
253
284
|
)
|
|
@@ -158,7 +158,47 @@ module AsciiChem
|
|
|
158
158
|
parts.join
|
|
159
159
|
end
|
|
160
160
|
|
|
161
|
-
|
|
161
|
+
def visit_calculation(calc)
|
|
162
|
+
parts = ["calc"]
|
|
163
|
+
params = []
|
|
164
|
+
params << calc.method if calc.method
|
|
165
|
+
params << calc.basis if calc.basis
|
|
166
|
+
parts << "(#{params.join('/')})" unless params.empty?
|
|
167
|
+
unless calc.properties.empty?
|
|
168
|
+
lines = calc.properties.map do |p|
|
|
169
|
+
line = "#{p[:title]}: #{p[:value]}"
|
|
170
|
+
line += " #{p[:units]}" if p[:units]
|
|
171
|
+
line
|
|
172
|
+
end
|
|
173
|
+
parts << "{\n #{lines.join("\n ")}\n}"
|
|
174
|
+
end
|
|
175
|
+
parts.join
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def visit_z_matrix(zm)
|
|
179
|
+
parts = ["zmatrix"]
|
|
180
|
+
unless zm.rows.empty?
|
|
181
|
+
lines = zm.rows.map do |row|
|
|
182
|
+
tokens = [row.atom]
|
|
183
|
+
tokens << row.ref1 << row.distance if row.ref1
|
|
184
|
+
tokens << row.ref2 << row.angle if row.ref2
|
|
185
|
+
tokens << row.ref3 << row.dihedral if row.ref3
|
|
186
|
+
tokens.compact.join(" ")
|
|
187
|
+
end
|
|
188
|
+
parts << "{\n #{lines.join("\n ")}\n}"
|
|
189
|
+
end
|
|
190
|
+
parts.join
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def visit_mechanism(mech)
|
|
194
|
+
parts = ["mechanism"]
|
|
195
|
+
unless mech.steps.empty? && mech.spectators.empty?
|
|
196
|
+
lines = mech.steps.map { |s| "#{s[:label]}: #{s[:reaction]}" }
|
|
197
|
+
mech.spectators.each { |sp| lines << "spectator: #{sp}" }
|
|
198
|
+
parts << "{\n #{lines.join("\n ")}\n}"
|
|
199
|
+
end
|
|
200
|
+
parts.join
|
|
201
|
+
end
|
|
162
202
|
|
|
163
203
|
def render_node(node)
|
|
164
204
|
node.accept(self)
|
data/lib/asciichem/grammar.rb
CHANGED
|
@@ -27,7 +27,7 @@ module AsciiChem
|
|
|
27
27
|
|
|
28
28
|
rule(:nodes) { node >> (spaces? >> node).repeat }
|
|
29
29
|
|
|
30
|
-
rule(:node) { reaction_cascade | reaction | electron_config | crystal | spectrum | annotated_molecule | molecule | embedded_math | text_run.as(:text_run) }
|
|
30
|
+
rule(:node) { reaction_cascade | reaction | electron_config | crystal | spectrum | calculation | zmatrix | mechanism | annotated_molecule | molecule | embedded_math | text_run.as(:text_run) }
|
|
31
31
|
|
|
32
32
|
# -- crystallography -------------------------------------------------
|
|
33
33
|
|
|
@@ -73,6 +73,45 @@ module AsciiChem
|
|
|
73
73
|
str('{') >> (str('}').absent? >> any).repeat.as(:spectrum_body) >> str('}')
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
+
# -- computational chemistry ----------------------------------------
|
|
77
|
+
|
|
78
|
+
# calc(method/basis){key: value units}
|
|
79
|
+
rule(:calculation) do
|
|
80
|
+
(str('calc') >>
|
|
81
|
+
calc_params.maybe >>
|
|
82
|
+
calc_body.maybe).as(:calc_node)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
rule(:calc_params) do
|
|
86
|
+
str('(') >> (str(')').absent? >> any).repeat.as(:calc_params) >> str(')')
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
rule(:calc_body) do
|
|
90
|
+
str('{') >> (str('}').absent? >> any).repeat.as(:calc_body) >> str('}')
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# -- Z-Matrix -------------------------------------------------------
|
|
94
|
+
|
|
95
|
+
rule(:zmatrix) do
|
|
96
|
+
(str('zmatrix') >>
|
|
97
|
+
zmatrix_body.maybe).as(:zmatrix_node)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
rule(:zmatrix_body) do
|
|
101
|
+
str('{') >> (str('}').absent? >> any).repeat.as(:zmatrix_body) >> str('}')
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# -- reaction mechanisms --------------------------------------------
|
|
105
|
+
|
|
106
|
+
rule(:mechanism) do
|
|
107
|
+
(str('mechanism') >>
|
|
108
|
+
mechanism_body.maybe).as(:mechanism_node)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
rule(:mechanism_body) do
|
|
112
|
+
str('{') >> (str('}').absent? >> any).repeat.as(:mechanism_body) >> str('}')
|
|
113
|
+
end
|
|
114
|
+
|
|
76
115
|
# Annotated molecule: a molecule followed by one or more
|
|
77
116
|
# `@key("value")` annotations for CML metadata (names,
|
|
78
117
|
# identifiers, title, formula, labels).
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AsciiChem
|
|
4
|
+
module Model
|
|
5
|
+
# A computational chemistry calculation result.
|
|
6
|
+
#
|
|
7
|
+
# Syntax:
|
|
8
|
+
# calc(b3lyp/6-31G*){
|
|
9
|
+
# energy: -234.5 Hartree
|
|
10
|
+
# dipole: [0.1, 0.2, 0.3] Debye
|
|
11
|
+
# }
|
|
12
|
+
class Calculation < Node
|
|
13
|
+
attr_accessor :method, :basis, :properties
|
|
14
|
+
|
|
15
|
+
def initialize(method: nil, basis: nil, properties: [])
|
|
16
|
+
@method = method
|
|
17
|
+
@basis = basis
|
|
18
|
+
@properties = properties
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def value_attributes
|
|
22
|
+
{ method: method, basis: basis, properties: properties }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def children
|
|
26
|
+
[]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def diagnostic_label
|
|
30
|
+
"Calculation(#{method}/#{basis})"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AsciiChem
|
|
4
|
+
module Model
|
|
5
|
+
# A reaction mechanism: multi-step pathway with spectators.
|
|
6
|
+
#
|
|
7
|
+
# Syntax:
|
|
8
|
+
# mechanism{
|
|
9
|
+
# step1: A + B -> C
|
|
10
|
+
# step2: C -> D + E
|
|
11
|
+
# spectator: Na+
|
|
12
|
+
# }
|
|
13
|
+
class Mechanism < Node
|
|
14
|
+
attr_accessor :steps, :spectators
|
|
15
|
+
|
|
16
|
+
def initialize(steps: [], spectators: [])
|
|
17
|
+
@steps = steps
|
|
18
|
+
@spectators = spectators
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def value_attributes
|
|
22
|
+
{ steps: steps, spectators: spectators }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def children
|
|
26
|
+
[]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def diagnostic_label
|
|
30
|
+
"Mechanism(#{steps.length} steps)"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AsciiChem
|
|
4
|
+
module Model
|
|
5
|
+
# A Z-Matrix: internal coordinates (bond lengths, angles, torsions).
|
|
6
|
+
#
|
|
7
|
+
# Syntax:
|
|
8
|
+
# zmatrix{
|
|
9
|
+
# C1
|
|
10
|
+
# H2 C1 1.09
|
|
11
|
+
# H3 C1 1.09 H2 109.5
|
|
12
|
+
# H4 C1 1.09 H2 109.5 H3 120.0
|
|
13
|
+
# }
|
|
14
|
+
class ZMatrix < Node
|
|
15
|
+
ZRow = Struct.new(:atom, :ref1, :distance, :ref2, :angle, :ref3, :dihedral, keyword_init: true)
|
|
16
|
+
|
|
17
|
+
attr_accessor :rows
|
|
18
|
+
|
|
19
|
+
def initialize(rows: [])
|
|
20
|
+
@rows = rows
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def value_attributes
|
|
24
|
+
{ rows: rows }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def children
|
|
28
|
+
[]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def diagnostic_label
|
|
32
|
+
"ZMatrix(#{rows.length} rows)"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/asciichem/model.rb
CHANGED
|
@@ -8,12 +8,14 @@ module AsciiChem
|
|
|
8
8
|
module Model
|
|
9
9
|
autoload :Atom, "asciichem/model/atom"
|
|
10
10
|
autoload :Bond, "asciichem/model/bond"
|
|
11
|
+
autoload :Calculation, "asciichem/model/calculation"
|
|
11
12
|
autoload :Crystal, "asciichem/model/crystal"
|
|
12
13
|
autoload :ElectronConfiguration, "asciichem/model/electron_configuration"
|
|
13
14
|
autoload :EmbeddedMath, "asciichem/model/embedded_math"
|
|
14
15
|
autoload :Formula, "asciichem/model/formula"
|
|
15
16
|
autoload :Group, "asciichem/model/group"
|
|
16
17
|
autoload :Identifier, "asciichem/model/identifier"
|
|
18
|
+
autoload :Mechanism, "asciichem/model/mechanism"
|
|
17
19
|
autoload :Molecule, "asciichem/model/molecule"
|
|
18
20
|
autoload :Name, "asciichem/model/name"
|
|
19
21
|
autoload :Node, "asciichem/model/node"
|
|
@@ -21,5 +23,6 @@ module AsciiChem
|
|
|
21
23
|
autoload :ReactionCascade, "asciichem/model/reaction_cascade"
|
|
22
24
|
autoload :Spectrum, "asciichem/model/spectrum"
|
|
23
25
|
autoload :Text, "asciichem/model/text"
|
|
26
|
+
autoload :ZMatrix, "asciichem/model/zmatrix"
|
|
24
27
|
end
|
|
25
28
|
end
|
data/lib/asciichem/transform.rb
CHANGED
|
@@ -171,6 +171,27 @@ module AsciiChem
|
|
|
171
171
|
).build
|
|
172
172
|
end
|
|
173
173
|
|
|
174
|
+
# -- computational chemistry ----------------------------------------
|
|
175
|
+
|
|
176
|
+
rule(calc_node: subtree(:data)) do
|
|
177
|
+
hash = data.is_a?(Hash) ? data : {}
|
|
178
|
+
CalculationBuilder.new(hash[:calc_params], hash[:calc_body]).build
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# -- Z-Matrix -------------------------------------------------------
|
|
182
|
+
|
|
183
|
+
rule(zmatrix_node: subtree(:data)) do
|
|
184
|
+
hash = data.is_a?(Hash) ? data : {}
|
|
185
|
+
ZMatrixBuilder.new(hash[:zmatrix_body]).build
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# -- reaction mechanisms --------------------------------------------
|
|
189
|
+
|
|
190
|
+
rule(mechanism_node: subtree(:data)) do
|
|
191
|
+
hash = data.is_a?(Hash) ? data : {}
|
|
192
|
+
MechanismBuilder.new(hash[:mechanism_body]).build
|
|
193
|
+
end
|
|
194
|
+
|
|
174
195
|
# -- internal helpers ------------------------------------------------
|
|
175
196
|
|
|
176
197
|
# Builds a Crystal from parsed grammar captures. The grammar
|
|
@@ -292,6 +313,141 @@ module AsciiChem
|
|
|
292
313
|
end
|
|
293
314
|
end
|
|
294
315
|
|
|
316
|
+
# Builds a Calculation from grammar captures.
|
|
317
|
+
# Params: "method/basis" string. Body: key-value lines.
|
|
318
|
+
class CalculationBuilder
|
|
319
|
+
def initialize(params_str, body_str)
|
|
320
|
+
@params_str = strip_value(params_str)
|
|
321
|
+
@body_str = strip_value(body_str)
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
def build
|
|
325
|
+
method, basis = parse_method_basis(@params_str)
|
|
326
|
+
Model::Calculation.new(
|
|
327
|
+
method: method,
|
|
328
|
+
basis: basis,
|
|
329
|
+
properties: parse_properties(@body_str)
|
|
330
|
+
)
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
private
|
|
334
|
+
|
|
335
|
+
def strip_value(value)
|
|
336
|
+
return nil if value.nil?
|
|
337
|
+
|
|
338
|
+
s = value.to_s.strip
|
|
339
|
+
s.empty? ? nil : s
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
def parse_method_basis(str)
|
|
343
|
+
return [nil, nil] unless str
|
|
344
|
+
|
|
345
|
+
parts = str.split('/', 2)
|
|
346
|
+
[parts[0]&.strip, parts[1]&.strip]
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
def parse_properties(str)
|
|
350
|
+
return [] unless str
|
|
351
|
+
|
|
352
|
+
str.split("\n").filter_map do |line|
|
|
353
|
+
line = line.strip
|
|
354
|
+
next nil if line.empty?
|
|
355
|
+
|
|
356
|
+
key, rest = line.split(':', 2)
|
|
357
|
+
next nil unless key
|
|
358
|
+
|
|
359
|
+
tokens = rest&.strip&.split(/\s+/) || []
|
|
360
|
+
{ title: key.strip, value: tokens[0], units: tokens[1] }
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
# Builds a ZMatrix from grammar captures.
|
|
366
|
+
# Each body line: atom [ref1 distance] [ref2 angle] [ref3 dihedral]
|
|
367
|
+
class ZMatrixBuilder
|
|
368
|
+
def initialize(body_str)
|
|
369
|
+
@body_str = strip_value(body_str)
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
def build
|
|
373
|
+
Model::ZMatrix.new(rows: parse_rows(@body_str))
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
private
|
|
377
|
+
|
|
378
|
+
def strip_value(value)
|
|
379
|
+
return nil if value.nil?
|
|
380
|
+
|
|
381
|
+
s = value.to_s.strip
|
|
382
|
+
s.empty? ? nil : s
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
def parse_rows(str)
|
|
386
|
+
return [] unless str
|
|
387
|
+
|
|
388
|
+
str.split("\n").filter_map { |line| parse_row(line.strip) }
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
def parse_row(line)
|
|
392
|
+
return nil if line.empty?
|
|
393
|
+
|
|
394
|
+
tokens = line.split(/\s+/)
|
|
395
|
+
Model::ZMatrix::ZRow.new(
|
|
396
|
+
atom: tokens[0],
|
|
397
|
+
ref1: tokens[1],
|
|
398
|
+
distance: tokens[2],
|
|
399
|
+
ref2: tokens[3],
|
|
400
|
+
angle: tokens[4],
|
|
401
|
+
ref3: tokens[5],
|
|
402
|
+
dihedral: tokens[6]
|
|
403
|
+
)
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
# Builds a Mechanism from grammar captures.
|
|
408
|
+
# Each body line: key: value (step1: reaction, spectator: ion)
|
|
409
|
+
class MechanismBuilder
|
|
410
|
+
def initialize(body_str)
|
|
411
|
+
@body_str = strip_value(body_str)
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
def build
|
|
415
|
+
steps = []
|
|
416
|
+
spectators = []
|
|
417
|
+
parse_entries(@body_str).each do |key, value|
|
|
418
|
+
if key == 'spectator'
|
|
419
|
+
spectators.concat(value.split(/\s+/).map(&:strip))
|
|
420
|
+
else
|
|
421
|
+
steps << { label: key, reaction: value }
|
|
422
|
+
end
|
|
423
|
+
end
|
|
424
|
+
Model::Mechanism.new(steps: steps, spectators: spectators)
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
private
|
|
428
|
+
|
|
429
|
+
def strip_value(value)
|
|
430
|
+
return nil if value.nil?
|
|
431
|
+
|
|
432
|
+
s = value.to_s.strip
|
|
433
|
+
s.empty? ? nil : s
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
def parse_entries(str)
|
|
437
|
+
return [] unless str
|
|
438
|
+
|
|
439
|
+
str.split("\n").filter_map do |line|
|
|
440
|
+
line = line.strip
|
|
441
|
+
next nil if line.empty?
|
|
442
|
+
|
|
443
|
+
key, val = line.split(':', 2)
|
|
444
|
+
next nil unless key && val
|
|
445
|
+
|
|
446
|
+
[key.strip, val.strip]
|
|
447
|
+
end
|
|
448
|
+
end
|
|
449
|
+
end
|
|
450
|
+
|
|
295
451
|
# Strips the surrounding `"..."` quotes from a quoted text match.
|
|
296
452
|
# Used by both `text_run` and `group_text_run` rules so the
|
|
297
453
|
# model never carries the delimiters — the formatter re-adds them
|
data/lib/asciichem/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: asciichem
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -155,12 +155,14 @@ files:
|
|
|
155
155
|
- lib/asciichem/model.rb
|
|
156
156
|
- lib/asciichem/model/atom.rb
|
|
157
157
|
- lib/asciichem/model/bond.rb
|
|
158
|
+
- lib/asciichem/model/calculation.rb
|
|
158
159
|
- lib/asciichem/model/crystal.rb
|
|
159
160
|
- lib/asciichem/model/electron_configuration.rb
|
|
160
161
|
- lib/asciichem/model/embedded_math.rb
|
|
161
162
|
- lib/asciichem/model/formula.rb
|
|
162
163
|
- lib/asciichem/model/group.rb
|
|
163
164
|
- lib/asciichem/model/identifier.rb
|
|
165
|
+
- lib/asciichem/model/mechanism.rb
|
|
164
166
|
- lib/asciichem/model/molecule.rb
|
|
165
167
|
- lib/asciichem/model/name.rb
|
|
166
168
|
- lib/asciichem/model/node.rb
|
|
@@ -168,6 +170,7 @@ files:
|
|
|
168
170
|
- lib/asciichem/model/reaction_cascade.rb
|
|
169
171
|
- lib/asciichem/model/spectrum.rb
|
|
170
172
|
- lib/asciichem/model/text.rb
|
|
173
|
+
- lib/asciichem/model/zmatrix.rb
|
|
171
174
|
- lib/asciichem/model_adapter.rb
|
|
172
175
|
- lib/asciichem/model_adapter/from_canonical.rb
|
|
173
176
|
- lib/asciichem/model_adapter/to_canonical.rb
|