💾 Archived View for stack.tilde.cafe › code › gemlit › gemlit.c captured on 2024-05-26 at 15:01:54.

View Raw

More Information

⬅️ Previous capture (2023-09-08)

-=-=-=-=-=-=-

/***********************************************************************
                 (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;
  }
  char* comment = (argc==3 ? argv[2] : "//");
  int comment_len = (strlen(comment));
  int code = 0;
  for(;fgets(buf,BUFSIZE,f);) {
    if(!code) {                       // gemtext mode?
      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?
      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;
}