@cyanheads/pubmed-mcp-server 2.3.8 → 2.3.10

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 (31) hide show
  1. package/CLAUDE.md +1 -1
  2. package/README.md +1 -1
  3. package/dist/mcp-server/tools/definitions/fetch-articles.tool.d.ts.map +1 -1
  4. package/dist/mcp-server/tools/definitions/fetch-articles.tool.js +2 -4
  5. package/dist/mcp-server/tools/definitions/fetch-articles.tool.js.map +1 -1
  6. package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.d.ts.map +1 -1
  7. package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.js +5 -8
  8. package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.js.map +1 -1
  9. package/dist/mcp-server/tools/definitions/search-articles.tool.d.ts +1 -0
  10. package/dist/mcp-server/tools/definitions/search-articles.tool.d.ts.map +1 -1
  11. package/dist/mcp-server/tools/definitions/search-articles.tool.js +51 -4
  12. package/dist/mcp-server/tools/definitions/search-articles.tool.js.map +1 -1
  13. package/dist/services/ncbi/parsing/esummary-parser.d.ts.map +1 -1
  14. package/dist/services/ncbi/parsing/esummary-parser.js +19 -4
  15. package/dist/services/ncbi/parsing/esummary-parser.js.map +1 -1
  16. package/dist/services/ncbi/parsing/pmc-article-parser.d.ts +21 -25
  17. package/dist/services/ncbi/parsing/pmc-article-parser.d.ts.map +1 -1
  18. package/dist/services/ncbi/parsing/pmc-article-parser.js +176 -223
  19. package/dist/services/ncbi/parsing/pmc-article-parser.js.map +1 -1
  20. package/dist/services/ncbi/parsing/pmc-xml-helpers.d.ts +44 -0
  21. package/dist/services/ncbi/parsing/pmc-xml-helpers.d.ts.map +1 -0
  22. package/dist/services/ncbi/parsing/pmc-xml-helpers.js +86 -0
  23. package/dist/services/ncbi/parsing/pmc-xml-helpers.js.map +1 -0
  24. package/dist/services/ncbi/response-handler.d.ts +12 -0
  25. package/dist/services/ncbi/response-handler.d.ts.map +1 -1
  26. package/dist/services/ncbi/response-handler.js +53 -9
  27. package/dist/services/ncbi/response-handler.js.map +1 -1
  28. package/dist/services/ncbi/types.d.ts +21 -127
  29. package/dist/services/ncbi/types.d.ts.map +1 -1
  30. package/package.json +1 -1
  31. package/server.json +3 -3
@@ -1,126 +1,78 @@
1
1
  /**
2
2
  * @fileoverview Parser for PMC full-text articles in JATS XML format.
3
- * Extracts metadata, body sections, and references from PMC EFetch responses.
3
+ * Consumes the ordered tree shape from fast-xml-parser's `preserveOrder: true`
4
+ * mode (see `pmc-xml-helpers.ts`) so that mixed-content elements — `<p>`,
5
+ * `<abstract>`, `<title>` with inline `<italic>`, `<xref>`, `<sup>`, etc. —
6
+ * read back in document order. Parsing in the default object shape scrambles
7
+ * inline children and drops body sections for markup-heavy articles.
4
8
  * @module src/services/ncbi/parsing/pmc-article-parser
5
9
  */
