docrev 0.7.8 → 0.7.9
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.
- package/lib/build.js +3 -2
- package/lib/crossref.js +60 -27
- package/package.json +1 -1
package/lib/build.js
CHANGED
|
@@ -213,7 +213,7 @@ export function combineSections(directory, config, options = {}) {
|
|
|
213
213
|
// Resolve forward references (refs that appear before their anchor definition)
|
|
214
214
|
// This fixes pandoc-crossref limitation with multi-file documents
|
|
215
215
|
if (hasPandocCrossref()) {
|
|
216
|
-
const registry = buildRegistry(directory);
|
|
216
|
+
const registry = buildRegistry(directory, sections);
|
|
217
217
|
const { text, resolved } = resolveForwardRefs(paperContent, registry);
|
|
218
218
|
if (resolved.length > 0) {
|
|
219
219
|
paperContent = text;
|
|
@@ -280,7 +280,8 @@ export function prepareForFormat(paperPath, format, config, options = {}) {
|
|
|
280
280
|
let content = fs.readFileSync(paperPath, 'utf-8');
|
|
281
281
|
|
|
282
282
|
// Build crossref registry for reference conversion
|
|
283
|
-
|
|
283
|
+
// Pass sections from config to ensure correct file ordering
|
|
284
|
+
const registry = buildRegistry(directory, config.sections);
|
|
284
285
|
|
|
285
286
|
if (format === 'pdf' || format === 'tex') {
|
|
286
287
|
// Strip all annotations for clean output
|
package/lib/crossref.js
CHANGED
|
@@ -11,6 +11,49 @@ import * as fs from 'fs';
|
|
|
11
11
|
import * as path from 'path';
|
|
12
12
|
import YAML from 'yaml';
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Discover section files from a directory by reading config files
|
|
16
|
+
* Only returns files explicitly defined in rev.yaml or sections.yaml
|
|
17
|
+
* Returns empty array if no config found (caller should handle this)
|
|
18
|
+
*
|
|
19
|
+
* @param {string} directory
|
|
20
|
+
* @returns {string[]} Ordered list of section filenames, or empty if no config
|
|
21
|
+
*/
|
|
22
|
+
function discoverSectionFiles(directory) {
|
|
23
|
+
// Try rev.yaml first
|
|
24
|
+
const revYamlPath = path.join(directory, 'rev.yaml');
|
|
25
|
+
if (fs.existsSync(revYamlPath)) {
|
|
26
|
+
try {
|
|
27
|
+
const config = YAML.parse(fs.readFileSync(revYamlPath, 'utf-8'));
|
|
28
|
+
if (config.sections && Array.isArray(config.sections) && config.sections.length > 0) {
|
|
29
|
+
return config.sections.filter(f => fs.existsSync(path.join(directory, f)));
|
|
30
|
+
}
|
|
31
|
+
} catch {
|
|
32
|
+
// Ignore yaml errors, try next option
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Try sections.yaml
|
|
37
|
+
const sectionsPath = path.join(directory, 'sections.yaml');
|
|
38
|
+
if (fs.existsSync(sectionsPath)) {
|
|
39
|
+
try {
|
|
40
|
+
const config = YAML.parse(fs.readFileSync(sectionsPath, 'utf-8'));
|
|
41
|
+
if (config.sections) {
|
|
42
|
+
const sectionOrder = Object.entries(config.sections)
|
|
43
|
+
.sort((a, b) => (a[1].order ?? 999) - (b[1].order ?? 999))
|
|
44
|
+
.map(([file]) => file);
|
|
45
|
+
return sectionOrder.filter(f => fs.existsSync(path.join(directory, f)));
|
|
46
|
+
}
|
|
47
|
+
} catch {
|
|
48
|
+
// Ignore yaml errors
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// No config found - return empty array
|
|
53
|
+
// Caller must handle this (either error or use explicit sections)
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
|
|
14
57
|
/**
|
|
15
58
|
* Patterns for detecting hardcoded references
|
|
16
59
|
* Matches complex patterns including:
|
|
@@ -208,8 +251,14 @@ export function parseReferenceList(listStr) {
|
|
|
208
251
|
* Build a registry of figure/table labels from .md files
|
|
209
252
|
* Scans for {#fig:label} and {#tbl:label} anchors
|
|
210
253
|
*
|
|
254
|
+
* IMPORTANT: This function requires either explicit sections or a rev.yaml/sections.yaml config.
|
|
255
|
+
* It will NOT guess by scanning all .md files, as this leads to incorrect numbering
|
|
256
|
+
* when temporary files (paper_clean.md, etc.) exist in the directory.
|
|
257
|
+
*
|
|
211
258
|
* @param {string} directory - Directory containing .md files
|
|
212
|
-
* @param {string[]} [
|
|
259
|
+
* @param {string[]} [sections] - Array of section filenames to scan (recommended).
|
|
260
|
+
* If not provided, reads from rev.yaml or sections.yaml.
|
|
261
|
+
* Returns empty registry if no sections can be determined.
|
|
213
262
|
* @returns {{
|
|
214
263
|
* figures: Map<string, {label: string, num: number, isSupp: boolean, file: string}>,
|
|
215
264
|
* tables: Map<string, {label: string, num: number, isSupp: boolean, file: string}>,
|
|
@@ -217,7 +266,7 @@ export function parseReferenceList(listStr) {
|
|
|
217
266
|
* byNumber: {fig: Map<string, string>, tbl: Map<string, string>, eq: Map<string, string>}
|
|
218
267
|
* }}
|
|
219
268
|
*/
|
|
220
|
-
export function buildRegistry(directory,
|
|
269
|
+
export function buildRegistry(directory, sections) {
|
|
221
270
|
const figures = new Map();
|
|
222
271
|
const tables = new Map();
|
|
223
272
|
const equations = new Map();
|
|
@@ -229,32 +278,16 @@ export function buildRegistry(directory, excludeFiles = ['paper.md', 'README.md'
|
|
|
229
278
|
let tblSuppNum = 0;
|
|
230
279
|
let eqNum = 0;
|
|
231
280
|
|
|
232
|
-
|
|
233
|
-
const files = fs.readdirSync(directory).filter((f) => {
|
|
234
|
-
if (!f.endsWith('.md')) return false;
|
|
235
|
-
if (excludeFiles.some((e) => f.toLowerCase() === e.toLowerCase())) return false;
|
|
236
|
-
return true;
|
|
237
|
-
});
|
|
281
|
+
let orderedFiles;
|
|
238
282
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
.sort((a, b) => (a[1].order ?? 999) - (b[1].order ?? 999))
|
|
248
|
-
.map(([file]) => file);
|
|
249
|
-
orderedFiles = sectionOrder.filter((f) => files.includes(f));
|
|
250
|
-
// Add any remaining files not in sections.yaml
|
|
251
|
-
for (const f of files) {
|
|
252
|
-
if (!orderedFiles.includes(f)) orderedFiles.push(f);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
} catch {
|
|
256
|
-
// Ignore yaml errors, use default order
|
|
257
|
-
}
|
|
283
|
+
if (Array.isArray(sections) && sections.length > 0) {
|
|
284
|
+
// Use explicitly provided section files - most reliable
|
|
285
|
+
orderedFiles = sections.filter(f => fs.existsSync(path.join(directory, f)));
|
|
286
|
+
} else {
|
|
287
|
+
// Try to determine sections from config files (rev.yaml or sections.yaml)
|
|
288
|
+
orderedFiles = discoverSectionFiles(directory);
|
|
289
|
+
// If no config found, return empty registry rather than guessing
|
|
290
|
+
// This prevents bugs from scanning wrong files
|
|
258
291
|
}
|
|
259
292
|
|
|
260
293
|
// Determine if a file is supplementary
|