Skip to content

EXPORT_PDF_COMMAND using weasyprint does not work as documented for versions < 53 #5301

@watschi

Description

@watschi

Describe the Bug

When configuring the EXPORT_PDF_COMMAND as documented at Admin Documentation > PDF Rendering, an error is thrown because weasyprint prints its help message due to a missing option or file extension.

Steps to Reproduce

  1. Configure EXPORT_PDF_COMMAND="weasyprint {input_html_path} {output_pdf_path}"
  2. Export a page to PDF
[2024-10-30 15:46:41] production.ERROR: PDF Export via command failed with exit code 2, stdout: , stderr: usage: weasyprint [-h] [--version] [-i] [-e ENCODING] [-f {pdf,png}]
                  [-s STYLESHEET] [-m MEDIA_TYPE] [-r RESOLUTION]
                  [-u BASE_URL] [-a ATTACHMENT] [-p] [-v] [-d] [-q]
                  input output
weasyprint: error: Either specify a format with -f or choose an output filename that ends in .pdf or .png
 {"userId":3,"exception":"[object] (BookStack\\Exceptions\\PdfExportException(code: 0): PDF Export via command failed with exit code 2, stdout: , stderr: usage: weasyprint [-h] [--version] [-i] [-e ENCODING] [-f {pdf,png}]
                  [-s STYLESHEET] [-m MEDIA_TYPE] [-r RESOLUTION]
                  [-u BASE_URL] [-a ATTACHMENT] [-p] [-v] [-d] [-q]
[-s STYLESHEET] [-m MEDIA_TYPE] [-r RESOLUTION]
                  [-u BASE_URL] [-a ATTACHMENT] [-p] [-v] [-d] [-q]
                  input output
weasyprint: error: Either specify a format with -f or choose an output filename that ends in .pdf or .png
 at /var/www/bookstack/app/Entities/Tools/PdfGenerator.php:100)
[stacktrace]
#0 /var/www/bookstack/app/Entities/Tools/PdfGenerator.php(24): BookStack\\Entities\\Tools\\PdfGenerator->renderUsingCommand()
#1 /var/www/bookstack/app/Entities/Tools/ExportFormatter.php(160): BookStack\\Entities\\Tools\\PdfGenerator->fromHtml()
#2 /var/www/bookstack/app/Entities/Tools/ExportFormatter.php(100): BookStack\\Entities\\Tools\\ExportFormatter->htmlToPdf()
#3 /var/www/bookstack/app/Entities/Controllers/PageExportController.php(32): BookStack\\Entities\\Tools\\ExportFormatter->pageToPdf()
#4 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): BookStack\\Entities\\Controllers\\PageExportController->pdf()
#5 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(43): Illuminate\\Routing\\Controller->callAction()
#6 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Routing/Route.php(259): Illuminate\\Routing\\ControllerDispatcher->dispatch()
#7 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Routing/Route.php(205): Illuminate\\Routing\\Route->runController()
#8 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Routing/Router.php(806): Illuminate\\Routing\\Route->run()
#9 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(144): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}()
#10 /var/www/bookstack/app/Http/Middleware/CheckUserHasPermission.php(25): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#11 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): BookStack\\Http\\Middleware\\CheckUserHasPermission->handle()
#12 /var/www/bookstack/app/Http/Middleware/Authenticate.php(23): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#13 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): BookStack\\Http\\Middleware\\Authenticate->handle()
#14 /var/www/bookstack/app/Http/Middleware/Localization.php(32): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#15 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): BookStack\\Http\\Middleware\\Localization->handle()
#16 /var/www/bookstack/app/Http/Middleware/RunThemeActions.php(26): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#17 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): BookStack\\Http\\Middleware\\RunThemeActions->handle()
#18 /var/www/bookstack/app/Http/Middleware/CheckEmailConfirmed.php(47): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#19 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): BookStack\\Http\\Middleware\\CheckEmailConfirmed->handle()
#20 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#21 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle()
#22 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#23 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle()
#24 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#25 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest()
#26 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Session\\Middleware\\StartSession->handle()
#27 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#28 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle()
#29 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#30 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle()
#31 /var/www/bookstack/app/Http/Middleware/ApplyCspRules.php(33): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#32 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): BookStack\\Http\\Middleware\\ApplyCspRules->handle()
#33 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#34 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Routing/Router.php(805): Illuminate\\Pipeline\\Pipeline->then()
#35 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Routing/Router.php(784): Illuminate\\Routing\\Router->runRouteWithinStack()
#36 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Routing/Router.php(748): Illuminate\\Routing\\Router->runRoute()
#37 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Routing/Router.php(737): Illuminate\\Routing\\Router->dispatchToRoute()
#38 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(200): Illuminate\\Routing\\Router->dispatch()
#39 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(144): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}()
#40 /var/www/bookstack/app/Http/Middleware/PreventResponseCaching.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#41 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): BookStack\\Http\\Middleware\\PreventResponseCaching->handle()
#42 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(39): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#43 /var/www/bookstack/app/Http/Middleware/TrustProxies.php(41): Illuminate\\Http\\Middleware\\TrustProxies->handle()
#44 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): BookStack\\Http\\Middleware\\TrustProxies->handle()
#45 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#46 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#47 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle()
#48 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#49 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle()
#50 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(99): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#51 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle()
#52 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#53 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(175): Illuminate\\Pipeline\\Pipeline->then()
#54 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(144): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter()
#55 /var/www/bookstack/public/index.php(52): Illuminate\\Foundation\\Http\\Kernel->handle()
#56 {main}
"}

Expected Behaviour

Export the page to pdf.

Screenshots or Additional Context

This issue can be resolved by adding the --format pdf argument to the weasyprint command (see https://codeberg.org/bookstack/website/pulls/190).
Edit: Or by updating weasyprint to a current version.
Opening this issue so others affected can find it.

Also @ssddanbrown: Does it make sense to add a pdf extension to the export filename here (PdfGenerator.php)?
I know other tools like pandoc also use file extensions to determine the output format if not explicitly mentioned, maybe this will save some people some time.

weasyprint version:

# weasyprint --version
WeasyPrint version 51

Browser Details

No response

Exact BookStack Version

v24.10

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions