asciichem 0.31.10 → 0.31.12

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 11c430e97b570a9f7297e831904c6701db083757a092646536a29d4452a7b302
4
- data.tar.gz: 21cb557a14d1914adec15dbbf8c9820160e7bf4a93bf3a853e6a81c61b4d595c
3
+ metadata.gz: 02ee049d5ed6b808972e18f4ecf7bbf6723b39b8ba7a6342c38a06cd24b3673a
4
+ data.tar.gz: d455c3156215f27e7509fa610769b573a6bb0e6592097f7c4c67357738095e1d
5
5
  SHA512:
6
- metadata.gz: 7b38cae89fed5fff85d89c9dd870915506cb9500b684281801ec2f4000c3da1c9bde273747b83438f7f85ed0a09eac5377499c977a05dd261360b7de57f038be
7
- data.tar.gz: 1a9e53346bdc0d74f99ecc34f525e2a3358054fc8ef97849f23451370ec03841c4adc61c2813c5abb9cdd59b9190a3de2185708c92841c203815fda2000e336b
6
+ metadata.gz: e83e9ce16a0ed8a1b22491c1964d15fc906467c152a5afec383ce4774d073beb591d8011a481216033855abc76e7f3febd377437f8808a6c1620448e17c60539
7
+ data.tar.gz: caeddc2cb2db07543e3ca9b49932a9ed2a0f68461f2f20eb7c6693914d9bf185b8c44cd7f27e5b2d107e0c9cf7ff704bf63a261180f5b6b112e0d2cc8326b28c
data/CHANGELOG.md CHANGED
@@ -3,6 +3,29 @@
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.12] - 2026-11-11
7
+
8
+ ### Changed
9
+ - CAS Common Chemistry resolves by default (maintainer decision:
10
+ CC BY-NC 4.0 acceptable on by default). The adapter self-registers
11
+ like the other sources; every result still carries the required
12
+ attribution. `Citation.for_molecule` accepts a `sources:`
13
+ allow-list so callers can keep resolution NC-free — the
14
+ metanorma plugin exposes it as the `asciichem-sources` document
15
+ attribute.
16
+
17
+ ## [0.31.11] - 2026-11-10
18
+
19
+ ### Added
20
+ - Dataset bibitems carry the resolver provenance as a
21
+ `type="provenance"` note: retrieval source (and version, when
22
+ recorded) plus the source's required attribution — CAS Common
23
+ Chemistry results now carry the CC BY-NC 4.0 terms into the
24
+ rendered document. `Provenance#note_text` renders the record; the
25
+ note is suppressed when it would duplicate publisher/docidentifier.
26
+ The Metanorma plugin and `asciichem cite` inherit it through the
27
+ shared Citation path.
28
+
6
29
  ## [0.31.10] - 2026-11-05
7
30
 
8
31
  ### Changed
data/README.adoc CHANGED
@@ -60,7 +60,7 @@ a level without the green corpus run behind it does not ship.
60
60
  |L1 semantics |yes |wire form validates against the v1 schemas and round-trips; the perception pass (implicit hydrogens, aromatic rings) is corpus-gated
61
61
  |L2 render |yes |MathML byte-goldens, canonical text, and the wire form for every construct
62
62
  |L3 stereo |yes |tetrahedral chirality, directional bonds, wedge/hash; parity-correct canonical SMILES including ring closures
63
- |L4 identity |partial |opt-in InChI engine with stereo layers, OPSIN adapter, identifier cross-check, citation bibitems; CAS source decision pending
63
+ |L4 identity |yes |opt-in InChI engine (binary or native) with stereo layers, OPSIN adapter, identifier cross-check, resolver (PubChem, OPSIN, and Common Chemistry on by default — CC BY-NC attribution carried everywhere; limit sources with `Resolver.resolve(sources:)`), citation bibitems
64
64
  |===
65
65
 
66
66
  TypeScript and Python claim the same levels they pass; see their
@@ -84,9 +84,15 @@ module AsciiChem
84
84
  #
85
85
  # AsciiChem.parse('H_2O @name("water") @cite("pubchem")')
86
86
  # AsciiChem::Citation.for_molecule(formula.nodes.first).map(&:last)
