Settings

Theme

Using the C preprocessor as an HTML templating engine

github.com

39 points by cedric_h 2 years ago · 33 comments

Reader

defrost 2 years ago

IIRC the earliest version of the C++ language, before a C++ compiler existed, was implemented with C and the M4 preprocessor.

https://en.wikipedia.org/wiki/M4_(computer_language)

https://www.gnu.org/software/m4/

  • ninjin 2 years ago

    Thank you, I did not know this. I was about to comment and say: Why not go with m4(1)? I have used it for a personal homepage and while it certainly will try to stab you in the back like any old macro processor will, it is more full-fledged that its C counterpart and will also allow to to smugly state that your homepage is POSIX compliant [1]. There are a few guides out there from around 2000 to get you started, but at some point one needs to read the original paper [2] and let your imagination run wild.

    [1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/m...

    [2]: https://maibriz.de/unix/ultrix/etc/m4.pdf

    • kragen 2 years ago

      one of the first things i did with html was to attempt to use m4 to simplify my personal home page. not only did that not work, it backfired to an incredible degree, but that's because i was using proprietary vendor m4. gnu m4 has a couple of features that make it significantly less error-prone:

      1. built-in macro names that require arguments such as `define' are not "expanded" if you don't follow them with parentheses

      2. there's an option to require a magic sigil character to invoke macros, such as % or something; this turns out to have been required in the original gpm and its bell labs clone m6. this helps enormously with complicated macros

      however, the fact that the output of your macro is always immediately run as new code (as opposed to m6 and gpm, where this was optional on a per-call basis) makes m4 just ridiculously error-prone. i feel like trauma from debugging m4 macros was a major consideration in the design of the weak-ass c preprocessor

      • ninjin 2 years ago

        > 1. built-in macro names that require arguments such as `define' are not "expanded" if you don't follow them with parentheses

        This one is pure pain. Thankfully, the only implementation I have encountered that does this is Heirloom's [1]. I doubt POSIX will do it, but I wish they would just define this behaviour out of existence for the built-ins as it is a minefield when trying to write prose (or comments, for that matter).

        [1]: https://heirloom.sourceforge.net

        As for outputs being interpreted iteratively, there is no way around it that I know of. To make invocation more explicit, I have just settled on prefixing macros with an underscore and it has worked well so far as it is uncommon in English text, HTML, and CSS.

  • imglorp 2 years ago

    Yep, it was called cfront.

    https://en.wikipedia.org/wiki/Cfront

  • cedric_hOP 2 years ago

    woah, that's a really fun tidbit.

woodruffw 2 years ago

Seems like a bad idea, given that the CPP and HTML have a fair number of overlapping tokens (e.g. `#` for both URL fragments and macro beginnings).

Why not use SSI[1]? It's inspired by the CPP's syntax, but is supported directly by most HTTP servers (and is more powerful, to boot).

[1]: https://en.wikipedia.org/wiki/Server_Side_Includes

  • tiagod 2 years ago

    >Why not use SSI[1]?

    Because hacking is fun, and it's still fun if it's a bad idea

  • ksherlock 2 years ago

    # is only processed by cpp when it's the first non-whitespace character in a line so that shouldn't be an issue in the real world. But, yeah, SSI.

    • woodruffw 2 years ago

      True. Maybe < and > would have been better examples, although one could argue those are optional :-)

    • zzo38computer 2 years ago

      Yes, although if you use #define or C comments or several other stuff then it can potentially cause a problem due to it is not a C syntax and is not expected.

  • Alifatisk 2 years ago

    Completely forgot about SSI! What a cool feature

rkeene2 2 years ago

I do this for some very small static sites like: [0]

[0] http://rbl.oc9.org/

katzenversteher 2 years ago

Quite a long time ago I worked at a company developing games for mobile phones in J2ME. The J2ME runtime had a lot of (different) quirks issues on different phones and the phones where also quite different. We used the C preprocessor a lot to make porting the games for different models easier.

litoE 2 years ago

There's also the htp processor that handles the same problem. It has macros (equivalent to #define) file inclusion (equivalent to #include) and conditionals (equivalent to #ifxxx) but is better suited for HTML than the C preprocessor. https://sourceforge.net/projects/htp/

_benj 2 years ago

I was considering doing something like this just the other day. It had a gnuplot script and it seemed to me that it would be so much more versatile if I could use #ifdefine and #include in it.

I ended up using a Perl preprocessor, but it seems like cpp would work ok-ish for certain use cases that don’t require, say, strict tabs like Python among a few other things mentioned on the cpp manual.

  • webstrand 2 years ago

    Check out https://github.com/logological/gpp it's what I use when I feel like I need a preprocessor. It's more flexible in syntax and operation than cpp.

    I've used it in the past for wrangling the definitions of a multitude of SQL triggers I was using to generate a real-time materialized view. The fact that you can modify its syntax is very helpful for making it work with non-C syntaxes (like SQL or even LaTeX).

    It even has an HTML mode built-in, which you can customize to your needs, but looks like:

        <#define x|y>
        <#macro arg|...>
    
    which works better for certain WYSIWYG editors. You could modify the syntax to be

        <!--#define x y-->
        <!--#macro(arg, ...)-->
sour-taste 2 years ago

Why not go all out? Use -DUSERNAME=$USERNAME on the command line to pass in data? Define macros with parameters to affect rendering in complicated ways. Call cpp for every request to generate the html. Could be fun!

  • cedric_hOP 2 years ago

    I've gotten a series of deranged preprocessor hacks from friends since sharing that repo, the possibilities are ... terrifyingly limitless.

torstenvl 2 years ago

https://news.ycombinator.com/item?id=39863492

cozzyd 2 years ago

Or there's the opposite choice of using PHP as a C preprocessors. Not sure which is more frightening.

kragen 2 years ago

i've used a linux setup for wireless access points that used the unix shell as its html templating engine. (openwrt 20 years ago, maybe?) the web server would run a shell script and send its output to the browser, cgi-style

babydevkute 2 years ago

hi

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection