@@ -3,7 +3,7 @@ import { getArgsContent } from '@unified-latex/unified-latex-util-arguments';
33import { unifiedLatexFromString } from '@unified-latex/unified-latex-util-parse' ;
44import { unifiedLatexStringCompiler } from '@unified-latex/unified-latex-util-to-string' ;
55import { visit } from '@unified-latex/unified-latex-util-visit' ;
6- import { dirname , parse , resolve } from 'pathe' ;
6+ import { dirname , join , parse , resolve } from 'pathe' ;
77import { unified } from 'unified' ;
88
99import { Fs } from '@isos/fs/types' ;
@@ -39,7 +39,11 @@ async function getLatexAst(
3939) {
4040 const processor = unified ( )
4141 // @ts -expect-error
42- . use ( unifiedLatexFromString )
42+ . use ( unifiedLatexFromString , {
43+ macros : {
44+ graphicspath : { signature : 'm' } ,
45+ } ,
46+ } )
4347 . use ( recursivelyIncludeFiles , ctx , fs , subFiles ) ;
4448 const parsed = processor . parse ( input ) ;
4549 const transformed = await processor . run ( parsed ) ;
@@ -53,22 +57,41 @@ function recursivelyIncludeFiles(
5357 subFiles : string [ ] ,
5458) {
5559 return async ( tree : Ast . Root ) => {
56- const dir = dirname ( ctx . srcFilePath ) ;
60+ // console.log(tree);
61+
62+ const srcDir = dirname ( ctx . srcFilePath ) ;
5763 const includePaths : string [ ] = [ ] ;
5864
65+ let graphicsPath = '' ;
66+
5967 visit ( tree , ( node ) => {
6068 if ( node . type === 'macro' ) {
6169 if ( isInclude ( node ) ) {
62- const fullPath = getFullPath ( node , dir ) ;
70+ const fullPath = getFullPath ( node , srcDir , '.tex' ) ;
6371 includePaths . push ( fullPath ) ;
6472 subFiles . push ( fullPath ) ;
6573 }
74+
75+ // let graphicspath float through files
76+ if ( node . content === 'graphicspath' ) {
77+ const args = getArgsContent ( node as Ast . Macro ) ;
78+ const lastArg = args [ args . length - 1 ] || [ ] ;
79+ const group = lastArg . find ( ( o ) => o . type === 'group' ) || {
80+ type : 'group' ,
81+ content : [ ] ,
82+ } ;
83+ const content = group . content as Ast . String [ ] ;
84+ graphicsPath = printRaw ( content ) ;
85+ }
86+
6687 if ( isImage ( node ) ) {
67- // default to .pdf if no extension given
68- const fullPath = getFullPath ( node , dir ) ;
69- const { name, ext } = parse ( fullPath ) ;
70- const filePath = `${ dir } /${ name } ${ ext || '.pdf' } ` ;
71- subFiles . push ( filePath ) ;
88+ const args = getArgsContent ( node as Ast . Macro ) ;
89+ const lastArg = args [ args . length - 1 ] || [ ] ;
90+ // prepend graphicspath to image file paths
91+ lastArg . unshift ( { type : 'string' , content : graphicsPath } ) ;
92+
93+ const fullPath = getFullPath ( node , srcDir , '.pdf' ) ;
94+ subFiles . push ( fullPath ) ;
7295 }
7396 }
7497 } ) ;
@@ -91,8 +114,8 @@ function recursivelyIncludeFiles(
91114
92115 visit ( tree , ( node , info ) => {
93116 if ( node . type === 'macro' && isInclude ( node ) ) {
94- const filePath = getFullPath ( node , dir ) ;
95- const ast = contents [ filePath ] ;
117+ const fullPath = getFullPath ( node , srcDir , '.tex' ) ;
118+ const ast = contents [ fullPath ] ;
96119 if ( ast ) {
97120 const idx = info . index || 0 ;
98121 const parent = info . parents [ 0 ] as Ast . Environment ;
@@ -113,8 +136,9 @@ function isImage(node: Ast.Macro) {
113136 return [ 'includegraphics' ] . includes ( node . content ) ;
114137}
115138
116- function getFullPath ( node : Ast . Macro , dir : string ) {
139+ function getFullPath ( node : Ast . Macro , srcDir : string , defaultExt : string ) {
117140 const args = getArgsContent ( node as Ast . Macro ) ;
118- const filePath = printRaw ( args [ args . length - 1 ] || [ ] ) ;
119- return resolve ( dir , filePath ) ;
141+ const fullPath = printRaw ( args [ args . length - 1 ] || [ ] ) ;
142+ const { dir, name, ext } = parse ( fullPath ) ;
143+ return resolve ( srcDir , dir , `${ name } ${ ext || defaultExt } ` ) ;
120144}
0 commit comments