87
- def for_molecule(molecule, cache: nil, fetch: nil)
88
- sources = citation_sources(molecule)
89
- return [] if sources.empty?
87
+ #
88
+ # `sources:` limits the citable set (an allow-list): cited
89
+ # sources outside it are skipped — the document pipeline (the
90
+ # metanorma plugin's `asciichem-sources` attribute) warns about
91
+ # the exclusions; the gem stays silent and total.
92
+ def for_molecule(molecule, cache: nil, fetch: nil, sources: nil)
93
+ citable = citation_sources(molecule)
94
+ citable &= Array(sources).map(&:to_s) if sources
95
+ return [] if citable.empty?
90
96
 
91
97
  convention, value = lookup_key(molecule)
92
98
  unless value
@@ -95,7 +101,7 @@ module AsciiChem
95
101
  '(annotate @cas/@inchikey/@smiles or @name)'
96
102
  end
97
103
 
98
- sources.filter_map do |source|
104
+ citable.filter_map do |source|
99
105
  substance = AsciiChem::Resolver[source].new.resolve(
100
106
  value: value, convention: convention, cache: cache, fetch: fetch
101
107
  )
@@ -108,7 +114,8 @@ module AsciiChem
108
114
  private
109
115
 
110
116
  # The version-independent field payload: one hash describing the
111
- # citation, translated to Relaton objects by RelatonApi.
117
+ # citation, translated to Relaton objects by RelatonApi. The
118
+ # provenance record travels as `notes` (Provenance#note_text).
112
119
  def fields(substance, profile, provenance)
113
120
  publisher = profile.publisher || provenance.source
114
121
  {
@@ -119,7 +126,8 @@ module AsciiChem
119
126
  publisher: publisher,
120
127
  accessed_on: accessed_on(provenance),
121
128
  link: profile.link_for.call(substance),
122
- keywords: substance.identifiers.map { |i| "#{i.convention}=#{i.value}" }
129
+ keywords: substance.identifiers.map { |i| "#{i.convention}=#{i.value}" },
130
+ notes: [provenance.note_text].compact
123
131
  }
124
132
  end
125
133
 
@@ -203,11 +211,23 @@ module AsciiChem
203
211
  docidentifier: [docidentifier(fields[:docid])],
204
212
  contributor: [contributor(fields[:publisher])],
205
213
  date: [Relaton::Bib::Date.new(type: 'accessed', at: fields[:accessed_on])],
206
- source: fields[:link] ? [Relaton::Bib::Uri.new(type: 'src', content: fields[:link])] : [],
207
- keyword: fields[:keywords].map { |text| keyword(text) }
214
+ source: links(fields),
215
+ keyword: fields[:keywords].map { |text| keyword(text) },
216
+ note: notes(fields)
208
217
  )
209
218
  end
210
219
 
220
+ def links(fields)
221
+ fields[:link] ? [Relaton::Bib::Uri.new(type: 'src', content: fields[:link])] : []
222
+ end
223
+
224
+ # The provenance record as a bibliographic note (TODO.v2
225
+ # item 3): retrieval source/version and the source's required
226
+ # attribution — licence terms must survive into the document.
227
+ def notes(fields)
228
+ fields[:notes].map { |text| Relaton::Bib::Note.new(type: 'provenance', content: text) }
229
+ end
230
+
211
231
  def docidentifier(docid)
212
232
  Relaton::Bib::Docidentifier.new(type: docid[:type], content: docid[:id])
213
233
  end
@@ -44,7 +44,9 @@ module AsciiChem
44
44
  def call(molfile, function)
45
45
  binding_class = self.class.binding_class(@lib)
46
46
  pointer = binding_class.public_send(function, molfile)
47
- unless pointer
47
+ # An FFI null return is a TRUTHY pointer object — `unless pointer`
48
+ # never fires; nil?/null? is the only correct emptiness test.
49
+ if pointer.nil? || pointer.null?
48
50
  message = binding_class.last_error
49
51
  raise AsciiChem::Error, "chemomer native engine: #{message || 'call failed'}"
50
52
  end
@@ -7,16 +7,15 @@ module AsciiChem
7
7
  module Resolver
8
8
  # CAS Common Chemistry source adapter (TODO.impl 40; TODO.v2 07).
9
9
  #
