aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--example.t26
-rw-r--r--refs.lex98
3 files changed, 127 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..c226ef4
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,3 @@
+refs: refs.lex
+ lex refs.lex
+ cc -O2 -o refs lex.yy.c -lfl
diff --git a/example.t b/example.t
new file mode 100644
index 0000000..de0f5f5
--- /dev/null
+++ b/example.t
@@ -0,0 +1,26 @@
+.SH
+References
+.XP
+%au В. А. Богородицкий
+%al Bogorodickij
+%da 1887
+%ti Курс грамматики русского языка. Часть 1-ая: Фонетика
+%ci Варшава
+%pu Типография Михаила Земкевича
+.XP
+%au J. Baudouin de Courtenay
+%da 1972
+%ti The Difference between Phonetics and Psychophonetics
+%bo A Baudouin de Courtenay Anthology
+%ed T. A. Sebeok et al.
+%tr Edward Stankiewicz
+%ci Bloomington
+%pu Indiana University Press
+.XP
+%au M. E. Lesk
+%ti Some Applications of Inverted Indexes on the UNIX System
+%bo UNIX Programmer's Manual
+%vo 2b
+%pu Bell Laboratories
+%ci Murray Hill, NJ
+%da 1978
diff --git a/refs.lex b/refs.lex
new file mode 100644
index 0000000..714a79e
--- /dev/null
+++ b/refs.lex
@@ -0,0 +1,98 @@
+ #include <err.h>
+ #include <stdarg.h>
+
+ #define MAX 255
+ #define ED "red."
+ #define TR "Övers."
+
+ void field(char *);
+ void entry(void);
+ int pf(char *, ...);
+
+ char *name;
+
+ struct entry {
+ char au[MAX]; char al[MAX];
+ char bo[MAX]; char ci[MAX];
+ char da[MAX]; char ed[MAX];
+ char jo[MAX]; char no[MAX];
+ char pg[MAX]; char pu[MAX];
+ char se[MAX]; char ti[MAX];
+ char tr[MAX]; char vo[MAX];
+ } e;
+
+%s ENTRY
+%%
+^%.*\n field(yytext); BEGIN(ENTRY);
+<ENTRY>^[^%] entry(); ECHO; BEGIN(0);
+<ENTRY><<EOF>> entry(); yyterminate();
+%%
+
+void
+main(int argc, char *argv[0])
+{
+ name = argv[0];
+ yylex();
+}
+
+void
+field(char *t)
+{
+
+#define AS(a,b) if(strncmp(t, a, 2) == 0 && (t += 3)){ strcpy(b, t); return; }
+
+ t++;
+ t[strcspn(t, "\n")] = 0;
+
+ AS("au",e.au); AS("al",e.al);
+ AS("bo",e.bo); AS("ci",e.ci);
+ AS("da",e.da); AS("ed",e.ed);
+ AS("jo",e.jo); AS("no",e.no);
+ AS("pg",e.pg); AS("pu",e.pu);
+ AS("se",e.se); AS("ti",e.ti);
+ AS("tr",e.tr); AS("vo",e.vo);
+
+ fprintf(stderr, "%s: unrecognized field %%%.2s\n", name, t);
+ exit(1);
+}
+
+void
+entry()
+{
+ (pf("% (%).\n", e.au, e.da) || pf("%.\n", e.au));
+ (pf("%.\n\\fI%\\fP.\n", e.ti, e.bo ? e.bo : e.jo)
+ || pf("%.\n", e.ti));
+ (pf("%: %.\n", e.ci, e.pu) || pf("%.\n", e.pu));
+}
+
+int
+pf(char *fmt, ...)
+{
+ char *buf, *p;
+ int n;
+ va_list ap;
+
+ n = 0;
+ for(p = fmt; *p; p++)
+ if(*p == '%')
+ n++;
+
+ if(!(buf = malloc(strlen(fmt)+n*MAX+1)))
+ err(1, "malloc");
+
+ va_start(ap, fmt);
+ for(; *fmt; fmt++)
+ switch(*fmt){
+ case '%':
+ p = va_arg(ap, char *);
+ if(!p || !p[0])
+ return 0;
+ strcat(buf, p);
+ break;
+ default:
+ strncat(buf, fmt, 1);
+ }
+ printf("%s", buf);
+ va_end(ap);
+ return 1;
+}