asciichem 0.31.12 → 0.31.13
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/CHANGELOG.md +15 -0
- data/README.adoc +85 -0
- data/lib/asciichem/resolver.rb +11 -4
- data/lib/asciichem/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 13b35ffffbfa3349f95961b56e7dae9e74d55a116554a76c1175f3f74e347183
|
|
4
|
+
data.tar.gz: ea78a952280a73728fbd27cff80af8e3eebf163e45b8428ece6171a588471b55
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 538a97d2151764c9c84026ecccf32380ca82393158ac56d85af050aceab459ca47eb23a7828fb48bb5ed9fbe8289b11d2a5583bd8bd8b96f40ee20002247d5d8
|
|
7
|
+
data.tar.gz: 6edff89d3e29935de3227db81ef9126d6d7ce46cf0c39d58343114522d88205de9d969d99f760e6bd8602bc71f85fd80310b8730684769c31ec9aa21fa8f0413
|
data/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,21 @@
|
|
|
3
3
|
All notable changes to AsciiChem are documented here.
|
|
4
4
|
This project follows [Semantic Versioning](https://semver.org/).
|
|
5
5
|
|
|
6
|
+
## [0.31.13] - 2026-11-11
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
- `Resolver.resolve_all` isolates source-level failures: a live probe
|
|
10
|
+
found the Common Chemistry API now answers 401 without an API key
|
|
11
|
+
(CAS key-gated the endpoint); with it registered by default, that
|
|
12
|
+
401 raised through the multi-source fan-out and took the other
|
|
13
|
+
sources down with it. A source-level error now skips that source —
|
|
14
|
+
callers see what answered.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- The README documents the full capability surface: structures,
|
|
18
|
+
lint, local identity, resolution with provenance, citations, and
|
|
19
|
+
the command line.
|
|
20
|
+
|
|
6
21
|
## [0.31.12] - 2026-11-11
|
|
7
22
|
|
|
8
23
|
### Changed
|
data/README.adoc
CHANGED
|
@@ -45,6 +45,91 @@ formula.to_mathml # => "<math>...</math>"
|
|
|
45
45
|
formula.to_text # => "H_2O" (round trip)
|
|
46
46
|
----
|
|
47
47
|
|
|
48
|
+
The parsed model is the canonical form: MathML, HTML, LaTeX, text,
|
|
49
|
+
linear and 2D structural SVG, and CML are views over the same tree.
|
|
50
|
+
|
|
51
|
+
=== Structures: SMILES and molfile in, AsciiChem out
|
|
52
|
+
|
|
53
|
+
[source,ruby]
|
|
54
|
+
----
|
|
55
|
+
formula = AsciiChem.parse_smiles("CC(=O)Oc1ccccc1C(=O)O")
|
|
56
|
+
formula.to_structural_svg # 2D depiction, deterministic layout
|
|
57
|
+
formula.to_smiles # canonical aromatic SMILES
|
|
58
|
+
formula.to_text # AsciiChem text
|
|
59
|
+
|
|
60
|
+
formula = AsciiChem.parse_molfile(molfile_text) # V2000 in and out
|
|
61
|
+
----
|
|
62
|
+
|
|
63
|
+
=== Lint
|
|
64
|
+
|
|
65
|
+
[source,ruby]
|
|
66
|
+
----
|
|
67
|
+
AsciiChem::Linter.run(formula) # chemistry diagnostics: balance,
|
|
68
|
+
# valence, charge, isotopes, rings,
|
|
69
|
+
# identifier consistency, ...
|
|
70
|
+
AsciiChem::Linter.errors?(formula) # => true/false
|
|
71
|
+
----
|
|
72
|
+
|
|
73
|
+
=== Local identity: InChI, AuxInfo, InChIKey
|
|
74
|
+
|
|
75
|
+
[source,ruby]
|
|
76
|
+
----
|
|
77
|
+
require "asciichem/inchi"
|
|
78
|
+
|
|
79
|
+
# the native chemomer engine (byte-exact vs the IUPAC oracle;
|
|
80
|
+
# CHEMOMER_LIB points at the built cdylib) or the IUPAC binary:
|
|
81
|
+
AsciiChem::Inchi.engine = AsciiChem::Inchi::NativeEngine.new
|
|
82
|
+
|
|
83
|
+
identity = AsciiChem::Inchi.identity_for(molecule)
|
|
84
|
+
identity.inchi # "InChI=1S/C9H8O4/..."
|
|
85
|
+
identity.inchikey # "BSYNRYMUTXBXSQ-UHFFFAOYSA-N"
|
|
86
|
+
----
|
|
87
|
+
|
|
88
|
+
=== Resolution: identifiers to substance records
|
|
89
|
+
|
|
90
|
+
[source,ruby]
|
|
91
|
+
----
|
|
92
|
+
require "asciichem/resolver"
|
|
93
|
+
|
|
94
|
+
substance = AsciiChem::Resolver.resolve(value: "50-78-2", convention: "cas")
|
|
95
|
+
substance.preferred_name # => "Aspirin"
|
|
96
|
+
substance.structure.to_smiles # from the source record
|
|
97
|
+
substance.identifiers.first.provenance.source # "common_chemistry"
|
|
98
|
+
|
|
99
|
+
# all shipped sources (PubChem, OPSIN, CAS Common Chemistry) resolve
|
|
100
|
+
# by default; attribution rides every record. Limit the set when a
|
|
101
|
+
# use must stay NC-free:
|
|
102
|
+
AsciiChem::Resolver.resolve(value: "50-78-2", convention: "cas",
|
|
103
|
+
sources: [:pubchem, :opsin])
|
|
104
|
+
----
|
|
105
|
+
|
|
106
|
+
=== Citations: dataset bibitems with provenance
|
|
107
|
+
|
|
108
|
+
[source,ruby]
|
|
109
|
+
----
|
|
110
|
+
require "asciichem/citation"
|
|
111
|
+
|
|
112
|
+
molecule = AsciiChem.parse("CC(=O)OC1=CC=CC=C1C(=O)O @cas(\"50-78-2\") @cite(\"pubchem\")").nodes.first
|
|
113
|
+
AsciiChem::Citation.for_molecule(molecule)
|
|
114
|
+
# => [["pubchem", #<Relaton bibitem>]] - one dataset-type bibitem per
|
|
115
|
+
# (substance, source), anchored by InChIKey, with a provenance note
|
|
116
|
+
# (retrieved from, version, attribution).
|
|
117
|
+
----
|
|
118
|
+
|
|
119
|
+
== Command line
|
|
120
|
+
|
|
121
|
+
[source,sh]
|
|
122
|
+
----
|
|
123
|
+
asciichem convert -i "H_2O" -t mathml # also: --from smiles|molfile
|
|
124
|
+
asciichem identity -i aspirin.smiles --from smiles
|
|
125
|
+
asciichem resolve --cas 50-78-2 --source common_chemistry
|
|
126
|
+
asciichem validate -i 'H_2O @cas("50-78-2")'
|
|
127
|
+
asciichem cite --cas 50-78-2 -t model-json
|
|
128
|
+
asciichem lint -i "2H_2 + O_2 -> 2H_2O"
|
|
129
|
+
asciichem roundtrip -i "C_6H_12O_6"
|
|
130
|
+
asciichem parse-cml -i formula.xml
|
|
131
|
+
----
|
|
132
|
+
|
|
48
133
|
== Conformance
|
|
49
134
|
|
|
50
135
|
The reference implementation of https://www.asciichem.org[the AsciiChem
|
data/lib/asciichem/resolver.rb
CHANGED
|
@@ -43,16 +43,23 @@ module AsciiChem
|
|
|
43
43
|
raise Error, "unknown resolver source #{name.inspect} (registered: #{adapters.keys.sort.join(', ')})"
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
# Resolves against every
|
|
47
|
-
# per source that answers (nil
|
|
48
|
-
# in registration order.
|
|
46
|
+
# Resolves against every registered source (or the selected
|
|
47
|
+
# subset), returning one Substance per source that answers (nil
|
|
48
|
+
# entries dropped). Sources answer in registration order. A
|
|
49
|
+
# source-level failure (HTTP error, rejected request) skips that
|
|
50
|
+
# source — one dead or key-gated endpoint must not poison the
|
|
51
|
+
# others; callers see what answered.
|
|
49
52
|
def resolve_all(value:, convention:, sources: nil, fetch: nil, cache: nil, refresh: false)
|
|
50
53
|
selected = sources ? Array(sources).map { |s| self[s] } : adapters.values
|
|
51
54
|
selected.filter_map do |adapter_class|
|
|
52
55
|
adapter = adapter_class.new
|
|
53
56
|
next unless adapter.supports?(convention)
|
|
54
57
|
|
|
55
|
-
|
|
58
|
+
begin
|
|
59
|
+
adapter.resolve(value: value, convention: convention, fetch: fetch, cache: cache, refresh: refresh)
|
|
60
|
+
rescue AsciiChem::Error
|
|
61
|
+
nil
|
|
62
|
+
end
|
|
56
63
|
end
|
|
57
64
|
end
|
|
58
65
|
|
data/lib/asciichem/version.rb
CHANGED