react-cheminfo 0.72.0 → 0.74.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.
Files changed (91) hide show
  1. package/README.md +29 -8
  2. package/lib/citation/core/formats.d.ts.map +1 -1
  3. package/lib/citation/core/formats.js +65 -17
  4. package/lib/citation/core/formats.js.map +1 -1
  5. package/lib/citation/core/index.d.ts +3 -2
  6. package/lib/citation/core/index.d.ts.map +1 -1
  7. package/lib/citation/core/index.js +2 -1
  8. package/lib/citation/core/index.js.map +1 -1
  9. package/lib/citation/core/openChemistryPaper.d.ts +15 -0
  10. package/lib/citation/core/openChemistryPaper.d.ts.map +1 -0
  11. package/lib/citation/core/openChemistryPaper.js +33 -0
  12. package/lib/citation/core/openChemistryPaper.js.map +1 -0
  13. package/lib/citation/core/reference.d.ts +36 -3
  14. package/lib/citation/core/reference.d.ts.map +1 -1
  15. package/lib/citation/core/reference.js +11 -0
  16. package/lib/citation/core/reference.js.map +1 -1
  17. package/lib/citation/core/segments.d.ts +9 -2
  18. package/lib/citation/core/segments.d.ts.map +1 -1
  19. package/lib/citation/core/segments.js +74 -7
  20. package/lib/citation/core/segments.js.map +1 -1
  21. package/lib/citation/ui/CitationMenu.js +2 -2
  22. package/lib/citation/ui/CitationMenu.js.map +1 -1
  23. package/lib/citation/ui/WorkEntry.d.ts.map +1 -1
  24. package/lib/citation/ui/WorkEntry.js +4 -2
  25. package/lib/citation/ui/WorkEntry.js.map +1 -1
  26. package/lib/i18n/core/chromeCatalog.d.ts +1 -1
  27. package/lib/i18n/core/chromeCatalog.d.ts.map +1 -1
  28. package/lib/locales/de.json +23 -0
  29. package/lib/locales/en.json +23 -0
  30. package/lib/locales/es.json +23 -0
  31. package/lib/locales/fr.json +23 -0
  32. package/lib/locales/it.json +23 -0
  33. package/lib/structure/core/fragmentIdCode.d.ts +15 -0
  34. package/lib/structure/core/fragmentIdCode.d.ts.map +1 -0
  35. package/lib/structure/core/fragmentIdCode.js +25 -0
  36. package/lib/structure/core/fragmentIdCode.js.map +1 -0
  37. package/lib/structure/core/index.d.ts +2 -0
  38. package/lib/structure/core/index.d.ts.map +1 -1
  39. package/lib/structure/core/index.js +1 -0
  40. package/lib/structure/core/index.js.map +1 -1
  41. package/lib/structure/core/structureSearch.d.ts +44 -0
  42. package/lib/structure/core/structureSearch.d.ts.map +1 -0
  43. package/lib/structure/core/structureSearch.js +31 -0
  44. package/lib/structure/core/structureSearch.js.map +1 -0
  45. package/lib/structure/core/substructureMatch.d.ts +33 -0
  46. package/lib/structure/core/substructureMatch.d.ts.map +1 -0
  47. package/lib/structure/core/substructureMatch.js +73 -0
  48. package/lib/structure/core/substructureMatch.js.map +1 -0
  49. package/lib/structure/ui/Structure.d.ts +18 -0
  50. package/lib/structure/ui/Structure.d.ts.map +1 -1
  51. package/lib/structure/ui/Structure.js +2 -2
  52. package/lib/structure/ui/Structure.js.map +1 -1
  53. package/lib/structure/ui/StructureSearchDialog.d.ts +55 -0
  54. package/lib/structure/ui/StructureSearchDialog.d.ts.map +1 -0
  55. package/lib/structure/ui/StructureSearchDialog.js +77 -0
  56. package/lib/structure/ui/StructureSearchDialog.js.map +1 -0
  57. package/lib/structure/ui/StructureSvg.d.ts +9 -0
  58. package/lib/structure/ui/StructureSvg.d.ts.map +1 -1
  59. package/lib/structure/ui/StructureSvg.js +7 -2
  60. package/lib/structure/ui/StructureSvg.js.map +1 -1
  61. package/lib/structure/ui/index.d.ts +4 -0
  62. package/lib/structure/ui/index.d.ts.map +1 -1
  63. package/lib/structure/ui/index.js +2 -0
  64. package/lib/structure/ui/index.js.map +1 -1
  65. package/lib/structure/ui/useStructureSearchModes.d.ts +18 -0
  66. package/lib/structure/ui/useStructureSearchModes.d.ts.map +1 -0
  67. package/lib/structure/ui/useStructureSearchModes.js +36 -0
  68. package/lib/structure/ui/useStructureSearchModes.js.map +1 -0
  69. package/package.json +12 -12
  70. package/src/citation/core/formats.ts +81 -18
  71. package/src/citation/core/index.ts +11 -2
  72. package/src/citation/core/openChemistryPaper.ts +37 -0
  73. package/src/citation/core/reference.ts +43 -3
  74. package/src/citation/core/segments.ts +92 -16
  75. package/src/citation/ui/CitationMenu.tsx +2 -2
  76. package/src/citation/ui/WorkEntry.tsx +7 -3
  77. package/src/locales/de.json +23 -0
  78. package/src/locales/en.json +23 -0
  79. package/src/locales/es.json +23 -0
  80. package/src/locales/fr.json +23 -0
  81. package/src/locales/it.json +23 -0
  82. package/src/structure/core/fragmentIdCode.ts +25 -0
  83. package/src/structure/core/index.ts +10 -0
  84. package/src/structure/core/structureSearch.ts +68 -0
  85. package/src/structure/core/substructureMatch.ts +85 -0
  86. package/src/structure/ui/Structure.tsx +24 -0
  87. package/src/structure/ui/StructureSearchDialog.tsx +218 -0
  88. package/src/structure/ui/StructureSvg.tsx +35 -0
  89. package/src/structure/ui/index.ts +4 -0
  90. package/src/structure/ui/useStructureSearchModes.ts +51 -0
  91. package/styles/chrome.css +31 -0
