groffstudio

Check-in Differences
Login

Difference From 8bb30e04bd97756c To 3b615f92bd879d7f

2024-01-30
22:21
[Improved] Multi-threading is more standards-compliant now (thanks @Th69). Oh, and I did some code formatting. Leaf check-in: 062e24b56e user: Cthulhux tags: trunk
2024-01-29
14:57
Added a release date, binaries will follow. check-in: 3b615f92bd user: Cthulhux tags: trunk, release-0.13.1
2024-01-19
15:39
Accidentally broke the changelog. Oops. check-in: e0eb5aa8e8 user: Cthulhux tags: trunk
2024-01-12
10:25
Added Mastodon contact check-in: 783ebc937c user: Cthulhux tags: trunk
2024-01-11
18:14
post-release changes for macOS project settings ;-) check-in: 8bb30e04bd user: Cthulhux tags: trunk
13:59
Updated screenshot check-in: ae0f803ae3 user: Cthulhux tags: trunk

Modified CHANGES.txt from [1b324e0183] to [f3eb69e38a].









1
2
3
4
5
6
7








Version 0.13.0
2024-01-11

[Feature] Support for hdtbl.
[Changed] Build extras and build preprocessors are now listed in a multi-select box.
[Improved] If no error has occurred, the log file will contain a success message.
[Improved] The default font looked gross on macOS. This should be better now.
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Version 0.13.1
2024-01-29

[Improved] Finding groff happens in a thread now. No more blocking on startup.
[Removed] So we got rid of the loading window again.

-------------------------------

Version 0.13.0
2024-01-11

[Feature] Support for hdtbl.
[Changed] Build extras and build preprocessors are now listed in a multi-select box.
[Improved] If no error has occurred, the log file will contain a success message.
[Improved] The default font looked gross on macOS. This should be better now.

Modified README.md from [b76a34f200] to [53e529d119].

1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
# groffstudio: An IDE for groff.

You know what was missing with `groff`? A good alternative to TeXstudio. Here we go.

## Screenshot

![Screenshot](https://i.imgur.com/GNu2M6n.png)

## Features

* Written in Lazarus (Free Pascal).
  * Should be cross-platform (but Windows support is mediocre yet).

* Can produce PS and PDF files.
* 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.












|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# groffstudio: An IDE for groff.

You know what was missing with `groff`? A good alternative to TeXstudio. Here we go.

## Screenshot

![Screenshot](https://i.imgur.com/GNu2M6n.png)

## Features

* Written in Lazarus (Free Pascal).
  * Should be cross-platform.
  * Successfully tested on Windows 10, macOS and Linux.
* Can produce PS and PDF files.
* 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.

32
33
34
35
36
37
38

39

Thank you.

## Contact

* IRC: [libera.chat: #groffstudio](irc://irc.libera.chat/groffstudio)
* Twitter: [@tux0r](https://twitter.com/tux0r)

* Matrix: @tux0r:matrix.org







>

33
34
35
36
37
38
39
40
41

Thank you.

## Contact

* IRC: [libera.chat: #groffstudio](irc://irc.libera.chat/groffstudio)
* Twitter: [@tux0r](https://twitter.com/tux0r)
* Mastodon: [@tux0r@layer8.space](https://layer8.space/@tux0r)
* Matrix: @tux0r:matrix.org

Modified src/groffstudio.lpi from [c7cb82821c] to [565cb1118a].

19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
        <Resource_0 FileName="..\LICENSE" Type="RCDATA" ResourceName="LICENSE"/>
      </Resources>
    </General>
    <VersionInfo>
      <UseVersionInfo Value="True"/>
      <AutoIncrementBuild Value="True"/>
      <MinorVersionNr Value="13"/>

      <BuildNr Value="16"/>
      <Attributes pvaPreRelease="True"/>
      <StringTable ProductName="groffstudio"/>
    </VersionInfo>
    <BuildModes>
      <Item Name="Default" Default="True"/>
    </BuildModes>
    <PublishOptions>
      <Version Value="2"/>







>
|
<







19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
        <Resource_0 FileName="..\LICENSE" Type="RCDATA" ResourceName="LICENSE"/>
      </Resources>
    </General>
    <VersionInfo>
      <UseVersionInfo Value="True"/>
      <AutoIncrementBuild Value="True"/>
      <MinorVersionNr Value="13"/>
      <RevisionNr Value="1"/>
      <BuildNr Value="17"/>

      <StringTable ProductName="groffstudio"/>
    </VersionInfo>
    <BuildModes>
      <Item Name="Default" Default="True"/>
    </BuildModes>
    <PublishOptions>
      <Version Value="2"/>
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
        <Filename Value="buildoutputwindow.pas"/>
        <IsPartOfProject Value="True"/>
        <ComponentName Value="BuildStatusWindow"/>
        <HasResources Value="True"/>
        <ResourceBaseClass Value="Form"/>
        <UnitName Value="BuildOutputWindow"/>
      </Unit>
      <Unit>
        <Filename Value="splashscreen.pas"/>
        <IsPartOfProject Value="True"/>
        <ComponentName Value="SplashscreenWindow"/>
        <HasResources Value="True"/>
        <ResourceBaseClass Value="Form"/>
        <UnitName Value="Splashscreen"/>
      </Unit>
    </Units>
  </ProjectOptions>
  <CompilerOptions>
    <Version Value="11"/>
    <PathDelim Value="\"/>
    <Target>
      <Filename Value="groffstudio"/>







<
<
<
<
<
<
<
<







75
76
77
78
79
80
81








82
83
84
85
86
87
88
        <Filename Value="buildoutputwindow.pas"/>
        <IsPartOfProject Value="True"/>
        <ComponentName Value="BuildStatusWindow"/>
        <HasResources Value="True"/>
        <ResourceBaseClass Value="Form"/>
        <UnitName Value="BuildOutputWindow"/>
      </Unit>








    </Units>
  </ProjectOptions>
  <CompilerOptions>
    <Version Value="11"/>
    <PathDelim Value="\"/>
    <Target>
      <Filename Value="groffstudio"/>

Modified src/groffstudio.lpr from [6bd99be7bf] to [85befef33a].

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  {$IFDEF HASAMIGA}
  athreads,
  {$ENDIF}
  Interfaces,
  Forms, lazcontrols, Unit1, Helpers, BuildOutputWindow, Splashscreen;

{$R *.res}

var
  Splash: TSplashscreenWindow;

begin
  RequireDerivedFormResource:=True;
  Application.Scaled:=True;
  Application.Initialize;
  
  { Load the loading screen }
  Splash := TSplashscreenWindow.Create(Application);
  Splash.Show;
  Splash.Update;
  Application.ProcessMessages;
  
  Application.CreateForm(TMainForm, MainForm);
  
  Splash.Close;
  Application.Run;
end.








|



<
<
<





<
<
<
<
<
<

|
<



21
22
23
24
25
26
27
28
29
30
31



32
33
34
35
36






37
38

39
40
41
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  {$IFDEF HASAMIGA}
  athreads,
  {$ENDIF}
  Interfaces,
  Forms, lazcontrols, Unit1, Helpers, BuildOutputWindow;

{$R *.res}




begin
  RequireDerivedFormResource:=True;
  Application.Scaled:=True;
  Application.Initialize;
  






  Application.CreateForm(TMainForm, MainForm);


  Application.Run;
end.

Deleted src/splashscreen.lfm version [1492917ff1].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
object SplashscreenWindow: TSplashscreenWindow
  Left = 493
  Height = 80
  Top = 160
  Width = 168
  BorderStyle = bsNone
  Caption = 'preparing'
  ClientHeight = 80
  ClientWidth = 168
  FormStyle = fsSplash
  object Label1: TLabel
    Left = 16
    Height = 37
    Top = 16
    Width = 141
    Caption = 'preparing ...'
    Font.Height = -27
    ParentFont = False
  end
end
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted src/splashscreen.pas version [a952d1c450].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
unit Splashscreen;

{
  The contents of this file are subject to the terms of the
  Common Development and Distribution License, Version 1.1 only
  (the "License").  You may not use this file except in compliance
  with the License.

  See the file LICENSE in this distribution for details.
  A copy of the CDDL is also available via the Internet at
  https://spdx.org/licenses/CDDL-1.1.html

  When distributing Covered Code, include this CDDL HEADER in each
  file and include the contents of the LICENSE file from this
  distribution.
}

{$mode ObjFPC}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TSplashscreenWindow }

  TSplashscreenWindow = class(TForm)
    Label1: TLabel;
  private

  public

  end;

implementation

{$R *.lfm}

end.

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































Modified src/unit1.lfm from [8f95214e34] to [2d8e8a4496].

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
object MainForm: TMainForm
  Left = 1073
  Height = 692
  Top = 99
  Width = 847
  Caption = 'groffstudio'
  ClientHeight = 692
  ClientWidth = 847
  DefaultMonitor = dmPrimary
  Position = poScreenCenter

  OnClose = FormClose
  OnCreate = FormCreate
  object MainStatusBar: TStatusBar
    Left = 0
    Height = 23
    Top = 669
    Width = 847










>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
object MainForm: TMainForm
  Left = 1073
  Height = 692
  Top = 99
  Width = 847
  Caption = 'groffstudio'
  ClientHeight = 692
  ClientWidth = 847
  DefaultMonitor = dmPrimary
  Position = poScreenCenter
  LCLVersion = '3.99.0.0'
  OnClose = FormClose
  OnCreate = FormCreate
  object MainStatusBar: TStatusBar
    Left = 0
    Height = 23
    Top = 669
    Width = 847

Modified src/unit1.pas from [5cfb67d430] to [cfe77c0b23].

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115




116
117
118

119
120
121
122

























123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
    procedure SynEdit1Change(Sender: TObject);
{$IFDEF DARWIN}
    procedure GetSocketHandler(Sender: TObject; const UseSSL: Boolean; out AHandler: TSocketHandler);
{$ENDIF}
  private
    var currentGroffFilePath: String;
    var currentGroffFileName: String;
    var hasGroff: Boolean;
    var unsavedChanges: Boolean;
{$IFDEF WINDOWS}
    var latestGroffWindowsUrl: String;
{$ENDIF}
    var storeBuildSettings: Boolean;
    var updateCheck: Boolean;
  public

  end;





var
  MainForm: TMainForm;
  BuildWindow: TBuildStatusWindow;


implementation

{$R *.lfm}


























{ TMainForm }

procedure TMainForm.FormCreate(Sender: TObject);
var
  GroffOutputVersion: String;
  OnlineVersionsFile: String;
  {$IFDEF WINDOWS}
  reGroffVersion: TRegExpr;
  {$ENDIF}
  reGroffStudioVersion: TRegExpr;
  FileVerInfo: TFileVersionInfo;
  HasVersionUpdate: Integer;
  GroffHelpers: TGroffHelpers;
  ResStream: TResourceStream;
  {$IFDEF DARWIN}
  HTTPClient: TFPHttpClient;
  {$ENDIF}
begin
  // What's the current running groff version?
  {$IFDEF WINDOWS}
  if RunCommand('cmd', ['/c', 'troff --version'], GroffOutputVersion, [], swoHIDE) then
  {$ELSE}
  if RunCommand('/bin/sh', ['-c', 'troff --version'], GroffOutputVersion, [], swoHIDE) then
  {$ENDIF}
  begin
    edtGroffInstalledVersion.Text := GroffOutputVersion;
    if pos('GNU', GroffOutputVersion) = 0 then
       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;
  end else begin
    edtGroffInstalledVersion.Text := 'n/a';
    hasGroff := False;
    lblTroffCommandNotFound.Visible := True;
  end;

  // Default file name
  currentGroffFileName := '[unsaved file]';

  // Embed the license
  ResStream:= TResourceStream.Create(HInstance, 'LICENSE', RT_RCDATA);
  try







<










>
>
>
>



>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





<














<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<







98
99
100
101
102
103
104

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164
165
166
167
168
169
170











171





172
173
174
175
176
177
178
    procedure SynEdit1Change(Sender: TObject);
{$IFDEF DARWIN}
    procedure GetSocketHandler(Sender: TObject; const UseSSL: Boolean; out AHandler: TSocketHandler);
{$ENDIF}
  private
    var currentGroffFilePath: String;
    var currentGroffFileName: String;

    var unsavedChanges: Boolean;
{$IFDEF WINDOWS}
    var latestGroffWindowsUrl: String;
{$ENDIF}
    var storeBuildSettings: Boolean;
    var updateCheck: Boolean;
  public

  end;

  TDetectGroffThread = class(TThread)
    procedure Execute; Override;
  end;

var
  MainForm: TMainForm;
  BuildWindow: TBuildStatusWindow;
  hasGroff: Boolean;

implementation

{$R *.lfm}

procedure TDetectGroffThread.Execute;
var
  GroffOutputVersion: String;
begin
  FreeOnTerminate := True;

  {$IFDEF WINDOWS}
  if RunCommand('cmd', ['/c', 'troff --version'], GroffOutputVersion, [], swoHIDE) then
  {$ELSE}
  if RunCommand('/bin/sh', ['-c', 'troff --version'], GroffOutputVersion, [], swoHIDE) then
  {$ENDIF}
  begin
    MainForm.edtGroffInstalledVersion.Text := GroffOutputVersion;
    if pos('GNU', GroffOutputVersion) = 0 then
       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;
  end else begin
    MainForm.edtGroffInstalledVersion.Text := 'n/a';
    hasGroff := False;
    MainForm.lblTroffCommandNotFound.Visible := True;
  end;
end;

{ TMainForm }

procedure TMainForm.FormCreate(Sender: TObject);
var

  OnlineVersionsFile: String;
  {$IFDEF WINDOWS}
  reGroffVersion: TRegExpr;
  {$ENDIF}
  reGroffStudioVersion: TRegExpr;
  FileVerInfo: TFileVersionInfo;
  HasVersionUpdate: Integer;
  GroffHelpers: TGroffHelpers;
  ResStream: TResourceStream;
  {$IFDEF DARWIN}
  HTTPClient: TFPHttpClient;
  {$ENDIF}
begin
  // What's the current running groff version?











  TDetectGroffThread.Create(False);






  // Default file name
  currentGroffFileName := '[unsaved file]';

  // Embed the license
  ResStream:= TResourceStream.Create(HInstance, 'LICENSE', RT_RCDATA);
  try