diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2017-06-02 20:30:20 +1200 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2017-06-02 20:30:20 +1200 |
commit | cde3c255ff7024181a54b19e5ec1dac3ab892836 (patch) | |
tree | 8b4b8ab889bb4d28223ff510ff7e6188d1641aa5 | |
parent | Simplify some awk (diff) | |
download | dotfiles-cde3c255ff7024181a54b19e5ec1dac3ab892836.tar.gz dotfiles-cde3c255ff7024181a54b19e5ec1dac3ab892836.zip |
Add mi5(1df)
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | IDEAS.markdown | 2 | ||||
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | README.markdown | 2 | ||||
-rw-r--r-- | bin/mi5.awk | 50 | ||||
-rw-r--r-- | man/man1/mi5.1df | 63 |
6 files changed, 119 insertions, 0 deletions
@@ -46,6 +46,7 @@ bin/jfc bin/jfcd bin/jfp bin/loc +bin/mi5 bin/max bin/maybe bin/mean diff --git a/IDEAS.markdown b/IDEAS.markdown index 3b0f1c75..61f1049d 100644 --- a/IDEAS.markdown +++ b/IDEAS.markdown @@ -12,3 +12,5 @@ Ideas processes and mkfifo(1). * Write something like hcat(1df) or tcat(1df) that includes filename headings for each concatenated file. +* mi5(1df) could be made to handle comment delimiters and $1 $2 expansions + without too much pain (substr/index counting) @@ -119,6 +119,7 @@ BINS = bin/ap \ bin/jfcd \ bin/jfp \ bin/loc \ + bin/mi5 \ bin/max \ bin/maybe \ bin/mean \ diff --git a/README.markdown b/README.markdown index c35d3790..bd0b6682 100644 --- a/README.markdown +++ b/README.markdown @@ -498,6 +498,8 @@ Installed by the `install-bin` target: success, it exits with success or failure. Good for quick tests. * `mex(1df)` makes given filenames in `$PATH` executable. +* `mi5(1df)` pre-processes a crude but less painful macro expansion file + format into m4. * `mftl(1df)` finds usable-looking targets in Makefiles. * `mkcp(1df)` creates a directory and copies preceding arguments into it. * `mkmv(1df)` creates a directory and moves preceding arguments into it. diff --git a/bin/mi5.awk b/bin/mi5.awk new file mode 100644 index 00000000..c05955ff --- /dev/null +++ b/bin/mi5.awk @@ -0,0 +1,50 @@ +# Crude m4 preprocessor +BEGIN { mac = 0 } + +# Print an m4 opener as the first byte +NR == 1 { printf "`" } + +# Blocks +NF == 1 && $1 == "<%" && !mac { + mac = 1 + printf "'" + next +} +NF == 1 && $1 == "%>" && mac { + mac = 0 + printf "`" + next +} + +# If processing macros, strip leading and trailing whitespace and skip blank +# lines +mac { + sub(/^ */, "") + sub(/ *$/, "") +} +mac && !NF { next } + +# Inlines +mac { + print $0 "dnl" +} +!mac { + + # Don't let apostrophes close the comment + gsub(/'/, "''`") + + # Don't let $ signs confound expansion + gsub(/\$/, "$'`") + + # Replace m5 opener with m4 closer + gsub(/<% */, "'") + + # Replace m5 closer with m4 opener + gsub(/ *%>/, "`") + print +} + +# Print an m4 closer and newline deleter as the last bytes +END { + print "'dnl" +} diff --git a/man/man1/mi5.1df b/man/man1/mi5.1df new file mode 100644 index 00000000..dd215d0c --- /dev/null +++ b/man/man1/mi5.1df @@ -0,0 +1,63 @@ +.TH MI5 1df "June 2017" "Manual page for mi5" +.SH NAME +.B mi5 +\- m4 inverted preprocessor +.SH SYNOPSIS +.B mi5 +FILE > out.m4 +.br +.B mi5 +FILE1 FILE2 > out.m4 +.br +prog | +.B mi5 > out.m4 +.br +.SH DESCRIPTION +.B mi5 +is a simple and crude m4 preprocessor to make using m4 slightly more bearable +and predictable for its author, who wants badly to like m4 but doesn't. It's +primarily intended for situations where the majority of a file is simple static +text, and only a few simple macros need to be defined and expanded, which +covers almost every usage case for the author. It's written to work with any +POSIX m4. +.P +mi5 inverts m4's usual approach by approaching most of the file as if it were +part of an m4 comment, with <% and %> as the delimiters to specify markers in +which macro expansion should occur. This makes m4 work in a way reminiscent of +templating libraries or languages like PHP. +.P +Macros can be expanded as blocks: +.P + <% + define(`FOO', `bar') + define(`BAZ', include(`include/quux.inc') + ?> +.P +For this format, "dnl" macros to delete newlines for each declaration are +inserted for you. Blank lines are skipped, and leading and trailing spaces are +ignored. The above code therefore produces no actual output, as it only has two +define calls. +.P +For inline expansion, the syntax is similar, but the behaviour slightly different: +.P + The value of the FOO macro is <% FOO %>. +.P +Spaces immediately after the opening delimiter and before the closing delimiter +are ignored, but spaces produced within the macro are preserved. +.P +Ideally, you do macro definition in an mi5 block at the top of your file, and +very simple macro expansion in an mi5 inline. +.SH CAVEATS +Only very simple macro expansions work in inline calls at the moment. This can +be fixed by the author tokenizing the line properly, which he'll do Real Soon +Now (TM). Specifically, neither comment delimiters nor macro parameters work. +The latter is because of a nasty corner-case in m4 where parameter expansions +$1, $2, $*, etc are expanded +.B even within comments, +one of m4's darkest corners. The workaround is to do as much logic as you can +in a block, defining your result as a single simple macros, and then expanding +that inline. +.SH SEE ALSO +bp(1df), xargs(1) +.SH AUTHOR +Tom Ryder <tom@sanctum.geek.nz> |