diff options
author | Thomas Voss <mail@thomasvoss.com> | 2023-11-14 10:03:19 +0100 |
---|---|---|
committer | Thomas Voss <mail@thomasvoss.com> | 2023-11-14 10:08:19 +0100 |
commit | 234a47f69f0957bf3e3d268749b01e112d53bb6c (patch) | |
tree | b6da59bc4d1bc9e93c0b0631042949bfd7ac02bc /src/blog/gsp/index.gsp | |
parent | 09e860d5a1e30901327aadb6bdfa0ee6afb00277 (diff) |
Move /srp to /blog
Diffstat (limited to 'src/blog/gsp/index.gsp')
-rw-r--r-- | src/blog/gsp/index.gsp | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/src/blog/gsp/index.gsp b/src/blog/gsp/index.gsp new file mode 100644 index 0000000..8c56883 --- /dev/null +++ b/src/blog/gsp/index.gsp @@ -0,0 +1,310 @@ +html lang="en" { + head { m4_include(head.gsp) } + body { + header { + div { + h1 {-Never Settle For Trash} + m4_include(nav.gsp) + } + + figure .quote { + blockquote { + p {= + đ¨đ¨ BREAKING: TYPESCRIPT SNATCHES DEFEAT FROM THE JAWS OF VICTORY + đ¨đ¨ + } + } + figcaption {-Lane Wagner} + } + } + + main { + h2 {-Table of Contents} + + ul { + li {a href="#simple" {-Simplicity and Abstraction}} + li {a href="#sucks" {-Most Software Sucks}} + li {a href="#solution" {-My Solution}} + li {a href="#syntax" {-Syntax Highlighting}} + li {a href="#takeaway" {-The Takeaway}} + } + + h2 #simple {-Simplicity and Abstraction} + p {- + I like my software simple and devoid of useless abstraction. I often + find myself in positions where Iâm searching for scissors to cut a sheet + of paper, and am instead greeted with a chainsaw. The urge to + over-complicate and -abstract your software can be strong; I often see + people who preach simple software writing programs to solve basic + problems that have 30 different command-line flags, and require a 50 + page m4_abbr(PDF) explaining its operation. + } + + p {- + Why do I mention all of this? Well as anyone whoâs ever tried their + hand at web-development knows, websites are written in m4_abbr(HTML). I + wish I could say thatâs a good thing, but as anyone whoâs ever looked at + m4_abbr(HTML) before would know, that language is â to put it lightly â + really not great. Itâs extremely verbose, and awkward to write- and + edit (angle brackets are not the easiest-to-reach keys on the keyboard). + } + + p {- + So whatâs the solution? The most obvious to me is to create a nicer to + read- and write language which I can easily transpile down to + m4_abbr(HTML). Ideally the m4_abbr(CLI) is very simple and works on the + standard input and -output like all good UNIX utilities. I should be + able to transpile my site by simply running â@code{-cmd in.xyz + out.html}â, where my input reflects the structure of my output will + nicer, less-polluting syntax such as in â@code{-div .cls { ⌠\}}â. + } + + p {- + The kind of tool I am describing here is what I imagine the ideal + solution to be. A @em{-simple} tool with a @em{-simple} function. It + takes an input language and produces an output language. There is also + minimal abstraction. The input language should reflect the structure of + m4_abbr(HTML), because thatâs exactly what weâre trying to output. It + makes little sense to create a fundamentally different language when + m4_abbr(HTML) not only does a good job at defining a websites structure, + but sticking close to the language we are targeting just makes + everyoneâs life easier in every way. + } + + h2 #sucks {-Most Software Sucks} + + p {- + So with my ideal solution being a simple language with a simple + m4_abbr(CLI) that sticks close to the structure of m4_abbr(HTML), letâs + take a look at what other people have come up with: + } + + figure { + pre {= m4_fmt_code(markdown.md.gsp) } + } + + p {- Oh no.} + + p {- + Now most readers probably had the initial reaction of â@em{-Whatâs wrong + with Markdown?}â. To answer your question: everything. The issue I + have with these highly-prevalent Markdown-based replacements for + m4_abbr(HTML) is that they ignore the fundamental fact that + m4_abbr(HTML) and Markdown are @em{-not} compatible languages with each + other. m4_abbr(HTML) is designed around making websites (with the added + autism of m4_abbr(XML)). It gives us things like semantic tags for + describing input forms, navigation bars, figures, and more. With the + addition of classes and IDs, we can even style two paragraphs on the + same page in different ways. This is fundamentally not possible in + Markdown. If we ignore the fact that Markdown is just poorly designed, + it offers us basically none of what we need to make an even + slightly-complex static page as itâs not meant for website-design but + simply to be a readable plain-text format you can use for documentation + or your email or something. + } + + p {- + How do you make your navigation bar in Markdown? Or style two + paragraphs differently? You canât. Some try to get around this by + adding extensions to the Markdown language, but they never manage to + cover all bases. Another problem I @em{-always} come across when trying + to use Markdown-to-m4_abbr(HTML) tools is code blocks. I always make + sure to use tabs for indentation in my code blocks instead of spaces, so + that I can vary the tab-width based on the screen size of the reader. + You obviously canât do this with spaces since the fundamental (and + retarded) purpose of space-indentation is to force everyone to view code + with the same indentation, which sucks for users on mobile when you have + nice large indents. To this day I have yet to find a + Markdown-to-m4_abbr(HTML) converter that will let me have tab indents + without error-prone post-processing of the generated m4_abbr(HTML). + } + + p {- + Ok well⌠there are other ways of generating m4_abbr(HTML); one rather + popular option is Pug: + } + + figure { + pre .pug {= m4_fmt_code(pug.pug.gsp) } + } + + p {- + While Pug certainly hits the âmaintain the same structureâ point right + on the head, it fails in one very crucial area â itâs a JavaScript + library @em{-only}, and so requires a whole m4_abbr(JS) setup simply to + transpile your site to m4_abbr(HTML). What a bummer. There is also a + second issue which is that it uses an indentation-sensitive syntax. + Normally I am actually a fan of languages like this â such as Python â + but in the case of a markup language like Pug, this is terrible as it + makes macros and templating with tools such as @code{-m4} exceptionally + difficult. Pug @em{-does} offer templating faculties via JavaScript, + but I really try to minimize the amount of JavaScript I need to write + whenever possible. + } + + h2 #solution {-My Solution} + + p {- + So with no existing tools fitting my entry criteria, I did the only + reasonable next thing and made my own tool. It tries to stick to the + format of m4_abbr(HTML) as closely as possible while offering an + @em{-extremely} easy-to-use transpiler. It also has no added bullshit + like filters, templates, etc. If you want macros, use a macro-processor + like @code{-m4}. I called it m4_abbr(GSP) because everyone knows that + German Shorthaired Pointers are better than pugs. Here is a quick + syntax example: + } + + figure { + pre .gsp {= m4_fmt_code(example.gsp.gsp) } + } + + p {- + Here you can see almost all of m4_abbr(GSP). The document follows the + same structure as m4_abbr(HTML), but thanks to the use of braces instead + of opening- and closing tags, the syntax is far less verbose and easier + to read. The language also provides shorthands for classes and IDs + through m4_abbr(CSS)-selector syntax. + } + + p {- + Templating and macros are also very easy via macro processors thanks to + the use of braces instead of whitespace-based scoping. You may have + noticed that I like to make use of abbreviations on this website that + expand when hovered over (unless youâre on mobile, in which case you + might not see them). I do this via the m4_abbr(HTML) @code{-<abbr>} + tag, providing the appropriate class. For example, many times on this + very page Iâve made use of @code{-\@abbr .html {-HTML\}}. Obviously + repeating that everywhere in my document can be quite annoying, so Iâve + gotten around this by making use of the following @code{-m4} macro: + } + + figure { + pre {= m4_fmt_code(abbr.m4.gsp) } + } + + p {- + I can then insert abbreviations by simply writing something along the + lines of â@code{-â¨m4_abbr(HTML)âŠ}â in my document. + } + + aside { + p {- + The first thing I did after finishing the transpiler was to rewrite + this entire site in m4_abbr(GSP). There is something that just feels + so great about writing a tool that you actually use in your day-to-day + life. + } + } + + p {- + The transpiler itself is also incredibly easy to use, something + JavaScript developers would never be able to comprehend. In order to + transpile a m4_abbr(GSP) document into an m4_abbr(HTML) document, I + simply run â@code{-gsp index.gsp >index.html}â. Yep, thatâs it. + } + + h2 #syntax {-Syntax Highlighting} + + p {- + One problem that I came across writing m4_abbr(GSP) was the lack of + syntax highlighting. It can seem not so important, but syntax + highlighting is crucial for helping you quickly identify different + syntax elements. The awesome solution I found for this ended being + Tree-Sitter. Tree-Sitter is a parser-generator that various text + editors such as Vim and Emacs can integrate with to offer efficient- and + high quality syntax highlighting, amongst other features such as + syntax-aware code folding and movement. + } + + p {- + After a bit of research and reading the documentation, I found that + creating your own parsers is actually really easy. You effectively just + define a JavaScript object that describes the language grammar, and a C + parser is generated from that. If youâre interested, you can find the + m4_abbr(GSP) parser @a href="https://git.sr.ht/~mango/tree-sitter-gsp" + {-here}. To give you a bit of an idea of just how simple a Tree-Sitter + parser is, hereâs a simplified example of how you describe the + definition of a node, and a node name @x-ref{-1}: + } + + figure { + pre .js {= m4_fmt_code(grammar.js.gsp) } + } + + aside { + p data-ref="1" {- + The definition for what constitutes a node name is simplified in the + example. In actuality node names can contain all sorts of unicode + characters too (because m4_abbr(XML) said so), but I would like the + regex to actually fit on the screen. + } + } + + p {- + As you can see, the grammar syntax is extremely simple. You simply + define your core syntax elements via regular expressions, and then + compose them together via helper functions such as @code{-optional} and + @code{-repeat} to define the full structure of your language. + } + + p {- + This isnât enough though. We now have a parser for our language that + can create a syntax tree that our editor can take advantage of, but our + editor still doesnât know what each node actually @em{-is} so that it + can be syntax highlighted properly. Tree Sitter solves this through a + query file written in Scheme where we can describe how to syntax + highlight our m4_abbr(AST). This is what the configuration for + m4_abbr(GSP) looks like: + } + + figure { + figcaption { + code {-queries/highlights.scm} + } + pre {= m4_fmt_code(highlights.scm.gsp) } + } + + p {- + As you can see, this is all really simple stuff, which is what I love so + much about Tree Sitter â itâs just so easy! With these basic + annotations your editor knows that attribute values should be + highlighted like strings, braces like tag delimiters, etc. In a similar + vein, writing a query to describe code-folding is really easy: + } + + figure { + figcaption { + code {-queries/folds.scm} + } + pre {= m4_fmt_code(folds.scm.gsp) } + } + + h2 #takeaway {-The Takeaway} + + p {- + So whatâs the takeaway? I think itâs that when you have a problem, + often times the best solution is not to fundamentally redesign something + from the ground up, or to completely change the way a system works, but + to instead identify the specific thing that annoys you and find a fix + for it. I thought that the syntax of m4_abbr(HTML) was annoying and + bad, so I found a solution for the syntax, while keeping the core + structure the same. In the same line of thinking, try not to + over-abstract â Iâm looking at you, Java developers. Abstraction often + leads to exponentially increased complications the moment we want to do + anything different or out of the ordinary, so unless you can find a + really nice abstraction that doesnât really make anyoneâs life harder, + try to avoid them when you can. + } + + p {- + If youâre interested in m4_abbr(GSP), you can find the git repository + over at @a href="https://git.sr.ht/~mango/gsp" {-Sourcehut}. + } + } + + hr{} + + footer { m4_footer } + } +} |