Path: blob/master/src/packages/project/print_to_pdf.ts
1447 views
/*1* This file is part of CoCalc: Copyright © 2023 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45//##############################################6// Printing an individual file to pdf7//##############################################89import { unlink, writeFile } from "node:fs/promises";10import { path as temp_path } from "temp";1112import { executeCode } from "@cocalc/backend/execute-code";13import { CoCalcSocket } from "@cocalc/backend/tcp/enable-messaging-protocol";14import * as message from "@cocalc/util/message";15import { defaults, filename_extension, required } from "@cocalc/util/misc";1617interface SagewsPrintOpts {18path: string;19outfile: string;20title: string;21author: string;22date: string;23contents: string;24subdir: string;25base_url?: string;26extra_data?: string;27timeout?: number;28}2930export async function printSageWS(opts: SagewsPrintOpts) {31opts = defaults(opts, {32path: required,33outfile: required,34title: required,35author: required,36date: required,37contents: required,38subdir: required, // 'true' or 'false', if true, then workdir is a generated subdirectory which will retain the temporary tex files39base_url: undefined, // the base_url for downloading blobs/images40extra_data: undefined, // extra data that is useful for displaying certain things in the worksheet.41timeout: 90,42});4344let extra_data_file: string | undefined = undefined;45let args = [46opts.path,47"--outfile",48opts.outfile,49"--title",50opts.title,51"--author",52opts.author,53"--date",54opts.date,55"--subdir",56opts.subdir,57"--contents",58opts.contents,59];60if (opts.base_url) {61args = args.concat(["--base_url", opts.base_url]);62}6364try {65if (opts.extra_data != null) {66extra_data_file = temp_path() + ".json";67args.push("--extra_data_file");68args.push(extra_data_file);69// NOTE: extra_data is a string that is *already* in JSON format.70await writeFile(extra_data_file, opts.extra_data);71}7273// run the converter script74await executeCode({75command: "smc-sagews2pdf",76args,77err_on_exit: true,78bash: false,79timeout: opts.timeout,80});81} finally {82if (extra_data_file != null) {83unlink(extra_data_file); // no need to wait84}85}86}8788export async function print_to_pdf(socket: CoCalcSocket, mesg) {89let pdf;90const ext = filename_extension(mesg.path);91if (ext) {92pdf = `${mesg.path.slice(0, mesg.path.length - ext.length)}pdf`;93} else {94pdf = mesg.path + ".pdf";95}9697try {98switch (ext) {99case "sagews":100await printSageWS({101path: mesg.path,102outfile: pdf,103title: mesg.options.title,104author: mesg.options.author,105date: mesg.options.date,106contents: mesg.options.contents,107subdir: mesg.options.subdir,108extra_data: mesg.options.extra_data,109timeout: mesg.options.timeout,110});111break;112113default:114throw new Error(`unable to print file of type '${ext}'`);115}116117// all good118return socket.write_mesg(119"json",120message.printed_to_pdf({ id: mesg.id, path: pdf }),121);122} catch (err) {123return socket.write_mesg(124"json",125message.error({ id: mesg.id, error: err }),126);127}128}129130131