rogram GeminiToHtml;
initial-scale=1">

{ gmi-html - A Gemtext to HTML converter.
This program is written in Pascal and
has been tested with FreePascal on Linux. }

uses
SysUtils, Character;

var
StyleString : String = '../style.css'; { Our CSS path }
PageTitle : String; { The title of the page }
MyString : String; { The current line }
OutFileName : String; { Name of the output file }
OutFile, InFile : Text; { The two important files}
Params : Integer; { Number of parameters given }
Version : String = '0.5'; { The version of gmi-html }

{ A function to remove the extension of a file.
hello.txt becomes 'hello'.
This will be handy for turning 'foo.gmi' into 'foo.html' }
function RemoveExtension (s : String): String;
var DotLocation : Integer;
begin
DotLocation := LastDelimiter ('.', s) - 1;
RemoveExtension := LeftStr (s, DotLocation);
end;

{ Remove the first N characters of string S. }
function LeftCut (s : String; n : Integer): String;
begin
LeftCut := Trim (RightStr (s, Length (s) - n));
end;

{ The same function, but without trimming }
function LeftCutNoTrim (s : String; n : Integer): String;
begin
LeftCutNoTrim := RightStr (s, Length (s) - n);
end;

{ Parse a header element }
Function GemHeader (s : String): String;
begin
if LeftStr(s, 3) = '###' then
GemHeader := '

' + LeftCut (s, 3) + '

'
else if LeftStr(s, 2) = '##' then
GemHeader := '

' + LeftCut (s, 2) + '

'
else if LeftStr(s, 1) = '#' then
GemHeader := '

' + LeftCut (s, 1) + '

'
end;

Procedure GemLink (s : String);
var C : String;
begin
C := 'A';
S := LeftCut (s, 2);
Write (OutFile, '');
WriteLn (s);
Write(OutFile, s);
WriteLn (OutFile, '

');
end;

{ Parse a blockquote }
Procedure GemQuote (s : String);
begin
s := LeftCut (s, 1);
WriteLn (OutFile, '

' + s + '
');
end;

{ Parse a list element }
Procedure GemList (s : String);
begin
WriteLn(OutFile, '

    ');
    repeat
    s := LeftCut (s, 1);
    WriteLn (OutFile, '
  • ' + s + '
  • ');
    ReadLn(InFile, s);
    until LeftStr(s, 1) <> '*';
    WriteLn (OutFile, '
');
end;

{ Parse a preformatted block }
Procedure GemPre (s : String);
begin
ReadLn (InFile, S);
WriteLn (OutFile, '

');
Writeln (OutFile, s);
While s <> '```' do begin
ReadLn (InFile, s);
{ There will be a trailing ``` if this isn't done: }
if LeftStr (s, 3) <> '```' then
WriteLn(OutFile, s);
end;
ReadLn(InFile, s);
WriteLn(OutFile, '
');
end;

{ One little thing about Paragraphs...
Most people use TWO newlines to denote a new paragraph entirely.
That's fine, that's good! But I've decided that, if there's only
*one* newline, to treat that as a
rather than a whole new

.
I'm only doing this because I'm using this converter for poetry.}
Procedure GemParagraph (s : String);
begin
{ ReadLn (InFile, S);}
WriteLn (OutFile, '

');
{ Writeln (OutFile, s); }
Repeat

{ There will be a trailing ``` if this isn't done: }
if s <> '' then begin
WriteLn(OutFile, s + '
');
end;
ReadLn (InFile, s);
Until s = '';
end;

begin { Main }
{We want to work on multiple files (possibly), so we will repeat this
for every file given.}
if ParamCount > 0 then
begin
for Params := 1 to ParamCount do
begin { For Loop }
OutFileName := RemoveExtension (ParamStr(Params)) + '.html';
Assign (InFile, ParamStr(Params));
Reset (InFile);
Assign (OutFile, OutFileName);
Rewrite (OutFile);

{ Put the first line into a title }
ReadLn (InFile, MyString);
PageTitle := LeftCut (MyString, 1);

Write (OutFile,
'' + LineEnding
+ '' + LineEnding
+ LineEnding
+ '' + LineEnding
+ ' ' + PageTitle + '' + LineEnding
+ ' ' + LineEnding);
Write (OutFile, ' + ' content="A Gemini Page">' + LineEnding
+ ' ' + LineEnding
+ ' + ' content="width=device-width,' + LineEnding);
Write (OutFile,
' initial-scale=1">' + LineEnding
+ ' '
+ LineEnding
+ '' + LineEnding
+ LineEnding
+ '' + LineEnding
+ '

');

{ And also write the title out}
WriteLn (OutFile, (GemHeader (MyString)));

Repeat
ReadLn (InFile, MyString);

if LeftStr (MyString, 1) = '*' then
GemList (MyString)
else if LeftStr (MyString, 1) = '#' then
WriteLn (OutFile, GemHeader (MyString))
else if LeftStr (MyString, 2) = '=>' then
GemLink (MyString)
else if LeftStr (MyString, 1) = '>' then
GemQuote(MyString)
else if LeftStr (MyString, 3) = '```' then
GemPre(MyString)
else if LeftStr (MyString, 1) <> '' then
{ WriteLn(OutFile, '

'+ MyString + '

')}
GemParagraph (MyString)
else
write ('');

Until Eof (InFile);

WriteLn(OutFile, '

');
Close (InFile);
Close (OutFile);
end; { For Loop }
End
else
Begin
Write ('gmi-html ' + Version + LineEnding
+ 'gmi-html requires filenames as arguments!' + LineEnding
+ 'Examples:' + LineEnding
+ 'gmi-html file.gmi' + LineEnding
+ 'gmi-html foo.gmi bar.gmi baz.gmi' + LineEnding);
end;
End.