I have PDF now!

well, kinda. I still need to fix few problems, but you can export to pdf, so that's nice.

At first, I thught that I would be able to just generate pdf out of nowhere. Yes, PDF is just a stack-based DSL (Domain Specific Language) that can be just interpreted from a plain text file. No, it does not seem to be intended for people to use it that way... Or to be used at all for that matter.

problems with PDF

First of all, there isn't that much documentation and most search results are related to manipulating already made PDF with adobe acrobat or something. I did however manage to find some documentation and in modern times, when in doubt, you can always reach out to some AI. It's wrong only third of the time! (or all the time if you bring some more niche language)

Second, fonts. Not only is the font loading very primitive (if you want bold text, you use it as a seperate font), I did not manage to make it support UTF-8 characters. I would like to write something for school in it and my language requires some non-ASCII characters, so that is a dealbreaker. Also no block art, and that's just sad.

Third, missing features. As someone who had only formatted text with a word processor or ANSI escape sequences, I was surprised that you can only set text foreground color and to change background color, you have to calculate text position (pdf does not count it for you) and draw a rectangle. I thought it was a standard feature since forever. You know your typesetter is trash when even dumb terminals can do better that you.

Last but not least: the complexity. So, you use a bunch of object for everything that refer to each other by number. That would not be that much of a problem, but you are expected to give a table with byte offsets of all of them‽ Also there might be more ugly stuff to do, since my PDF viewer constantly warned me about some errors.

Let's just say that I don't like PDF.

lesser evil

After deciding to ditch PDF, I looked for some alternatives that could be exported to PDF. Yes, that means external dependencies, but I kinda don't care at this point. I setteled on LaTeX. In case you don't know, LaTeX is a bunch of macros on top of the TeX typesetter. It's what most typesetter fans use today.

It still has some stuff I don't like about it tho. First thing to note is that it's made for traditional proportional fonts and not simulating terminal output like I want. Second, I only ever made one LaTeX document few years ago and I don't remember anything about it, so I guess that also doesn't help.

While there aren't any built-in background color settings, there is a package for that. It took some messing around to make it do what I want, it works now. I need to replace dashes with escaped ones or LaTeX would replase them with fewer unicode ones.

Also LaTeX formats stuff by encosing instructions in blocks deliminated by '{' and '}'. I personally prefer escape sequences where you instead have instructions to change one aspect on and off without any closing to keep track of. In most cases I could just open instructions inside instructions and they wolud overwrite, but when doing bold/italic, there was no instruction to use normal text, so I had to close everything and reopen what I needed.

fonts

At first I wanted to have at least one font embedded into the program, but crystal refused to compile with a binary blob inside for some reason, so I'll just copy one somewhere safe and access it from here. At first I wanted to use Fira Mono but it has no italic form. Then I tried Anonymous Pro but it doesn't support unicode blocks, and as I already stated, that's just sad. In the end I think I will use Hack as I didn't found any problems with it yet.

But the problems don't end there: FONT FILES! (yey)

First of all, linux has at least three possible font directories:

Each has font-specific folders of various naming schemes that has the fonts in them. One font is split into multiple files for different styles like so:

Some fonts however drop the '-Regular' part and 'Italic' is sometimes refered to as 'Oblique'.

The more I work on this stuff, the more I wish that GUI was never invented... Where is the sense for minimalism?

implementation

So I should probably also talk about what I've actually done.

First I make a directory in /tmp/. There I create a .tex file. I generate text like I would normally and then give it to a convertor. There I call this function to escape what needs to be escaped

def txt2latex(line : String, nobreak = false)
   unless nobreak
      line = line.gsub ' ', '\t' 
   else
      line = line.sub ' ', '\t' 
   end
   line = line.gsub '\', "\textbackslash "
   line = line.gsub '^', "\textasciicircum "
   line = line.gsub '$', "\$"
   line = line.gsub '%', "\%"
   line = line.gsub '&', "\&"
   line = line.gsub '{', "\{"
   line = line.gsub '}', "\}"
   line = line.gsub '_', "\_"
   line = line.gsub '~', "\textasciitilde "
   line = line.gsub '#', "\#"
   line = line.gsub '\t', '~'
   line = line.gsub '-', "\textendash "
   esc2latex line
end

The 'nobreak' is for footnotes and I replace spaces with tildes (nobreak space) so that they can repeat. Normally, LaTeX writes only one space at a time.

Then I replace all the escape sequences with LaTeX instructions as already stated. I need to put '\strut' in colorboxes so they take full width. Latex has built-in footnote support, so that's nice.

Now it's ready to be put at the end of a .tex document with a bunch of config. I also find required font and replace all missing variants with it's 'Regular' form.

Then I just call 'xelatex' and it's done!

I would talk more about the config, if I actually knew what I'm doing, but it's mostly just stack overflow and chatGPT sticked together, edited to fit my needs.

I also tried to calculate the fontsize to fit the paper based on the knowladge that monospaced fonts have width half their height, but I apparently don't understand something and it just wont work. I guess something to fix later.

Oh yea, I also made it possible to generate the PDF in both dark and light variants.

What's next: