const { writeFile , unlink } = require ( "fs" ) ; const tmp = require ( "tmp" ) ; const { callback } = require ( "awaiting" ) ; const { spawn } = require ( "child_process" ) ; const { replace_all } = require ( "@cocalc/util/misc" ) ; interface ParserOptions { parser : string ; tabWidth ? : number ; useTabs ? : boolean ; } function close ( proc , cb ) { proc . on ( "close" , ( code ) => cb ( undefined , code ) ) ; } export async function latex_format ( input , options ) { const input_path = await callback ( tmp . file , { postfix : ".tex" } ) ; try { await callback ( writeFile , input_path , input ) ; const latexindent = spawn ( "latexindent" , [ input_path ] ) ; let output = "" ; latexindent . stdout . on ( "data" , ( data ) => ( output += data . toString ( ) ) ) ; const code = await callback ( close , latexindent ) ; if ( code ) { throw Error ( `latexindent exited with code ${ code }` ) ; } if ( ! options . useTabs ) { let tab_width = 2 ; if ( options . tabWidth !== undefined ) { tab_width = options . tabWidth ; } let SPACES = "" ; for ( let i = 0 ; i < tab_width ; i ++ ) { SPACES += " " ; } output = replace_all ( output , "\t" , SPACES ) ; } const lines = output . split ( "\n" ) , lines2 = [ ] ; for ( let i = 0 ; i < lines . length ; i ++ ) { if ( /\S/ . test ( lines [ i ] ) ) { lines2 . push ( lines [ i ] ) ; } else { lines2 . push ( "" ) ; } output = lines2 . join ( "\n" ) ; } return output ; } finally { unlink ( input_path , ( ) => { } ) ; } }