@@ -1,8 +1,13 @@
1
- import type { Reference } from './reference.ts';
1
+ import type {
2
+ ArticleReference,
3
+ DatasetReference,
4
+ Reference,
5
+ ReferenceAuthor,
6
+ } from './reference.ts';
2
7
  import { doiUrl } from './reference.ts';
3
8
  import { renderHtml, renderMarkdown, renderText } from './render.ts';
4
9
  import type { CitationStyleId } from './segments.ts';
5
- import { citationSegments, pageRange } from './segments.ts';
10
+ import { citationSegments, nameFamilyFirst, pageRange } from './segments.ts';
6
11
 
7
12
  /** The formats the reference can be copied in. */
8
13
  export type CitationFormatId =
@@ -112,8 +117,20 @@ export function formatCitation(
112
117
  }
113
118
 
114
119
  function formatBibTeX(reference: Reference): string {
120
+ const fields =
121
+ reference.kind === 'dataset'
122
+ ? datasetBibTeXFields(reference)
123
+ : articleBibTeXFields(reference);
124
+ const body = fields
125
+ .map(([name, value]) => ` ${name} = {${value}},`)
126
+ .join('\n');
127
+ const type = reference.kind === 'dataset' ? 'misc' : 'article';
128
+ return `@${type}{${bibTeXKey(reference)},\n${body}\n}`;
129
+ }
130
+
131
+ function articleBibTeXFields(reference: ArticleReference): Field[] {
115
132
  const { title, journal, year, volume, issue, publisher, doi } = reference;
116
- const fields: Array<[string, string]> = [
133
+ return [
117
134
  ['author', authorList(reference, ' and ')],
118
135
  ['title', title],
119
136
  ['journal', journal],
@@ -125,21 +142,42 @@ function formatBibTeX(reference: Reference): string {
125
142
  ['doi', doi],
126
143
  ['url', doiUrl(reference)],
127
144
  ];
128
- const body = fields
129
- .map(([name, value]) => ` ${name} = {${value}},`)
130
- .join('\n');
131
- return `@article{${bibTeXKey(reference)},\n${body}\n}`;
145
+ }
146
+
147
+ /**
148
+ * A dataset as the `@misc` entry every BibTeX style knows, its repository
149
+ * standing as the publisher.
150
+ * @param reference - Dataset to write.
151
+ * @returns The fields of the entry.
152
+ */
153
+ function datasetBibTeXFields(reference: DatasetReference): Field[] {
154
+ const { title, repository, year, version, doi } = reference;
155
+ return [
156
+ ['author', authorList(reference, ' and ')],
157
+ ['title', title],
158
+ ['howpublished', repository],
159
+ ['year', String(year)],
160
+ ...(version === undefined ? [] : [['version', version] as Field]),
161
+ ['publisher', repository],
162
+ ['doi', doi],
163
+ ['url', doiUrl(reference)],
164
+ ];
132
165
  }
133
166
 
134
167
  function formatRis(reference: Reference): string {
135
- const { title, journal, year, volume, issue, publisher, doi } = reference;
136
- const { authors, firstPage, lastPage } = reference;
137
- const lines: Array<[string, string]> = [
168
+ const lines =
169
+ reference.kind === 'dataset'
170
+ ? datasetRisLines(reference)
171
+ : articleRisLines(reference);
172
+ return lines.map(([tag, value]) => `${tag} - ${value}`).join('\n');
173
+ }
174
+
175
+ function articleRisLines(reference: ArticleReference): Field[] {
176
+ const { authors, title, journal, year, volume, issue } = reference;
177
+ const { firstPage, lastPage, publisher, doi } = reference;
178
+ return [
138
179
  ['TY', 'JOUR'],
139
- ...authors.map((author): [string, string] => [
140
- 'AU',
141
- `${author.family}, ${author.given}`,
142
- ]),
180
+ ...risAuthors(authors),
143
181
  ['TI', title],
144
182
  ['JO', journal],
145
183
  ['PY', String(year)],
@@ -152,13 +190,38 @@ function formatRis(reference: Reference): string {
152
190
  ['UR', doiUrl(reference)],
153
191
  ['ER', ''],
154
192
  ];
155
- return lines.map(([tag, value]) => `${tag} - ${value}`).join('\n');
156
193
  }
157
194
 
195
+ /**
196
+ * A dataset as an RIS `DATA` record, its version where reference managers
197
+ * read one, the edition.
198
+ * @param reference - Dataset to write.
199
+ * @returns The lines of the record.
200
+ */
201
+ function datasetRisLines(reference: DatasetReference): Field[] {
202
+ const { authors, title, year, version, repository, doi } = reference;
203
+ return [
204
+ ['TY', 'DATA'],
205
+ ...risAuthors(authors),
206
+ ['TI', title],
207
+ ['PY', String(year)],
208
+ ...(version === undefined ? [] : [['ET', version] as Field]),
209
+ ['PB', repository],
210
+ ['DO', doi],
211
+ ['UR', doiUrl(reference)],
212
+ ['ER', ''],
213
+ ];
214
+ }
215
+
216
+ function risAuthors(authors: readonly ReferenceAuthor[]): Field[] {
217
+ return authors.map((author): Field => ['AU', nameFamilyFirst(author)]);
218
+ }
219
+
220
+ /** One field of a BibTeX entry, or one tagged line of an RIS record. */
221
+ type Field = [name: string, value: string];
222
+
158
223
  function authorList(reference: Reference, separator: string): string {
159
- return reference.authors
160
- .map((author) => `${author.family}, ${author.given}`)
161
- .join(separator);
224
+ return reference.authors.map(nameFamilyFirst).join(separator);
162
225
  }
163
226
 
164
227
  function bibTeXKey(reference: Reference): string {
@@ -13,10 +13,19 @@ export {
13
13
  formatCitation,
14
14
  } from './formats.ts';
15
15
  export { GFN2_XTB_PAPER, GFN2_XTB_WORK } from './gfn2Paper.ts';
16
+ export {
17
+ OPEN_CHEMISTRY_PAPER,
18
+ OPEN_CHEMISTRY_WORK,
19
+ } from './openChemistryPaper.ts';
16
20
  export { OPENCHEMLIB_PAPER, OPENCHEMLIB_WORK } from './openchemlibPaper.ts';
17
21
  export { PLATFORM_PAPER, PLATFORM_WORK } from './platformPaper.ts';
18
- export type { Reference, ReferenceAuthor } from './reference.ts';
19
- export { doiUrl } from './reference.ts';
22
+ export type {
23
+ ArticleReference,
24
+ DatasetReference,
25
+ Reference,
26
+ ReferenceAuthor,
27
+ } from './reference.ts';
28
+ export { doiUrl, referenceVenue } from './reference.ts';
20
29
  export type {
21
30
  CitationSegment,
22
31
  CitationStyle,
@@ -0,0 +1,37 @@
1
+ import type { Reference } from './reference.ts';
2
+ import type { CitedWork } from './works.ts';
3
+
4
+ /**
5
+ * The case for publishing chemistry's data open and machine actionable, from
6
+ * the electronic lab notebook to the repository: the sites of the family that
7
+ * read research data where it was deposited come out of it. One record holds
8
+ * it, so no site can name a different version of it.
9
+ */
10
+ export const OPEN_CHEMISTRY_PAPER: Reference = {
11
+ authors: [
12
+ { given: 'K. M.', family: 'Jablonka' },
13
+ { given: 'L.', family: 'Patiny' },
14
+ { given: 'B.', family: 'Smit' },
15
+ ],
16
+ title:
17
+ 'Making the collective knowledge of chemistry open and machine actionable',
18
+ journal: 'Nature Chemistry',
19
+ journalAbbreviation: 'Nat. Chem.',
20
+ year: 2022,
21
+ volume: '14',
22
+ issue: '4',
23
+ firstPage: '365',
24
+ lastPage: '376',
25
+ doi: '10.1038/s41557-022-00910-7',
26
+ publisher: 'Springer Science and Business Media LLC',
27
+ };
28
+
29
+ /**
30
+ * The open-chemistry paper as one of the works a site reading deposited data
31
+ * asks to be cited, after the dataset it shows.
32
+ */
33
+ export const OPEN_CHEMISTRY_WORK: CitedWork = {
34
+ reference: OPEN_CHEMISTRY_PAPER,
35
+ what: 'Open, machine-actionable chemistry',
36
+ note: 'Cite it for publishing data the way this site reads it.',
37
+ };
@@ -1,13 +1,18 @@
1
1
  /** One author of a reference, as the citation styles need them. */
2
2
  export interface ReferenceAuthor {
3
- /** Initials or first name, e.g. `J. R.`. */
3
+ /** Initials or first name, e.g. `J. R.`; empty for an organisation. */
4
4
  given: string;
5
- /** Family name, e.g. `Vanderveen`. */
5
+ /** Family name, e.g. `Vanderveen`, or the organisation's name. */
6
6
  family: string;
7
7
  }
8
8
 
9
9
  /** A journal article, with everything the citation formats need. */
10
- export interface Reference {
10
+ export interface ArticleReference {
11
+ /**
12
+ * What the work is.
13
+ * @default 'article'
14
+ */
15
+ kind?: 'article';
11
16
  authors: readonly ReferenceAuthor[];
12
17
  title: string;
13
18
  /** Full journal name, e.g. `Green Chemistry`. */
@@ -23,6 +28,29 @@ export interface Reference {
23
28
  publisher: string;
24
29
  }
25
30
 
31
+ /**
32
+ * A dataset deposited in a repository, with everything the citation formats
33
+ * need: it has no journal, no volume and no pages, and a repository instead.
34
+ */
35
+ export interface DatasetReference {
36
+ /** What the work is. */
37
+ kind: 'dataset';
38
+ authors: readonly ReferenceAuthor[];
39
+ title: string;
40
+ /** The repository holding it, e.g. `Zenodo`. */
41
+ repository: string;
42
+ year: number;
43
+ /**
44
+ * The version deposited, when the repository records one.
45
+ * @default undefined
46
+ */
47
+ version?: string;
48
+ doi: string;
49
+ }
50
+
51
+ /** A work the citation formats write: a journal article, or a dataset. */
52
+ export type Reference = ArticleReference | DatasetReference;
53
+
26
54
  /**
27
55
  * Resolvable address of a reference.
28
56
  * @param reference - Reference to link to.
@@ -31,3 +59,15 @@ export interface Reference {
31
59
  export function doiUrl(reference: Reference): string {
32
60
  return `https://doi.org/${reference.doi}`;
33
61
  }
62
+
63
+ /**
64
+ * Where a work was published, as a menu names it beside its year: the
65
+ * abbreviated journal of an article, the repository of a dataset.
66
+ * @param reference - The work.
67
+ * @returns The journal or the repository.
68
+ */
69
+ export function referenceVenue(reference: Reference): string {
70
+ return reference.kind === 'dataset'
71
+ ? reference.repository
72
+ : reference.journalAbbreviation;
73
+ }
@@ -1,4 +1,9 @@
1
- import type { Reference } from './reference.ts';
1
+ import type {
2
+ ArticleReference,
3
+ DatasetReference,
4
+ Reference,
5
+ ReferenceAuthor,
6
+ } from './reference.ts';
2
7
  import { doiUrl } from './reference.ts';
3
8
 
4
9
  /** One piece of a written reference, with the emphasis its style asks for. */
@@ -37,6 +42,7 @@ export function citationSegments(
37
42
  reference: Reference,
38
43
  style: CitationStyleId,
39
44
  ): CitationSegment[] {
45
+ if (reference.kind === 'dataset') return datasetSegments(reference, style);
40
46
  switch (style) {
41
47
  case 'acs':
42
48
  return acs(reference);
@@ -51,10 +57,62 @@ export function citationSegments(
51
57
  }
52
58
  }
53
59
 
54
- function acs(reference: Reference): CitationSegment[] {
60
+ /**
61
+ * A dataset as each style writes one: the repository stands where the journal
62
+ * would, and there is neither a volume nor pages. The title is kept by every
63
+ * style, the RSC one included, since it is what tells two datasets of the same
64
+ * authors and year apart.
65
+ * @param reference - Dataset to write.
66
+ * @param style - Style to write it in.
67
+ * @returns The segments of the citation, in reading order.
68
+ */
69
+ function datasetSegments(
70
+ reference: DatasetReference,
71
+ style: CitationStyleId,
72
+ ): CitationSegment[] {
73
+ const { repository, year, version } = reference;
74
+ const title =
75
+ version === undefined
76
+ ? reference.title
77
+ : `${reference.title}, version ${version}`;
78
+ switch (style) {
79
+ case 'acs':
80
+ return [
81
+ text(`${withPeriod(familyFirst(reference, '; '))} ${title}; `),
82
+ italic(repository),
83
+ text(`, ${year}. `),
84
+ doiLink(reference),
85
+ ];
86
+ case 'nature':
87
+ return [
88
+ text(`${withPeriod(familyFirstAmpersand(reference))} ${title}. `),
89
+ italic(repository),
90
+ text(` (${year}). `),
91
+ doiLink(reference),
92
+ ];
93
+ case 'rsc':
94
+ return [
95
+ text(`${initialsFirst(reference, ' and ')}, ${title}, `),
96
+ italic(repository),
97
+ text(`, ${year}. `),
98
+ doiLink(reference),
99
+ ];
100
+ case 'wiley':
101
+ return [
102
+ text(`${initialsFirst(reference, ', ')}, ${title}, `),
103
+ italic(repository),
104
+ text(`, ${year}. `),
105
+ doiLink(reference),
106
+ ];
107
+ default:
108
+ throw new Error(`unknown citation style: ${String(style)}`);
109
+ }
110
+ }
111
+
112
+ function acs(reference: ArticleReference): CitationSegment[] {
55
113
  const { title, journalAbbreviation, year, volume } = reference;
56
114
  return [
57
- text(`${familyFirst(reference, '; ')} ${title}. `),
115
+ text(`${withPeriod(familyFirst(reference, '; '))} ${title}. `),
58
116
  italic(journalAbbreviation),
59
117
  text(' '),
60
118
  bold(String(year)),
@@ -65,10 +123,10 @@ function acs(reference: Reference): CitationSegment[] {
65
123
  ];
66
124
  }
67
125
 
68
- function nature(reference: Reference): CitationSegment[] {
126
+ function nature(reference: ArticleReference): CitationSegment[] {
69
127
  const { title, journalAbbreviation, year, volume } = reference;
70
128
  return [
71
- text(`${familyFirstAmpersand(reference)} ${title}. `),
129
+ text(`${withPeriod(familyFirstAmpersand(reference))} ${title}. `),
72
130
  italic(journalAbbreviation),
73
131
  text(' '),
74
132
  bold(volume),
@@ -77,7 +135,7 @@ function nature(reference: Reference): CitationSegment[] {
77
135
  ];
78
136
  }
79
137
 
80
- function rsc(reference: Reference): CitationSegment[] {
138
+ function rsc(reference: ArticleReference): CitationSegment[] {
81
139
  const { journalAbbreviation, year, volume } = reference;
82
140
  return [
83
141
  text(`${initialsFirst(reference, ' and ')}, `),
@@ -89,7 +147,7 @@ function rsc(reference: Reference): CitationSegment[] {
89
147
  ];
90
148
  }
91
149
 
92
- function wiley(reference: Reference): CitationSegment[] {
150
+ function wiley(reference: ArticleReference): CitationSegment[] {
93
151
  const { journalAbbreviation, year, volume } = reference;
94
152
  return [
95
153
  text(`${initialsFirst(reference, ', ')}, `),
@@ -123,6 +181,16 @@ function doiLink(reference: Reference): CitationSegment {
123
181
  };
124
182
  }
125
183
 
184
+ /**
185
+ * The author list closed by a full stop. A person's name already ends on the
186
+ * one of their last initial; an organisation's name needs its own.
187
+ * @param authors - The author list.
188
+ * @returns It, ending with a full stop.
189
+ */
190
+ function withPeriod(authors: string): string {
191
+ return authors.endsWith('.') ? authors : `${authors}.`;
192
+ }
193
+
126
194
  /**
127
195
  * `Vanderveen, J. R.; Patiny, L.` — the family name leads.
128
196
  * @param reference - The work being written.
@@ -130,9 +198,7 @@ function doiLink(reference: Reference): CitationSegment {
130
198
  * @returns The authors, as one string.
131
199
  */
132
200
  function familyFirst(reference: Reference, separator: string): string {
133
- return reference.authors
134
- .map((author) => `${author.family}, ${author.given}`)
135
- .join(separator);
201
+ return reference.authors.map(nameFamilyFirst).join(separator);
136
202
  }
137
203
 
138
204
  /**
@@ -141,9 +207,7 @@ function familyFirst(reference: Reference, separator: string): string {
141
207
  * @returns The authors, as one string.
142
208
  */
143
209
  function familyFirstAmpersand(reference: Reference): string {
144
- const names = reference.authors.map(
145
- (author) => `${author.family}, ${author.given}`,
146
- );
210
+ const names = reference.authors.map(nameFamilyFirst);
147
211
  const last = names.at(-1);
148
212
  if (names.length < 2 || last === undefined) return names.join(', ');
149
213
  return `${names.slice(0, -1).join(', ')} & ${last}`;
@@ -156,8 +220,8 @@ function familyFirstAmpersand(reference: Reference): string {
156
220
  * @returns The authors, as one string.
157
221
  */
158
222
  function initialsFirst(reference: Reference, lastSeparator: string): string {
159
- const names = reference.authors.map(
160
- (author) => `${author.given} ${author.family}`,
223
+ const names = reference.authors.map((author) =>
224
+ author.given === '' ? author.family : `${author.given} ${author.family}`,
161
225
  );
162
226
  const last = names.at(-1);
163
227
  if (names.length < 2 || last === undefined) return names.join(', ');
@@ -171,8 +235,20 @@ function initialsFirst(reference: Reference, lastSeparator: string): string {
171
235
  * @returns One number for a journal that paginates by article number, the
172
236
  * range otherwise.
173
237
  */
174
- export function pageRange(reference: Reference, dash = '–'): string {
238
+ export function pageRange(reference: ArticleReference, dash = '–'): string {
175
239
  const { firstPage, lastPage } = reference;
176
240
  if (firstPage === lastPage) return firstPage;
177
241
  return `${firstPage}${dash}${lastPage}`;
178
242
  }
243
+
244
+ /**
245
+ * An author with the family name first, `Vanderveen, J. R.`, or the name of an
246
+ * organisation alone.
247
+ * @param author - The author.
248
+ * @returns The name, as a reference list writes it.
249
+ */
250
+ export function nameFamilyFirst(author: ReferenceAuthor): string {
251
+ return author.given === ''
252
+ ? author.family
253
+ : `${author.family}, ${author.given}`;
254
+ }
@@ -5,7 +5,7 @@ import type { CSSProperties, ReactElement } from 'react';
5
5
  import { useChromeT } from '../../i18n/ui/useT.ts';
6
6
  import { CITATION_DOWNLOADS } from '../core/formats.ts';
7
7
  import type { Reference } from '../core/reference.ts';
8
- import { doiUrl } from '../core/reference.ts';
8
+ import { doiUrl, referenceVenue } from '../core/reference.ts';
9
9
  import type { CitedWork } from '../core/works.ts';
10
10
  import { citedReferences } from '../core/works.ts';
11
11
 
@@ -78,7 +78,7 @@ function OneWorkMenu(props: CitedReferenceProps): ReactElement {
78
78
  <Menu className="citation-menu" style={MENU_STYLE}>
79
79
  <MenuItem
80
80
  icon={<SvgLogoDoi style={DOI_ICON_STYLE} />}
81
- text={`${reference.journalAbbreviation} ${reference.year}`}
81
+ text={`${referenceVenue(reference)} ${reference.year}`}
82
82
  label={reference.doi}
83
83
  href={doiUrl(reference)}
84
84
  target="_blank"
@@ -4,7 +4,7 @@ import type { CSSProperties, ReactElement } from 'react';
4
4
 
5
5
  import { useChromeT } from '../../i18n/ui/useT.ts';
6
6
  import { CITATION_DOWNLOADS } from '../core/formats.ts';
7
- import { doiUrl } from '../core/reference.ts';
7
+ import { doiUrl, referenceVenue } from '../core/reference.ts';
8
8
  import type { CitedWork } from '../core/works.ts';
9
9
 
10
10
  import { CopyFormatEntries } from './CopyFormatEntries.tsx';
@@ -52,11 +52,15 @@ export function WorkEntry(props: WorkEntryProps): ReactElement {
52
52
  {note === undefined ? null : <div style={NOTE_STYLE}>{note}</div>}
53
53
  </span>
54
54
  }
55
- label={`${reference.journalAbbreviation} ${reference.year}`}
55
+ label={`${referenceVenue(reference)} ${reference.year}`}
56
56
  >
57
57
  <MenuItem
58
58
  icon={<SvgLogoDoi style={DOI_ICON_STYLE} />}
59
- text={t('cite.openArticle')}
59
+ text={
60
+ reference.kind === 'dataset'
61
+ ? t('cite.openDataset')
62
+ : t('cite.openArticle')
63
+ }
60
64
  label={reference.doi}
61
65
  href={doiUrl(reference)}
62
66
  target="_blank"
@@ -155,6 +155,7 @@
155
155
  "cite.copyEveryAs": "Alle Literaturangaben kopieren als",
156
156
  "cite.importIntoManager": "In ein Literaturverwaltungsprogramm importieren",
157
157
  "cite.openArticle": "Den Artikel öffnen",
158
+ "cite.openDataset": "Den Datensatz öffnen",
158
159
  "cite.copyThisAs": "Diese Literaturangabe kopieren als",
159
160
  "cite.importThis": "Diese Literaturangabe importieren",
160
161
  "cite.copied": "kopiert",
@@ -582,6 +583,28 @@
582
583
  "structure.export.noStereoIdCodeHelp": "Jedes Stereoisomer ergibt diese, womit ein ohne Stereozentren gezeichneter Eintrag gefunden wird.",
583
584
  "structure.export.noStereoTautomerIdCode": "idCode ohne Stereochemie und Tautomerie",
584
585
  "structure.export.noStereoTautomerIdCodeHelp": "Jedes Tautomer und jedes Stereoisomer ergibt diese: Keto- und Enolform haben denselben Schlüssel.",
586
+ "structure.search.title": "Nach Struktur filtern",
587
+ "structure.search.apply": "Anwenden",
588
+ "structure.search.examples": "Ausgehend von",
589
+ "structure.search.substructure": "Enthält",
590
+ "structure.search.substructureHelp": "Jedes Molekül, das die Zeichnung enthält.",
591
+ "structure.search.similarity": "Ähnlich zu",
592
+ "structure.search.similarityHelp": "Geordnet danach, wie viel der Zeichnung sie teilen.",
593
+ "structure.search.exact": "Ist genau",
594
+ "structure.search.exactHelp": "Genau das gezeichnete Molekül.",
595
+ "structure.search.exactNoStereo": "Beliebiges Stereoisomer",
596
+ "structure.search.exactNoStereoHelp": "Dieselbe Verbindung, wie auch immer ihre Stereochemie gezeichnet ist.",
597
+ "structure.search.exactNoStereoTautomer": "Beliebiges Tautomer",
598
+ "structure.search.exactNoStereoTautomerHelp": "Dieselbe Verbindung in jeder tautomeren Form, ohne ihre Stereochemie.",
599
+ "structure.search.similarityLabel": "Ähnlichkeit",
600
+ "structure.search.threshold": "Mindestähnlichkeit",
601
+ "structure.search.thresholdHelp": "Der kleinste Tanimoto-Koeffizient, den ein Treffer mit der Zeichnung erreicht.",
602
+ "structure.search.thresholdOption": "≥ {percent}",
603
+ "structure.search.exampleBenzene": "Benzol",
604
+ "structure.search.examplePyridine": "Pyridin",
605
+ "structure.search.exampleAmide": "Amid",
606
+ "structure.search.exampleSulfonamide": "Sulfonamid",
607
+ "structure.search.exampleTrifluoromethyl": "Trifluormethyl",
585
608
  "molecule3d.view": "Ansicht",
586
609
  "molecule3d.resetView": "Ansicht zurücksetzen",
587
610
  "molecule3d.spin": "Drehen lassen",
@@ -155,6 +155,7 @@
155
155
  "cite.copyEveryAs": "Copy every reference as",
156
156
  "cite.importIntoManager": "Import into a reference manager",
157
157
  "cite.openArticle": "Open the article",
158
+ "cite.openDataset": "Open the dataset",
158
159
  "cite.copyThisAs": "Copy this reference as",
159
160
  "cite.importThis": "Import this reference",
160
161
  "cite.copied": "copied",
@@ -526,6 +527,28 @@
526
527
  "structure.export.noStereoIdCodeHelp": "Every stereoisomer of this structure gives this one, so it finds a record drawn without its stereocentres.",
527
528
  "structure.export.noStereoTautomerIdCode": "idCode without stereochemistry or tautomer",
528
529
  "structure.export.noStereoTautomerIdCodeHelp": "Every tautomer and every stereoisomer gives this one, so the keto and the enol form key together.",
530
+ "structure.search.title": "Filter by structure",
531
+ "structure.search.apply": "Apply",
532
+ "structure.search.examples": "Start from",
533
+ "structure.search.substructure": "Contains",
534
+ "structure.search.substructureHelp": "Every molecule the drawing is part of.",
535
+ "structure.search.similarity": "Similar to",
536
+ "structure.search.similarityHelp": "Ranked by how much of the drawing they share.",
537
+ "structure.search.exact": "Is exactly",
538
+ "structure.search.exactHelp": "The one molecule drawn.",
539
+ "structure.search.exactNoStereo": "Any stereoisomer",
540
+ "structure.search.exactNoStereoHelp": "The same compound however its stereochemistry is drawn.",
541
+ "structure.search.exactNoStereoTautomer": "Any tautomer",
542
+ "structure.search.exactNoStereoTautomerHelp": "The same compound in any tautomeric form, its stereochemistry ignored.",
543
+ "structure.search.similarityLabel": "Similarity",
544
+ "structure.search.threshold": "Minimum similarity",
545
+ "structure.search.thresholdHelp": "The least Tanimoto coefficient a hit reaches with the drawing.",
546
+ "structure.search.thresholdOption": "≥ {percent}",
547
+ "structure.search.exampleBenzene": "Benzene",
548
+ "structure.search.examplePyridine": "Pyridine",
549
+ "structure.search.exampleAmide": "Amide",
550
+ "structure.search.exampleSulfonamide": "Sulfonamide",
551
+ "structure.search.exampleTrifluoromethyl": "Trifluoromethyl",
529
552
  "periodic.table": "Periodic table",
530
553
  "periodic.group": "Group {group}",
531
554
  "periodic.period": "Period {period}",
@@ -155,6 +155,7 @@
155
155
  "cite.copyEveryAs": "Copiar todas las referencias como",
156
156
  "cite.importIntoManager": "Importar a un gestor de referencias",
157
157
  "cite.openArticle": "Abrir el artículo",
158
+ "cite.openDataset": "Abrir el conjunto de datos",
158
159
  "cite.copyThisAs": "Copiar esta referencia como",
159
160
  "cite.importThis": "Importar esta referencia",
160
161
  "cite.copied": "copiado",
@@ -582,6 +583,28 @@
582
583
  "structure.export.noStereoIdCodeHelp": "Todos los estereoisómeros dan este, así que encuentra un registro dibujado sin sus centros estereogénicos.",
583
584
  "structure.export.noStereoTautomerIdCode": "idCode sin estereoquímica ni tautomería",
584
585
  "structure.export.noStereoTautomerIdCodeHelp": "Todos los tautómeros y estereoisómeros dan este: la forma cetónica y la enólica comparten clave.",
586
+ "structure.search.title": "Filtrar por estructura",
587
+ "structure.search.apply": "Aplicar",
588
+ "structure.search.examples": "Partir de",
589
+ "structure.search.substructure": "Contiene",
590
+ "structure.search.substructureHelp": "Toda molécula de la que el dibujo forma parte.",
591
+ "structure.search.similarity": "Similar a",
592
+ "structure.search.similarityHelp": "Ordenadas por cuánto del dibujo comparten.",
593
+ "structure.search.exact": "Es exactamente",
594
+ "structure.search.exactHelp": "La molécula dibujada.",
595
+ "structure.search.exactNoStereo": "Cualquier estereoisómero",
596
+ "structure.search.exactNoStereoHelp": "El mismo compuesto, sea cual sea su estereoquímica dibujada.",
597
+ "structure.search.exactNoStereoTautomer": "Cualquier tautómero",
598
+ "structure.search.exactNoStereoTautomerHelp": "El mismo compuesto en cualquier forma tautomérica, sin su estereoquímica.",
599
+ "structure.search.similarityLabel": "Similitud",
600
+ "structure.search.threshold": "Similitud mínima",
601
+ "structure.search.thresholdHelp": "El menor coeficiente de Tanimoto que alcanza un resultado con el dibujo.",
602
+ "structure.search.thresholdOption": "≥ {percent}",
603
+ "structure.search.exampleBenzene": "Benceno",
604
+ "structure.search.examplePyridine": "Piridina",
605
+ "structure.search.exampleAmide": "Amida",
606
+ "structure.search.exampleSulfonamide": "Sulfonamida",
607
+ "structure.search.exampleTrifluoromethyl": "Trifluorometilo",
585
608
  "molecule3d.view": "Vista",
586
609
  "molecule3d.resetView": "Reiniciar la vista",
587
610
  "molecule3d.spin": "Giro continuo",
@@ -155,6 +155,7 @@
155
155
  "cite.copyEveryAs": "Copier toutes les références en",
156
156
  "cite.importIntoManager": "Importer dans un gestionnaire de références",
157
157
  "cite.openArticle": "Ouvrir l'article",
158
+ "cite.openDataset": "Ouvrir le jeu de données",
158
159
  "cite.copyThisAs": "Copier cette référence en",
159
160
  "cite.importThis": "Importer cette référence",
160
161
  "cite.copied": "copié",
@@ -582,6 +583,28 @@
582
583
  "structure.export.noStereoIdCodeHelp": "Tous les stéréoisomères donnent celui-ci, ce qui retrouve un enregistrement dessiné sans ses centres stéréogènes.",
583
584
  "structure.export.noStereoTautomerIdCode": "idCode sans stéréochimie ni tautomérie",
584
585
  "structure.export.noStereoTautomerIdCodeHelp": "Tous les tautomères et tous les stéréoisomères donnent celui-ci : la forme cétone et la forme énol ont la même clé.",
586
+ "structure.search.title": "Filtrer par structure",
587
+ "structure.search.apply": "Appliquer",
588
+ "structure.search.examples": "Partir de",
589
+ "structure.search.substructure": "Contient",
590
+ "structure.search.substructureHelp": "Toutes les molécules dont le dessin fait partie.",
591
+ "structure.search.similarity": "Similaire à",
592
+ "structure.search.similarityHelp": "Classées selon la part du dessin qu’elles partagent.",
593
+ "structure.search.exact": "Exactement",
594
+ "structure.search.exactHelp": "La seule molécule dessinée.",
595
+ "structure.search.exactNoStereo": "Tout stéréoisomère",
596
+ "structure.search.exactNoStereoHelp": "Le même composé, quelle que soit sa stéréochimie dessinée.",
597
+ "structure.search.exactNoStereoTautomer": "Tout tautomère",
598
+ "structure.search.exactNoStereoTautomerHelp": "Le même composé sous toute forme tautomère, sa stéréochimie ignorée.",
599
+ "structure.search.similarityLabel": "Similarité",
600
+ "structure.search.threshold": "Similarité minimale",
601
+ "structure.search.thresholdHelp": "Le plus petit coefficient de Tanimoto qu’un résultat atteint avec le dessin.",
602
+ "structure.search.thresholdOption": "≥ {percent}",
603
+ "structure.search.exampleBenzene": "Benzène",
604
+ "structure.search.examplePyridine": "Pyridine",
605
+ "structure.search.exampleAmide": "Amide",
606
+ "structure.search.exampleSulfonamide": "Sulfonamide",
607
+ "structure.search.exampleTrifluoromethyl": "Trifluorométhyle",
585
608
  "molecule3d.view": "Vue",
586
609
  "molecule3d.resetView": "Réinitialiser la vue",
587
610
  "molecule3d.spin": "Rotation continue",