From a65336ea79935dfbf3006e775dd16a15f5ef1bd8 Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Wed, 4 Sep 2024 12:25:04 +0200 Subject: Support LaTeX output --- src/main.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++-------- src/parser.y | 6 +++- src/pinocchio.h | 3 +- 3 files changed, 81 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index fd2fbcc..678f4eb 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,8 @@ #include #include +#include #include +#include #include #include #include @@ -22,6 +24,7 @@ static int rv; static bool interactive, utf8; +bool lflag; const char *current_file; static bool eqnsolve(eqn_t *, uint64_t, uint64_t); @@ -44,28 +47,48 @@ popcnt(uint64_t n) int main(int argc, char **argv) { + argv[0] = basename(argv[0]); setlocale(LC_ALL, ""); utf8 = strcmp(nl_langinfo(CODESET), "UTF-8") == 0; interactive = isatty(STDIN_FILENO); - if (argc == 1) { + int opt; + static struct option longopts[] = { + {"latex", no_argument, 0, 'l'}, + {0}, + }; + + while ((opt = getopt_long(argc, argv, "l", longopts, NULL)) != -1) { + switch (opt) { + case 'l': + lflag = true; + break; + default: + fprintf(stderr, "Usage: %s [-l] [file ...]\n", argv[0]); + exit(EXIT_FAILURE); + } + } + + argc -= optind; + argv += optind; + + if (argc == 0) { current_file = "-"; for (;;) { - int ret = yyparse(); - if (ret == 0) + if (yyparse() == 0) break; rv = EXIT_FAILURE; } - } else for (int i = 1; i < argc; i++) { + } else for (int i = 0; i < argc; i++) { if (strcmp(argv[i], "-") == 0) yyin = stdin; else if ((yyin = fopen(argv[i], "r")) == NULL) { - warn("fopen: %s", argv[1]); + warn("fopen: %s", argv[i]); rv = EXIT_FAILURE; continue; } - current_file = argv[1]; + current_file = argv[i]; yyparse(); fclose(yyin); } @@ -74,11 +97,8 @@ main(int argc, char **argv) } void -astprocess(ast_t a) +astprocess_cli(ast_t a) { - if (a.eqn == NULL) - return; - enum { TBLVBAR, TBLHBAR, @@ -127,6 +147,38 @@ astprocess(ast_t a) eqnfree(a.eqn); } +void +astprocess_latex(ast_t a) +{ + fputs("\\begin{displaymath}\n\t\\begin{array}{|", stdout); + int varcnt = popcnt(a.vars); + for (int i = 0; i < varcnt; i++) { + if (i == 0) + putchar('c'); + else + fputs(" c", stdout); + } + fputs("|c|}\n\t\t", stdout); + + for (int i = 0; i < MAXVARS; i++) { + if ((a.vars & UINT64_C(1)< 0;) + printf("%d & ", (bool)(msk & UINT64_C(1)<", 2}, [EQUIV - NOT] = {"<=>", 3}, }; + static const sym_t symbols_latex[] = { + [NOT - NOT] = {"\\lnot ", -1}, + [OR - NOT] = {"\\lor", -1}, + [AND - NOT] = {"\\land", -1}, + [XOR - NOT] = {"\\oplus", -1}, + [IMPL - NOT] = {"\\implies", -1}, + [EQUIV - NOT] = {"\\iff", -1}, + }; - const sym_t *symtab = utf8 ? symbols_utf8 : symbols_ascii; + const sym_t *symtab + = lflag ? symbols_latex + : utf8 ? symbols_utf8 + : symbols_ascii; switch (a->type) { case IDENT: diff --git a/src/parser.y b/src/parser.y index 5a4c409..d7e8168 100644 --- a/src/parser.y +++ b/src/parser.y @@ -11,6 +11,7 @@ static ast_t astmerge(int, ast_t, ast_t); static void *xmalloc(size_t); static void yyerror(const char *); +extern bool lflag; extern const char *current_file; %} @@ -44,7 +45,10 @@ extern const char *current_file; input : %empty - | input line { astprocess($2); } + | input line { + if ($2.eqn != NULL) + (lflag ? astprocess_latex : astprocess_cli)($2); + } ; line diff --git a/src/pinocchio.h b/src/pinocchio.h index fb74f3c..51e4dd5 100644 --- a/src/pinocchio.h +++ b/src/pinocchio.h @@ -19,7 +19,8 @@ typedef struct { uint64_t vars; } ast_t; -void astprocess(ast_t); +void astprocess_cli(ast_t); +void astprocess_latex(ast_t); void user_error(const char *, ...) #if __GNUC__ __attribute__((format(printf, 1, 2))) -- cgit v1.2.3