💾 Archived View for stack.tilde.cafe › code › gemlit › gemlit.gmi captured on 2023-09-08 at 16:26:58. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
(c) Copyright 2021 StackSmith All Rights Reserverd
Distributed under BSD 3-clause license (attached below)
gemlit supports literate programming using gemtext (and markdown), by
commenting away non-code segments of a source file. The comment string is
specified as an optional second parameter, and defaults to // (for C and C++)
The file may contain arbitrary gemtext, mixed with code which must be enclosed
into one or more pre-format blocks bound by lines starting with ```. Such
files may be transmitted and viewed by any gemini browser, and compiled after
commenting non-code text with this utility.
gcc gemlit.c -o gemlit
Usage
gemlit <file> (<comment-marker>)
The processed file is output to stdout for piping into the compiler.
The logistics of using gemlit depend on your preferences. You may wish to
convert an entire directory of files, renaming them from .c gmi to .c. Another
approach is to create a makefile that processes each file, piping it to the
compiler.
========================================================
#include <stdio.h> #include <stdlib.h> #include <string.h> #define BUFSIZE 1024 int main(int argc, char** argv) { if ((argc < 2) || (argc > 3)) { printf("Usage: gemlit <filename> (<comment-marker>)\n"); printf("Converts a literal gemtext file to a compilable form\n"); return EXIT_FAILURE; } FILE* f; char buf[BUFSIZE]; if(!(f = fopen(argv[1],"r"))) { fprintf(stderr,"Could not read file %s\n",argv[1]); return EXIT_FAILURE; }
We default to C/C++ line comment style using //
char* comment = (argc==3 ? argv[2] : "//"); int comment_len = (strlen(comment)); int code = 0;
Process the gemfile one line at a time
for(;fgets(buf,BUFSIZE,f);) { if(!code) { // gemtext mode?
We are in gemtext mode. Each line must be commented, and we shall check for the terminator.
fprintf(stdout,"%s ",comment); // start with a comment fprintf(stdout,"%s",buf); // then, text if(!strncmp("```",buf,3)) // if ```, flip state code = ~code; } else { // code mode?
We are in code mode. But watch out for the terminating ```, as it must be commented-out!
if(!strncmp("```",buf,3)) { // first check for terminating ``` code = ~code; // switch to gemtext mode for later fprintf(stdout,"%s ",comment); // but comment out the ```` } fprintf(stdout,"%s",buf); // and output the linr contents } } fclose(f); return EXIT_SUCCESS; }