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);