diff --git a/.changeset/cyan-moles-leave.md b/.changeset/cyan-moles-leave.md new file mode 100644 index 000000000..7e13f1f2d --- /dev/null +++ b/.changeset/cyan-moles-leave.md @@ -0,0 +1,5 @@ +--- +'myst-cli': patch +--- + +Fix crosslinked content for single file exports diff --git a/.changeset/lucky-moles-mix.md b/.changeset/lucky-moles-mix.md new file mode 100644 index 000000000..1871078fa --- /dev/null +++ b/.changeset/lucky-moles-mix.md @@ -0,0 +1,6 @@ +--- +'myst-directives': patch +'myst-parser': patch +--- + +Remove identifier from embed node diff --git a/.changeset/poor-toes-work.md b/.changeset/poor-toes-work.md new file mode 100644 index 000000000..cb017df46 --- /dev/null +++ b/.changeset/poor-toes-work.md @@ -0,0 +1,5 @@ +--- +'myst-to-tex': patch +--- + +Remove {name} template from getting printed into single article exports diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dfa3c118f..5effef28c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,6 +33,7 @@ jobs: with: fetch-depth: 2 submodules: recursive + - run: sudo apt-get update - run: sudo apt-get install -y libxml2-utils - name: Setup Node.js environment uses: actions/setup-node@v2 diff --git a/packages/myst-cli/src/build/utils/collectExportOptions.ts b/packages/myst-cli/src/build/utils/collectExportOptions.ts index fa99842ba..466cf29e6 100644 --- a/packages/myst-cli/src/build/utils/collectExportOptions.ts +++ b/packages/myst-cli/src/build/utils/collectExportOptions.ts @@ -39,7 +39,7 @@ async function prepareExportOptions( exportOptions.forEach((exp) => { // If no files are specified, use the sourceFile for article if (!exp.article && SOURCE_EXTENSIONS.includes(path.extname(sourceFile))) { - exp.article = sourceFile; + exp.article = path.resolve(sourceFile); } // Also validate that sub_articles exist if (exp.sub_articles) { diff --git a/packages/myst-cli/src/build/utils/getFileContent.ts b/packages/myst-cli/src/build/utils/getFileContent.ts index ae3f2997e..105f2b307 100644 --- a/packages/myst-cli/src/build/utils/getFileContent.ts +++ b/packages/myst-cli/src/build/utils/getFileContent.ts @@ -35,12 +35,14 @@ export async function getFileContent( const toc = tic(); files = files.map((file) => resolve(file)); projectPath = projectPath ?? resolve('.'); - const { project } = await loadProject(session, projectPath); + const { project, pages } = await loadProject(session, projectPath); + const projectFiles = pages.map((page) => page.file); + const allFiles = [...new Set([...files, ...projectFiles])]; await Promise.all([ // Load all citations (.bib) ...project.bibliography.map((path) => loadFile(session, path, '.bib')), // Load all content (.md and .ipynb) - ...files.map((file) => loadFile(session, file, undefined, { minifyMaxCharacters: 0 })), + ...allFiles.map((file) => loadFile(session, file, undefined, { minifyMaxCharacters: 0 })), // Load up all the intersphinx references loadIntersphinx(session, { projectPath }) as Promise, ]); @@ -55,7 +57,7 @@ export async function getFileContent( // extraTransforms.push(...opts.extraTransforms); // } await Promise.all( - files.map(async (file) => { + allFiles.map(async (file) => { await transformMdast(session, { file, imageWriteFolder, @@ -68,7 +70,7 @@ export async function getFileContent( ); const pageReferenceStates = selectPageReferenceStates( session, - files.map((file) => { + allFiles.map((file) => { return { file }; }), ); @@ -82,6 +84,12 @@ export async function getFileContent( return selectedFile; }), ); - session.log.info(toc(`📚 Built ${files.length} pages for export from ${projectPath} in %s.`)); + session.log.info( + toc( + `📚 Built ${allFiles.length} pages for export (including ${ + allFiles.length - files.length + } dependencies) from ${projectPath} in %s.`, + ), + ); return selectedFiles; } diff --git a/packages/myst-directives/src/embed.ts b/packages/myst-directives/src/embed.ts index 4c453a11d..2217ed02d 100644 --- a/packages/myst-directives/src/embed.ts +++ b/packages/myst-directives/src/embed.ts @@ -16,12 +16,11 @@ export const embedDirective: DirectiveSpec = { }, }, run(data: DirectiveData): GenericNode[] { - const { label, identifier } = normalizeLabel(data.options?.label as string) || {}; + const { label } = normalizeLabel(data.options?.label as string) || {}; return [ { type: 'embed', label, - identifier, 'remove-input': data.options?.['remove-input'], 'remove-output': data.options?.['remove-output'], }, diff --git a/packages/myst-parser/tests/directives/embed.yml b/packages/myst-parser/tests/directives/embed.yml index 54e08c41d..ba36a2816 100644 --- a/packages/myst-parser/tests/directives/embed.yml +++ b/packages/myst-parser/tests/directives/embed.yml @@ -17,5 +17,4 @@ cases: children: - type: embed label: hi - identifier: hi remove-output: true diff --git a/packages/myst-to-jats/jest.config.cjs b/packages/myst-to-jats/jest.config.cjs index 12a5f074e..79c0bc362 100644 --- a/packages/myst-to-jats/jest.config.cjs +++ b/packages/myst-to-jats/jest.config.cjs @@ -17,7 +17,7 @@ module.exports = { verbose: true, testEnvironment: 'node', transformIgnorePatterns: [ - '/node_modules/(?!(vfile|formdata-polyfill|chalk|fetch-blob|vfile-message|unified|bail|trough|zwitch|unist-|hast-|html-|rehype-|mdast-|micromark-|trim-|web-namespaces|property-information|space-separated-tokens|comma-separated-tokens|get-port|stringify-entities|character-entities-html4|ccount))', + '/node_modules/(?!(vfile|formdata-polyfill|chalk|fetch-blob|vfile-message|unified|bail|trough|zwitch|unist-|hast-|html-|rehype-|mdast-|micromark-|trim-|web-namespaces|property-information|space-separated-tokens|comma-separated-tokens|get-port|stringify-entities|character-entities-html4|ccount|is-plain-obj|nanoid))', ], testPathIgnorePatterns: ['/node_modules/', '/.yalc/', '/dist/'], }; diff --git a/packages/myst-to-jats/package.json b/packages/myst-to-jats/package.json index 3407ba0b4..64782b80d 100644 --- a/packages/myst-to-jats/package.json +++ b/packages/myst-to-jats/package.json @@ -50,13 +50,18 @@ "myst-frontmatter": "^0.0.12", "myst-spec": "^0.0.4", "myst-spec-ext": "^0.0.10", + "unified": "^10.1.2", "unist-util-select": "^4.0.3", "vfile-reporter": "^7.0.4", "xml-js": "^1.6.11" }, "devDependencies": { "@types/jest": "^28.1.6", + "@types/js-yaml": "^4.0.5", + "@types/mdast": "^3.0.11", "jest": "^28.1.3", + "js-yaml": "^4.1.0", + "myst-cli-utils": "^0.0.11", "npm-run-all": "^4.1.5", "prettier": "^2.6.1", "rimraf": "^3.0.2", diff --git a/packages/myst-to-jats/tests/basic.spec.ts b/packages/myst-to-jats/tests/basic.spec.ts index 60133f780..7b976b38e 100644 --- a/packages/myst-to-jats/tests/basic.spec.ts +++ b/packages/myst-to-jats/tests/basic.spec.ts @@ -7,6 +7,8 @@ import yaml from 'js-yaml'; import { VFile } from 'vfile'; import mystToJats, { writeJats } from '../src'; +const TEST_DTD = false; + type TestFile = { cases: TestCase[]; }; @@ -39,6 +41,19 @@ const testLogger = new Session({ }, }); +function addHeader(data: string) { + return ` + +
+ + + + + ${data} + +
`; +} + async function writeValidateDelete(data: string) { const testXml = path.join(__dirname, 'test.xml'); fs.writeFileSync(testXml, data); @@ -49,11 +64,12 @@ async function writeValidateDelete(data: string) { describe('Basic JATS body', () => { const cases = loadCases('basic.yml'); - test.each(cases.map((c): [string, TestCase] => [c.title, c]))('%s', (_, { tree, jats }) => { + test.each(cases.map((c): [string, TestCase] => [c.title, c]))('%s', async (_, { tree, jats }) => { const pipe = unified().use(mystToJats); pipe.runSync(tree as any); const vfile = pipe.stringify(tree as any); expect(vfile.result).toEqual(jats); + if (TEST_DTD) expect(await writeValidateDelete(addHeader(vfile.result as string))).toBeTruthy(); }); }); @@ -69,7 +85,7 @@ describe('JATS full article', () => { pipe.runSync(tree as any); const vfile = pipe.stringify(tree as any); expect(vfile.result).toEqual(jats); - expect(await writeValidateDelete(vfile.result as string)).toBeTruthy(); + if (TEST_DTD) expect(await writeValidateDelete(vfile.result as string)).toBeTruthy(); }, ); }); @@ -86,7 +102,7 @@ describe('JATS full article with bibliography', () => { pipe.runSync(tree as any); const vfile = pipe.stringify(tree as any); expect(vfile.result).toEqual(jats); - expect(await writeValidateDelete(vfile.result as string)).toBeTruthy(); + if (TEST_DTD) expect(await writeValidateDelete(vfile.result as string)).toBeTruthy(); }, ); }); @@ -106,7 +122,7 @@ describe('JATS multi-article', () => { }, ); expect(vfile.result).toEqual(jats); - expect(await writeValidateDelete(vfile.result as string)).toBeTruthy(); + if (TEST_DTD) expect(await writeValidateDelete(vfile.result as string)).toBeTruthy(); }, ); }); @@ -115,7 +131,7 @@ describe('JATS SI units', () => { const cases = loadCases('siunit.yml'); test.each(cases.map((c): [string, TestCase] => [c.title, c]))( '%s', - (_, { tree, jats, frontmatter, citations }) => { + async (_, { tree, jats, frontmatter, citations }) => { const vfile = writeJats( new VFile(), { mdast: tree as any, frontmatter, citations }, @@ -124,6 +140,9 @@ describe('JATS SI units', () => { }, ); expect(vfile.result).toEqual(jats); + if (TEST_DTD) { + expect(await writeValidateDelete(addHeader(vfile.result as string))).toBeTruthy(); + } }, ); }); diff --git a/packages/myst-to-tex/src/index.ts b/packages/myst-to-tex/src/index.ts index 2d96a4c7b..c07dccce0 100644 --- a/packages/myst-to-tex/src/index.ts +++ b/packages/myst-to-tex/src/index.ts @@ -220,7 +220,8 @@ const handlers: Record = { captionNumber: () => undefined, crossReference(node, state) { // Look up reference and add the text - const text = (node.template ?? toText(node))?.replace(/\s/g, '~') || '%s'; + const usedTemplate = node.template?.includes('%s') ? node.template : undefined; + const text = (usedTemplate ?? toText(node))?.replace(/\s/g, '~') || '%s'; const id = node.label; state.write(text.replace(/%s/g, `\\ref{${id}}`)); },