Index: CHANGES.txt ================================================================== --- CHANGES.txt +++ CHANGES.txt @@ -1,5 +1,12 @@ +Version [next] + +[Feature] On Windows, Ghostscript replaced pdfroff. +[Bugfix] The groff detection logic was not as logical as it should have been. + +------------------------------- + Version 0.13.2 2024-04-30 [Improved] Multi-threading is more standards-compliant now (thanks @Th69). Index: README.md ================================================================== --- README.md +++ README.md @@ -10,10 +10,11 @@ * Written in Lazarus (Free Pascal). * Should be cross-platform. * Successfully tested on Windows 10, macOS and Linux. * Can produce PS and PDF files. + * On Windows, creating PDF files requires [Ghostscript](https://www.ghostscript.com/) for the time being. On other systems, [i]groff[/i] should be able to just do it. * Can handle some macros. ## License `groffstudio` is free software under the terms of the CDDL-1.1. Feel free to help me with development. I'll happily grant you access to the upstream repository if you are good. Index: src/groffstudio.lpi ================================================================== --- src/groffstudio.lpi +++ src/groffstudio.lpi @@ -20,13 +20,11 @@ - - - + Index: src/unit1.pas ================================================================== --- src/unit1.pas +++ src/unit1.pas @@ -123,47 +123,64 @@ var MainForm: TMainForm; BuildWindow: TBuildStatusWindow; hasGroff: boolean; GroffOutputVersion: string; + {$IFDEF WINDOWS} + hasGhostscript: boolean; + ps2pdfOutput: string; + {$ENDIF} implementation {$R *.lfm} procedure TDetectGroffThread.UpdateUI; begin + // groff: MainForm.edtGroffInstalledVersion.Text := GroffOutputVersion; if pos('GNU', GroffOutputVersion) = 0 then begin ShowMessage('groffstudio thinks that your installed version of troff is not GNU troff.' + LineEnding + 'If this is correct, you are advised to fix this before continuing.' + LineEnding + 'If it is an error, please tell me so I can improve this detection.'); - hasGroff := True; + hasGroff := False; + MainForm.edtGroffInstalledVersion.Text := 'n/a'; + MainForm.lblTroffCommandNotFound.Visible := True; end else + hasGroff := True; + + // ps2pdf (Windows-only): + {$IFDEF WINDOWS} + if pos('ps2pdf', ps2pdfOutput) = 0 then begin - MainForm.edtGroffInstalledVersion.Text := 'n/a'; - hasGroff := False; - MainForm.lblTroffCommandNotFound.Visible := True; + ShowMessage('On Windows, for creating PDF files, you need Ghostscript installed.' + + LineEnding + 'Sadly, groffstudio could not find ps2pdf.exe in your %PATH%, so ' + + 'writing PDF files will not be supported.'); + hasGhostscript := False; + MainForm.rdPdf.Enabled := False; + end else begin + hasGhostscript := True; + MainForm.rdPdf.Enabled := True; end; + {$ENDIF} end; procedure TDetectGroffThread.Execute; begin FreeOnTerminate := True; {$IFDEF WINDOWS} - if RunCommand('cmd', ['/c', 'troff --version'], GroffOutputVersion, [], swoHIDE) then + RunCommand('cmd', ['/c', 'troff --version'], GroffOutputVersion, [], swoHIDE); + RunCommand('cmd', ['/c', 'ps2pdf'], ps2pdfOutput, [], swoHIDE); {$ELSE} - if RunCommand('/bin/sh', ['-c', 'troff --version'], GroffOutputVersion, - [], swoHIDE) then + RunCommand('/bin/sh', ['-c', 'troff --version'], GroffOutputVersion, + [], swoHIDE); {$ENDIF} - begin - Synchronize(@UpdateUI); - end; + Synchronize(@UpdateUI); end; { TMainForm } procedure TMainForm.FormCreate(Sender: TObject); @@ -373,17 +390,23 @@ if chkBoxPreprocessors.Checked[5] then buildOpts := buildOpts + ' -tbl'; if chkBoxExtras.Checked[0] then buildOpts := buildOpts + ' -mhdtbl'; // - PDF-specifics: + {$IFNDEF WINDOWS} + // On Windows, we use a two-step program: + // 1) Output to PostScript, + // 2) ps2pdf to PDF. + // This is because there is no pdfroff.exe. Requires Ghostscript. if rdPdf.Checked then begin buildOpts := buildOpts + ' -Tpdf'; if chkBoxExtras.Checked[1] then buildOpts := buildOpts + ' -mpdfmark'; outputFileName := currentGroffFilePath + '.pdf'; end else + {$ENDIF} outputFileName := currentGroffFilePath + '.ps'; // - Input file: buildOpts := buildOpts + ' ' + currentGroffFilePath; buildOpts := buildOpts + ' > ' + outputFileName; @@ -395,10 +418,28 @@ buildSuccess := BuildWindow.BuildDocument(buildOpts, logFileName); if buildSuccess then MainStatusBar.Panels[1].Text := 'build successful' else MainStatusBar.Panels[1].Text := 'build problem'; + + {$IFDEF WINDOWS} + if buildSuccess and hasGhostscript then + begin + // Invoke ps2pdf: + buildOpts := 'ps2pdf'; + // outputFileName is still the .ps file. Just use it as the input name. + buildOpts := buildOpts + ' ' + outputFileName; + buildSuccess := BuildWindow.BuildDocument(buildOpts, logFileName); + if buildSuccess then + begin + MainStatusBar.Panels[1].Text := 'build successful'; + DeleteFile(outputFileName); // get rid of the .ps file + end + else + MainStatusBar.Panels[1].Text := 'build problem'; + end; + {$ENDIF} FreeAndNil(BuildWindow); end; procedure TMainForm.btnLoadGroffClick(Sender: TObject);