10
- # License posture (maintainer sign-off 2026-09-13): Common
11
- # Chemistry data is CC BY-NC 4.0 — this adapter is OPT-IN and never
12
- # self-registers; users register it explicitly:
13
- #
14
- # AsciiChem::Resolver.register(:common_chemistry,
15
- # AsciiChem::Resolver::CommonChemistry)
16
- #
17
- # Every result carries the required attribution.
10
+ # License posture (maintainer decision 2026-11-11): Common
11
+ # Chemistry data is CC BY-NC 4.0 — acceptable to enable by
12
+ # default; every result carries the required attribution, and the
13
+ # citation track carries it into rendered documents. Documents
14
+ # that must stay NC-free limit sources with the
15
+ # `asciichem-sources` attribute (metanorma-plugin-asciichem) or
16
+ # `Resolver.resolve(sources:)`.
18
17
  class CommonChemistry < Adapter
19
- source_name :common_chemistry, register: false
18
+ source_name :common_chemistry
20
19
  supports "cas"
21
20
 
22
21
  BASE = "https://commonchemistry.cas.org/api/detail"
@@ -5,7 +5,19 @@ module AsciiChem
5
5
  # Domain value objects for resolution results. These are data
6
6
  # carriers; (de)serialization to the canonical wire form goes
7
7
  # through the lutaml-model Wire classes only.
8
- Provenance = Struct.new(:source, :retrieved_at, :source_version, :attribution, keyword_init: true)
8
+ Provenance = Struct.new(:source, :retrieved_at, :source_version, :attribution, keyword_init: true) do
9
+ # The provenance record as one sentence (the citation track's
10
+ # bibitem note): retrieval source and version plus the source's
11
+ # required attribution — licence terms (CAS Common Chemistry is
12
+ # CC BY-NC 4.0) must survive into the rendered document. Nil
13
+ # when there is nothing beyond the source name itself.
14
+ def note_text
15
+ details = [source_version && "version #{source_version}", attribution].compact
16
+ return nil if details.empty?
17
+
18
+ "Retrieved from #{source}; #{details.join('; ')}"
19
+ end
20
+ end
9
21
  Identifier = Struct.new(:value, :convention, :provenance, keyword_init: true)
10
22
  Property = Struct.new(:name, :value, :units, :provenance, keyword_init: true)
11
23
 
@@ -9,10 +9,13 @@ module AsciiChem
9
9
  # citation track (TODO.v2 08) emits one bibitem per (substance,
10
10
  # source) the user chooses to cite.
11
11
  #
12
- # Sources are opt-in adapters that self-register (OCP, same pattern
13
- # as the linter checks). NC-licensed sources are never registered by
14
- # default — Common Chemistry ships only after the maintainer
15
- # sign-off recorded in TODO.v2 07.
12
+ # Sources are adapters that self-register (OCP, same pattern
13
+ # as the linter checks). All shipped sources are on by default;
14
+ # every result carries its source's required attribution (Common
15
+ # Chemistry: CC BY-NC 4.0 — default-on per the maintainer decision
16
+ # of 2026-11-11). Callers limit the set explicitly:
17
+ # `Resolver.resolve(sources:)` or the metanorma plugin's
18
+ # `asciichem-sources` attribute for NC-free documents.
16
19
  module Resolver
17
20
  autoload :Adapter, "asciichem/resolver/adapter"
18
21
  autoload :Cache, "asciichem/resolver/cache"
@@ -71,9 +74,10 @@ module AsciiChem
71
74
  end
72
75
  end
73
76
 
74
- # Open, permissive sources register eagerly. CommonChemistry is
75
- # CC BY-NC 4.0: it loads (autoload) but never self-registers —
76
- # users opt in explicitly via Resolver.register.
77
+ # Every shipped source self-registers eagerly (autoload fires the
78
+ # class bodies). CommonChemistry is CC BY-NC 4.0 and default-on
79
+ # per the maintainer decision of 2026-11-11; callers that need
80
+ # NC-free resolution limit sources explicitly.
77
81
  adapters
78
82
  constants.each { |c| const_get(c) unless c == :Conflict }
79
83
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AsciiChem
4
- VERSION = "0.31.10"
4
+ VERSION = "0.31.12"
5
5
  end
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.31.10
4
+ version: 0.31.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.