#!/usr/bin/awk -f # # A literate program in text/gemini document format to program converter. # text/gemini specification can be found at: # # gemini://gemini.circumlunar.space/docs/specification.html # https://gemini.circumlunar.space/docs/specification.html # # Call like: # # gmitangle file.gmi > program # # e.g. # # gmitangle file.gmi > program # # You can also call passing in the language identifier to tangle into the program, this will default # to "AWK" if not passed in: # # gmitangle -v LANG={program type to tangle/weave} file.gmi > program # # e.g. # # gmitangle -v LANG=SQL file.gmi > file.sql # BEGIN { true = "true" false = "false" preformat_toggle = false tangle = false macro = "" literate = false PROGRAM_COUNTER = 0 MACRO_COUNTER = 0 delete PROGRAM delete MACROS if (LANG == "") { LANG = "AWK" } } function trim(string) { sub(/^[ \t]+/,"",string) sub(/[ \t]+$/,"",string) return string } # Preformatting toggle line start /^```/ && preformat_toggle == false { preformat_toggle = true # Check if this section should be output as code i.e. see if it has specified the # language identifier the program is tangling # Check if this section should be captured as the program structure i.e. see if it # has the "litgmi" language identifier sub(/^```[ \t]*/, "") sub(/[ \t]+$/,"") split($0,identifier,":") language = trim(identifier[1]) macro = trim(identifier[2]) if (language == LANG) { tangle = true } else if (language == "litgmi") { literate = true } next } # Preformatting toggle line end /^```/ && preformat_toggle == true { preformat_toggle = false literate = false # Record the number of lines that the macro contains so that it is easy to # print it out later if (tangle == true) { MACROS[macro,"size"] = MACRO_COUNTER } macro = "" tangle = false MACRO_COUNTER = 0 next } # Macro lines preformat_toggle == true && tangle == true { MACROS[macro,++MACRO_COUNTER] = $0 } # Literate lines preformat_toggle == true && literate == true { PROGRAM[++PROGRAM_COUNTER] = trim($0) } END { for (i = 1; i <= PROGRAM_COUNTER; i++) { macro = PROGRAM[i] size = MACROS[macro,"size"] for (j = 1; j <= size; j++) { print MACROS[macro,j] } print "" } }