6
- import { ensureArray, getAttribute, getText } from './xml-helpers.js';
7
- // ─── Text Extraction ────────────────────────────────────────────────────────
8
- /**
9
- * Recursively extracts plain text content from a JATS XML node.
10
- * Handles mixed content where text and child elements are interleaved.
11
- * fast-xml-parser with `preserveOrder: false` stores text in `#text` and
12
- * child elements as named properties — document order is lost, but all
13
- * text content is preserved.
14
- */
15
- export function extractTextContent(node) {
16
- if (node == null)
17
- return '';
18
- if (typeof node === 'string')
19
- return node;
20
- if (typeof node === 'number' || typeof node === 'boolean')
21
- return String(node);
22
- if (Array.isArray(node)) {
23
- return node.map(extractTextContent).filter(Boolean).join(' ');
24
- }
25
- if (typeof node === 'object') {
26
- const obj = node;
27
- const parts = [];
28
- // Collect #text from this node
29
- if (obj['#text'] !== undefined) {
30
- const text = typeof obj['#text'] === 'string' ? obj['#text'] : String(obj['#text']);
31
- if (text)
32
- parts.push(text);
33
- }
34
- // Recurse into child elements (skip attributes prefixed with @_)
35
- for (const key of Object.keys(obj)) {
36
- if (key === '#text' || key.startsWith('@_'))
37
- continue;
38
- const childText = extractTextContent(obj[key]);
39
- if (childText)
40
- parts.push(childText);
41
- }
42
- return parts.join(' ').replace(/\s+/g, ' ').trim();
43
- }
44
- return '';
45
- }
46
- // ─── Article ID Extraction ──────────────────────────────────────────────────
47
- /**
48
- * Extracts a specific article ID by pub-id-type from article-meta.
49
- */
50
- function extractArticleId(articleIds, pubIdType) {
51
- for (const id of ensureArray(articleIds)) {
52
- if (getAttribute(id, 'pub-id-type') === pubIdType) {
53
- const val = id['#text'];
54
- if (val !== undefined)
55
- return String(val);
10
+ import { attrOf, childrenOf, findAll, findOne, tagNameOf, textContent, } from './pmc-xml-helpers.js';
11
+ // ─── Article IDs ────────────────────────────────────────────────────────────
12
+ function extractArticleId(articleMeta, pubIdType) {
13
+ if (!articleMeta)
14
+ return;
15
+ for (const idNode of findAll(articleMeta, 'article-id')) {
16
+ if (attrOf(idNode, 'pub-id-type') === pubIdType) {
17
+ return textContent(idNode) || undefined;
56
18
  }
57
19
  }
58
20
  return;
59
21
  }
60
- // ─── Author Extraction ──────────────────────────────────────────────────────
61
- /**
62
- * Extracts authors from JATS contrib-group elements.
63
- * Only includes contributors with contrib-type="author".
64
- */
65
- export function extractJatsAuthors(contribGroups) {
66
- if (!contribGroups)
22
+ // ─── Authors & Affiliations ─────────────────────────────────────────────────
23
+ /** Extract authors from a single `<contrib-group>` node. Non-author contributors are skipped. */
24
+ export function extractJatsAuthors(contribGroup) {
25
+ if (!contribGroup)
67
26
  return [];
68
27
  const authors = [];
69
- for (const group of ensureArray(contribGroups)) {
70
- for (const contrib of ensureArray(group.contrib)) {
71
- // Only include authors (skip editors, etc.)
72
- if (contrib['@_contrib-type'] && contrib['@_contrib-type'] !== 'author')
73
- continue;
74
- const collectiveName = extractTextContent(contrib.collab);
75
- if (collectiveName) {
28
+ for (const contrib of findAll(contribGroup, 'contrib')) {
29
+ const contribType = attrOf(contrib, 'contrib-type');
30
+ if (contribType && contribType !== 'author')
31
+ continue;
32
+ const collab = findOne(contrib, 'collab');
33
+ if (collab) {
34
+ const collectiveName = textContent(collab);
35
+ if (collectiveName)
76
36
  authors.push({ collectiveName });
77
- continue;
78
- }
79
- if (contrib.name) {
80
- const lastName = extractTextContent(contrib.name.surname) || undefined;
81
- const givenNames = extractTextContent(contrib.name['given-names']) || undefined;
82
- authors.push({
83
- ...(lastName && { lastName }),
84
- ...(givenNames && { givenNames }),
85
- });
86
- }
37
+ continue;
38
+ }
39
+ const nameNode = findOne(contrib, 'name');
40
+ if (nameNode) {
41
+ const lastName = textContent(findOne(nameNode, 'surname')) || undefined;
42
+ const givenNames = textContent(findOne(nameNode, 'given-names')) || undefined;
43
+ authors.push({
44
+ ...(lastName && { lastName }),
45
+ ...(givenNames && { givenNames }),
46
+ });
87
47
  }
88
48
  }
89
49
  return authors;
90
50
  }
91
- // ─── Affiliation Extraction ─────────────────────────────────────────────────
92
- /**
93
- * Extracts affiliation strings from JATS aff elements.
94
- */
95
- function extractAffiliations(affs) {
96
- if (!affs)
51
+ function extractAffiliations(articleMeta) {
52
+ if (!articleMeta)
97
53
  return [];
98
54
  const result = [];
99
- for (const aff of ensureArray(affs)) {
100
- const text = extractTextContent(aff);
55
+ for (const aff of findAll(articleMeta, 'aff')) {
56
+ const text = textContent(aff);
101
57
  if (text)
102
58
  result.push(text);
103
59
  }
104
60
  return result;
105
61
  }
106
- // ─── Journal Extraction ─────────────────────────────────────────────────────
107
- /**
108
- * Extracts journal metadata from JATS journal-meta.
109
- */
62
+ // ─── Journal & Publication Date ─────────────────────────────────────────────
110
63
  function extractJournal(journalMeta, articleMeta) {
111
64
  if (!journalMeta)
112
65
  return;
113
- const title = extractTextContent(journalMeta['journal-title-group']?.['journal-title']) ||
114
- extractTextContent(journalMeta['journal-title']) ||
66
+ const titleGroup = findOne(journalMeta, 'journal-title-group');
67
+ const title = textContent(findOne(titleGroup, 'journal-title')) ||
68
+ textContent(findOne(journalMeta, 'journal-title')) ||
115
69
  undefined;
116
- const issns = ensureArray(journalMeta.issn);
117
- const issn = issns.length > 0 ? getText(issns[0]) || undefined : undefined;
118
- const volume = articleMeta?.volume
119
- ? extractTextContent(articleMeta.volume) || undefined
120
- : undefined;
121
- const issue = articleMeta?.issue ? extractTextContent(articleMeta.issue) || undefined : undefined;
122
- const fpage = articleMeta?.fpage ? extractTextContent(articleMeta.fpage) : undefined;
123
- const lpage = articleMeta?.lpage ? extractTextContent(articleMeta.lpage) : undefined;
70
+ const firstIssn = findAll(journalMeta, 'issn')[0];
71
+ const issn = firstIssn ? textContent(firstIssn) || undefined : undefined;
72
+ const volume = articleMeta ? textContent(findOne(articleMeta, 'volume')) || undefined : undefined;
73
+ const issue = articleMeta ? textContent(findOne(articleMeta, 'issue')) || undefined : undefined;
74
+ const fpage = articleMeta ? textContent(findOne(articleMeta, 'fpage')) : '';
75
+ const lpage = articleMeta ? textContent(findOne(articleMeta, 'lpage')) : '';
124
76
  const pages = fpage && lpage ? `${fpage}-${lpage}` : fpage || undefined;
125
77
  if (!title && !issn && !volume && !issue && !pages)
126
78
  return;
@@ -132,157 +84,147 @@ function extractJournal(journalMeta, articleMeta) {
132
84
  ...(pages && { pages }),
133
85
  };
134
86
  }
135
- // ─── Publication Date Extraction ────────────────────────────────────────────
136
- /**
137
- * Extracts publication date from JATS pub-date elements.
138
- * Prefers epub date, falls back to ppub, then any available.
139
- */
140
- function extractPubDate(pubDates) {
141
- if (!pubDates)
87
+ function extractPubDate(articleMeta) {
88
+ if (!articleMeta)
89
+ return;
90
+ const dates = findAll(articleMeta, 'pub-date');
91
+ if (dates.length === 0)
142
92
  return;
143
- const dates = ensureArray(pubDates);
144
- // Prefer epub, then ppub, then first available
145
- const preferred = dates.find((d) => getAttribute(d, 'pub-type') === 'epub') ??
146
- dates.find((d) => getAttribute(d, 'pub-type') === 'ppub') ??
147
- dates.find((d) => getAttribute(d, 'date-type') === 'pub') ??
93
+ const preferred = dates.find((d) => attrOf(d, 'pub-type') === 'epub') ??
94
+ dates.find((d) => attrOf(d, 'pub-type') === 'ppub') ??
95
+ dates.find((d) => attrOf(d, 'date-type') === 'pub') ??
148
96
  dates[0];
149
97
  if (!preferred)
150
98
  return;
151
- const year = extractTextContent(preferred.year) || undefined;
152
- const month = extractTextContent(preferred.month) || undefined;
153
- const day = extractTextContent(preferred.day) || undefined;
99
+ const year = textContent(findOne(preferred, 'year')) || undefined;
154
100
  if (!year)
155
101
  return;
102
+ const month = textContent(findOne(preferred, 'month')) || undefined;
103
+ const day = textContent(findOne(preferred, 'day')) || undefined;
156
104
  return {
157
105
  year,
158
106
  ...(month && { month }),
159
107
  ...(day && { day }),
160
108
  };
161
109
  }
162
- // ─── Abstract Extraction ────────────────────────────────────────────────────
163
- /**
164
- * Extracts abstract text from JATS abstract element.
165
- * Handles both simple and structured abstracts (with titled sections).
166
- */
167
- function extractAbstract(abstractNode) {
110
+ // ─── Abstract & Keywords ────────────────────────────────────────────────────
111
+ function extractAbstract(articleMeta) {
112
+ if (!articleMeta)
113
+ return;
114
+ const abstractNode = findOne(articleMeta, 'abstract');
168
115
  if (!abstractNode)
169
116
  return;
170
- // Structured abstract with sections
171
- if (typeof abstractNode === 'object' && !Array.isArray(abstractNode)) {
172
- const obj = abstractNode;
173
- // Check for sectioned abstract (<abstract><sec><title>...<p>...</sec></abstract>)
174
- if (obj.sec) {
175
- const sections = ensureArray(obj.sec);
176
- const parts = [];
177
- for (const sec of sections) {
178
- const secObj = sec;
179
- const title = extractTextContent(secObj.title);
180
- const text = extractTextContent(secObj.p);
181
- if (title && text) {
182
- parts.push(`${title}: ${text}`);
183
- }
184
- else if (text) {
185
- parts.push(text);
186
- }
187
- }
188
- const result = parts.join('\n\n').trim();
189
- return result || undefined;
190
- }
191
- // Simple abstract with just <p> elements
192
- if (obj.p) {
193
- const text = extractTextContent(obj.p);
194
- return text || undefined;
117
+ const sections = findAll(abstractNode, 'sec');
118
+ if (sections.length > 0) {
119
+ const parts = [];
120
+ for (const sec of sections) {
121
+ const title = textContent(findOne(sec, 'title'));
122
+ const text = findAll(sec, 'p')
123
+ .map((p) => textContent(p))
124
+ .filter(Boolean)
125
+ .join(' ');
126
+ if (title && text)
127
+ parts.push(`${title}: ${text}`);
128
+ else if (text)
129
+ parts.push(text);
195
130
  }
131
+ return parts.join('\n\n').trim() || undefined;
132
+ }
133
+ const paragraphs = findAll(abstractNode, 'p');
134
+ if (paragraphs.length > 0) {
135
+ return (paragraphs
136
+ .map((p) => textContent(p))
137
+ .filter(Boolean)
138
+ .join(' ') || undefined);
196
139
  }
197
- // Fallback: extract all text
198
- const text = extractTextContent(abstractNode);
199
- return text || undefined;
140
+ return textContent(abstractNode) || undefined;
200
141
  }
201
- // ─── Keywords Extraction ────────────────────────────────────────────────────
202
- /**
203
- * Extracts keywords from JATS kwd-group elements.
204
- */
205
- function extractKeywords(kwdGroups) {
206
- if (!kwdGroups)
142
+ function extractKeywords(articleMeta) {
143
+ if (!articleMeta)
207
144
  return [];
208
145
  const keywords = [];
209
- for (const group of ensureArray(kwdGroups)) {
210
- for (const kwd of ensureArray(group.kwd)) {
211
- const text = extractTextContent(kwd);
146
+ for (const group of findAll(articleMeta, 'kwd-group')) {
147
+ for (const kwd of findAll(group, 'kwd')) {
148
+ const text = textContent(kwd);
212
149
  if (text)
213
150
  keywords.push(text);
214
151
  }
215
152
  }
216
153
  return keywords;
217
154
  }
218
- // ─── Body Section Extraction ────────────────────────────────────────────────
155
+ // ─── Body Sections ──────────────────────────────────────────────────────────
219
156
  /**
220
- * Recursively extracts body sections from JATS sec elements.
157
+ * Extract body sections from a `<body>` node, walking children in document order.
158
+ * Consecutive bare `<p>` siblings are collected into an untitled section so
159
+ * articles with mixed structure (direct paragraphs + trailing `<sec>`, common
160
+ * in manuscript-submitted PMC deposits) preserve their main text.
221
161
  */
222
162
  export function extractBodySections(body) {
223
163
  if (!body)
224
164
  return [];
225
- // Some articles have paragraphs directly in body without section wrappers
226
- if (!body.sec) {
227
- if (body.p) {
228
- const text = extractTextContent(body.p);
229
- return text ? [{ text }] : [];
165
+ const sections = [];
166
+ let pendingParagraphs = [];
167
+ const flushPending = () => {
168
+ if (pendingParagraphs.length > 0) {
169
+ sections.push({ text: pendingParagraphs.join('\n\n') });
170
+ pendingParagraphs = [];
171
+ }
172
+ };
173
+ for (const child of childrenOf(body)) {
174
+ const tag = tagNameOf(child);
175
+ if (tag === 'p') {
176
+ const text = textContent(child);
177
+ if (text)
178
+ pendingParagraphs.push(text);
179
+ }
180
+ else if (tag === 'sec') {
181
+ flushPending();
182
+ const section = extractSection(child);
183
+ if (section)
184
+ sections.push(section);
230
185
  }
231
- return [];
232
186
  }
233
- return ensureArray(body.sec)
234
- .map(extractSection)
235
- .filter((s) => s !== null);
187
+ flushPending();
188
+ return sections;
236
189
  }
237
- /**
238
- * Extracts a single JATS section, recursing into subsections.
239
- */
240
190
  function extractSection(sec) {
241
- const title = extractTextContent(sec.title) || undefined;
242
- const label = extractTextContent(sec.label) || undefined;
243
- // Collect text from paragraphs
244
- const paragraphs = ensureArray(sec.p);
245
- const textParts = [];
246
- for (const p of paragraphs) {
247
- const text = extractTextContent(p);
248
- if (text)
249
- textParts.push(text);
250
- }
251
- // Recurse into subsections
252
- const subsections = sec.sec
253
- ? ensureArray(sec.sec)
254
- .map(extractSection)
255
- .filter((s) => s !== null)
256
- : undefined;
191
+ const title = textContent(findOne(sec, 'title')) || undefined;
192
+ const label = textContent(findOne(sec, 'label')) || undefined;
193
+ const paragraphs = findAll(sec, 'p');
194
+ const textParts = paragraphs.map((p) => textContent(p)).filter(Boolean);
195
+ const subsections = findAll(sec, 'sec')
196
+ .map(extractSection)
197
+ .filter((s) => s !== null);
257
198
  const text = textParts.join('\n\n');
258
- // Skip empty sections with no subsections
259
- if (!text && (!subsections || subsections.length === 0))
199
+ if (!text && subsections.length === 0)
260
200
  return null;
261
201
  return {
262
202
  ...(title && { title }),
263
203
  ...(label && { label }),
264
204
  text,
265
- ...(subsections && subsections.length > 0 && { subsections }),
205
+ ...(subsections.length > 0 && { subsections }),
266
206
  };
267
207
  }
268
- // ─── Reference Extraction ───────────────────────────────────────────────────
269
- /**
270
- * Extracts references from JATS back matter ref-list.
271
- */
208
+ // ─── References ─────────────────────────────────────────────────────────────
209
+ /** Extract references from a `<back>` node. Prefers mixed-citation over element-citation. */
272
210
  export function extractReferences(back) {
273
- if (!back?.['ref-list']?.ref)
211
+ if (!back)
212
+ return [];
213
+ const refList = findOne(back, 'ref-list');
214
+ if (!refList)
274
215
  return [];
275
- const refs = ensureArray(back['ref-list'].ref);
276
216
  const results = [];
277
- for (const ref of refs) {
278
- // Try mixed-citation first, then element-citation
279
- const citationNode = ref['mixed-citation'] ?? ref['element-citation'];
280
- const citation = extractTextContent(citationNode);
217
+ for (const ref of findAll(refList, 'ref')) {
218
+ const citationNode = findOne(ref, 'mixed-citation') ?? findOne(ref, 'element-citation');
219
+ if (!citationNode)
220
+ continue;
221
+ const citation = textContent(citationNode);
281
222
  if (!citation)
282
223
  continue;
283
- const label = ref.label ? extractTextContent(ref.label) || undefined : undefined;
224
+ const id = attrOf(ref, 'id');
225
+ const label = textContent(findOne(ref, 'label')) || undefined;
284
226
  results.push({
285
- ...(ref['@_id'] && { id: ref['@_id'] }),
227
+ ...(id && { id }),
286
228
  ...(label && { label }),
287
229
  citation,
288
230
  });
@@ -291,31 +233,32 @@ export function extractReferences(back) {
291
233
  }
292
234
  // ─── Main Parser ────────────────────────────────────────────────────────────
293
235
  /**
294
- * Parses a JATS XML article (from PMC EFetch) into a structured ParsedPmcArticle.
295
- * @param xmlArticle - The parsed JATS article object from fast-xml-parser.
296
- * @returns A fully parsed PMC article with metadata, body sections, and optional references.
236
+ * Parse a single JATS `<article>` node (from PMC EFetch via the ordered parser)
237
+ * into a structured `ParsedPmcArticle`. The input node is the element wrapper
238
+ * itself `{ article: [...], ':@': { '@_article-type': ... } }` not the
239
+ * outer `<pmc-articleset>`.
297
240
  */
298
- export function parsePmcArticle(xmlArticle) {
299
- const front = xmlArticle.front;
300
- const articleMeta = front?.['article-meta'];
301
- const journalMeta = front?.['journal-meta'];
302
- const articleIds = articleMeta?.['article-id'];
303
- const pmcId = extractArticleId(articleIds, 'pmcid') ?? extractArticleId(articleIds, 'pmc-uid') ?? '';
304
- const pmid = extractArticleId(articleIds, 'pmid');
305
- const doi = extractArticleId(articleIds, 'doi');
306
- const title = articleMeta?.['title-group']
307
- ? extractTextContent(articleMeta['title-group']['article-title']) || undefined
308
- : undefined;
309
- const authors = extractJatsAuthors(articleMeta?.['contrib-group']);
310
- const affiliations = extractAffiliations(articleMeta?.aff);
241
+ export function parsePmcArticle(articleNode) {
242
+ const front = findOne(articleNode, 'front');
243
+ const articleMeta = findOne(front, 'article-meta');
244
+ const journalMeta = findOne(front, 'journal-meta');
245
+ const body = findOne(articleNode, 'body');
246
+ const back = findOne(articleNode, 'back');
247
+ const pmcId = extractArticleId(articleMeta, 'pmcid') ?? extractArticleId(articleMeta, 'pmc-uid') ?? '';
248
+ const pmid = extractArticleId(articleMeta, 'pmid');
249
+ const doi = extractArticleId(articleMeta, 'doi');
250
+ const titleGroup = findOne(articleMeta, 'title-group');
251
+ const title = textContent(findOne(titleGroup, 'article-title')) || undefined;
252
+ const authors = collectAuthors(articleMeta);
253
+ const affiliations = extractAffiliations(articleMeta);
311
254
  const journal = extractJournal(journalMeta, articleMeta);
312
- const publicationDate = extractPubDate(articleMeta?.['pub-date']);
313
- const abstract = extractAbstract(articleMeta?.abstract);
314
- const keywords = extractKeywords(articleMeta?.['kwd-group']);
315
- const sections = extractBodySections(xmlArticle.body);
316
- const references = extractReferences(xmlArticle.back);
317
- // Normalize PMCID — ensure it has the PMC prefix (skip if empty)
255
+ const publicationDate = extractPubDate(articleMeta);
256
+ const abstract = extractAbstract(articleMeta);
257
+ const keywords = extractKeywords(articleMeta);
258
+ const sections = extractBodySections(body);
259
+ const references = extractReferences(back);
318
260
  const normalizedPmcId = !pmcId ? '' : pmcId.startsWith('PMC') ? pmcId : `PMC${pmcId}`;
261
+ const articleType = attrOf(articleNode, 'article-type');
319
262
  return {
320
263
  pmcId: normalizedPmcId,
321
264
  ...(pmid && { pmid }),
@@ -329,9 +272,19 @@ export function parsePmcArticle(xmlArticle) {
329
272
  ...(keywords.length > 0 && { keywords }),
330
273
  sections,
331
274
  ...(references.length > 0 && { references }),
332
- ...(xmlArticle['@_article-type'] && { articleType: xmlArticle['@_article-type'] }),
275
+ ...(articleType && { articleType }),
333
276
  pmcUrl: `https://www.ncbi.nlm.nih.gov/pmc/articles/${normalizedPmcId}/`,
334
277
  ...(pmid && { pubmedUrl: `https://pubmed.ncbi.nlm.nih.gov/${pmid}/` }),
335
278
  };
336
279
  }
280
+ /** Collect authors across every `<contrib-group>` under `<article-meta>`. */
281
+ function collectAuthors(articleMeta) {
282
+ if (!articleMeta)
283
+ return [];
284
+ const result = [];
285
+ for (const group of findAll(articleMeta, 'contrib-group')) {
286
+ result.push(...extractJatsAuthors(group));
287
+ }
288
+ return result;
289
+ }
337
290
  //# sourceMappingURL=pmc-article-parser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pmc-article-parser.js","sourceRoot":"","sources":["../../../../src/services/ncbi/parsing/pmc-article-parser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pmc-article-parser.js","sourceRoot":"","sources":["../../../../src/services/ncbi/parsing/pmc-article-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @fileoverview Helpers for fast-xml-parser output in `preserveOrder: true` mode.
3
+ * Each element node is `{ tagName: JatsNode[] }` with an optional `:@` carrying
4
+ * attributes; text nodes are `{ "#text": value }`. Preserving order is critical
5
+ * for JATS mixed content (e.g. `<p>text <italic>inline</italic> more text</p>`)
6
+ * — the default object shape collapses all text into a single string keyed by
7
+ * `#text`, dropping inline children's position. PMC full-text articles rely on
8
+ * this order for readable abstracts and body sections.
9
+ * @module src/services/ncbi/parsing/pmc-xml-helpers
10
+ */
11
+ /**
12
+ * A node in the ordered XML tree.
13
+ * - Element: `{ tagName: JatsNode[] }`, optionally with `:@` carrying attributes
14
+ * - Text: `{ "#text": string | number | boolean }`
15
+ */
16
+ export type JatsNode = Record<string, unknown>;
17
+ /**
18
+ * Ordered sibling list — every children array and the document root.
19
+ * Plain `JatsNode[]` (not readonly) so `Array.isArray` narrows inputs cleanly
20
+ * in `findOne` / `findAll`; callers should not mutate the list.
21
+ */
22
+ export type JatsNodeList = JatsNode[];
23
+ /** Tag name of an element (the single non-attribute key); undefined for text nodes. */
24
+ export declare function tagNameOf(node: JatsNode): string | undefined;
25
+ /** Ordered children of an element node. Empty for text nodes or missing tags. */
26
+ export declare function childrenOf(node: JatsNode): JatsNodeList;
27
+ /** Attribute value (caller omits the `@_` prefix). */
28
+ export declare function attrOf(node: JatsNode, name: string): string | undefined;
29
+ /** True for `{ "#text": ... }` nodes. */
30
+ export declare function isTextNode(node: JatsNode): boolean;
31
+ /** Stringified text value of a text node. */
32
+ export declare function textOf(node: JatsNode): string;
33
+ /**
34
+ * Extract all text from a node or sibling list in document order, collapsing
35
+ * runs of whitespace to a single space and trimming the result. Use this for
36
+ * mixed-content elements (`<p>`, `<title>`, `<abstract>`, …) where inline
37
+ * children must read back in the order they appear in the source.
38
+ */
39
+ export declare function textContent(input: JatsNode | JatsNodeList | undefined): string;
40
+ /** First direct child with the given tag name. */
41
+ export declare function findOne(input: JatsNode | JatsNodeList | undefined, tagName: string): JatsNode | undefined;
42
+ /** All direct children with the given tag name. */
43
+ export declare function findAll(input: JatsNode | JatsNodeList | undefined, tagName: string): JatsNode[];
44
+ //# sourceMappingURL=pmc-xml-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pmc-xml-helpers.d.ts","sourceRoot":"","sources":["../../../../src/services/ncbi/parsing/pmc-xml-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/C;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,QAAQ,EAAE,CAAC;AAKtC,uFAAuF;AACvF,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAK5D;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,YAAY,CAKvD;AAED,sDAAsD;AACtD,wBAAgB,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIvE;AAED,yCAAyC;AACzC,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAElD;AAED,6CAA6C;AAC7C,wBAAgB,MAAM,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAG7C;AAmBD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,YAAY,GAAG,SAAS,GAAG,MAAM,CAG9E;AAED,kDAAkD;AAClD,wBAAgB,OAAO,CACrB,KAAK,EAAE,QAAQ,GAAG,YAAY,GAAG,SAAS,EAC1C,OAAO,EAAE,MAAM,GACd,QAAQ,GAAG,SAAS,CAItB;AAED,mDAAmD;AACnD,wBAAgB,OAAO,CAAC,KAAK,EAAE,QAAQ,GAAG,YAAY,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CAI/F"}