From a10779058f72fb1c6187e9cd6c297c5e24c686d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Tue, 20 Jul 2021 15:13:12 +0200 Subject: Add %lg (language) field for reference-specific language --- example.t | 1 + fref.1 | 4 ++ fref.lex | 179 +++++++++++++++++++++++++++++++++++++++----------------------- 3 files changed, 118 insertions(+), 66 deletions(-) diff --git a/example.t b/example.t index 9c77766..4b45204 100644 --- a/example.t +++ b/example.t @@ -13,6 +13,7 @@ References %pu Indiana University Press %xx Extra information .XP +%lg ru %la Bogorodickij (1887) %au Богородицкий, В. А. %da 1887 diff --git a/fref.1 b/fref.1 index 74e6c53..793e1ab 100644 --- a/fref.1 +++ b/fref.1 @@ -36,6 +36,8 @@ The following values are supported: .Bl -tag -width xx -offset indent .It Em en English (default) +.It Em ru +Russian .It Em sv Swedish .El @@ -71,6 +73,8 @@ Hypertext reference Journal .It Sy %la Label +.It Sy %lg +Reference-specific language .It Sy %no TODO: Issue number .It Sy %pp diff --git a/fref.lex b/fref.lex index dee3658..9f58b69 100644 --- a/fref.lex +++ b/fref.lex @@ -16,48 +16,43 @@ #define MAX 255 /* Max field length. */ - #define DO_FIELDS \ - DO("ad",ad,e.ad) /* Access date. */ \ - DO("bo",bo,e.bo) /* Book. */ \ - DO("ci",ci,e.ci) /* City. */ \ - DO("da",da,e.da) /* Date (year). */ \ - DO("ed",ed,e.ed) /* Editor. */ \ - DO("hr",hr,e.hr) /* Hypertext reference. */ \ - DO("jo",jo,e.jo) /* Journal. */ \ - DO("la",la,e.la) /* Label. */ \ - DO("no",no,e.no) /* TODO: Issue number. */ \ - DO("pp",pp,e.pp) /* Pages. */ \ - DO("pu",pu,e.pu) /* Publisher. */ \ - DO("se",se,e.se) /* TODO: Series. */ \ - DO("ti",ti,e.ti) /* Title. */ \ - DO("tr",tr,e.tr) /* Translator. */ \ - DO("vo",vo,e.vo) /* Volume. */ \ - DO("xx",xx,e.xx) /* Extra information. */ \ + #define FOR_FIELDS \ + DO("ad",ad,e.ad) /* Access date. */ \ + DO("bo",bo,e.bo) /* Book. */ \ + DO("ci",ci,e.ci) /* City. */ \ + DO("da",da,e.da) /* Date (year). */ \ + DO("ed",ed,e.ed) /* Editor. */ \ + DO("hr",hr,e.hr) /* Hypertext reference. */ \ + DO("jo",jo,e.jo) /* Journal. */ \ + DO("la",la,e.la) /* Label. */ \ + DO("lg",lg,e.lg) /* Reference-specific language. */ \ + DO("no",no,e.no) /* TODO: Issue number. */ \ + DO("pp",pp,e.pp) /* Pages. */ \ + DO("pu",pu,e.pu) /* Publisher. */ \ + DO("se",se,e.se) /* TODO: Series. */ \ + DO("ti",ti,e.ti) /* Title. */ \ + DO("tr",tr,e.tr) /* Translator. */ \ + DO("vo",vo,e.vo) /* Volume. */ \ + DO("xx",xx,e.xx) /* Extra information. */ \ /* END */ - void field(char *); void entry(void); + void field(char *); void harvard(void); + struct trans *gettrans(char *); int pf(char *, ...); - extern char *optarg; - extern int optind; - - char *name; - int line; /* Line at which entry begins. */ - int lines = 0; /* Total number of lines. */ - /* Fields of current entry. */ struct entry { - #define DO(s,n,m) char n[MAX]; - DO_FIELDS - #undef DO int a; /* Number of authors. */ char au[MAX][MAX]; /* Authors. */ + #define DO(s,n,m) char n[MAX]; + FOR_FIELDS + #undef DO } e; /* Translation strings. */ - struct translations { + struct trans { char *and; char *avail; char *ed; @@ -65,7 +60,18 @@ char *pp; char *tr; char *vo; - } t; + }; + + extern char *optarg; + extern int optind; + + char *name; /* Program name. */ + char *lang = NULL; /* Main language (-l). */ + int line; /* Line at which entry begins. */ + int lines = 0; /* Total number of lines. */ + struct trans *len = NULL; /* English strings. */ + struct trans *lru = NULL; /* Russian strings. */ + struct trans *lsv = NULL; /* Swedish strings. */ %% \n lines++; ECHO; @@ -78,7 +84,6 @@ void main(int argc, char *argv[]) { - char *lang; int c; /* Save program name. */ @@ -99,24 +104,9 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - /* Set translation strings according to -l. */ - if(strncmp(lang, "sv", 2) == 0){ - t.and = strdup("och"); - t.avail = strdup("Tillgänglig: "); - t.ed = strdup("red. "); - t.p = strdup("s. "); - t.pp = strdup("ss. "); - t.tr = strdup("Övers. "); - t.vo = strdup("vol. "); - }else{ - t.and = strdup("and"); - t.avail = strdup("Available: "); - t.ed = strdup("ed. "); - t.p = strdup("p. "); - t.pp = strdup("pp. "); - t.tr = strdup("Trans. "); - t.vo = strdup("vol. "); - } + if(!lang) + lang = strdup("en"); + gettrans(lang); /* Clear entry struct. */ memset(&e, 0, sizeof(e)); @@ -132,11 +122,13 @@ field(char *s) s[strcspn(s, "\n")] = 0; /* Fill corresponding field. */ -#define AS(a,b) if(strncmp(s, a, 2) == 0 && (s += 3)){ strcpy(b, s); return; } + #define AS(a,b) \ + if(strncmp(s, a, 2) == 0 && (s += 3)){ strcpy(b, s); return; } + AS("au",e.au[e.a++]); -#define DO(s,n,m) AS(s,m) - DO_FIELDS -#undef DO + #define DO(s,n,m) AS(s,m) + FOR_FIELDS + #undef DO /* * As no field matched, an error is printed and the program exits @@ -162,8 +154,13 @@ entry() void harvard() { + struct trans *t; int i; + /* Get translation strings. */ + t = gettrans(*e.lg ? e.lg : lang); + *e.lg = 0; + /* Print label. */ pf("% = ", e.la); @@ -171,7 +168,7 @@ harvard() for(i = 0; i < e.a-2; i++) printf("%s, ", e.au[i]); if(i == e.a-2) - printf("%s %s ", e.au[i++], t.and); + printf("%s %s ", e.au[i++], t->and); if(i == e.a-1) printf("%s", e.au[i]); @@ -182,16 +179,16 @@ harvard() if(*e.bo || *e.jo){ pf("%.\n", e.ti); pf("\\fI%\\fP", e.bo ? e.bo : e.jo); - pf(" (*%)", t.ed, e.ed); + pf(" (*%)", t->ed, e.ed); }else pf("\\fI%\\fP", e.ti); /* Print volume. */ - pf(", *%", t.vo, e.vo); + pf(", *%", t->vo, e.vo); /* Print pages, converting hyphens to en dashes. */ if(*e.pp){ - printf(", %s", strpbrk(e.pp, ",-") ? t.pp : t.p); + printf(", %s", strpbrk(e.pp, ",-") ? t->pp : t->p); for(i = 0; i < strlen(e.pp); i++){ if(e.pp[i] == '-') putchar('\\'); putchar(e.pp[i]); @@ -201,7 +198,7 @@ harvard() pf(".\n"); /* Print translator. */ - pf("*%.\n", t.tr, e.tr); + pf("*%.\n", t->tr, e.tr); /* Print city, publisher. */ (pf("%: %.\n", e.ci, e.pu) || pf("%.\n", e.pu)); @@ -210,19 +207,69 @@ harvard() pf("%.\n", e.xx); /* Print hypertext reference. */ - pf("*%\n", t.avail, e.hr); + pf("*%\n", t->avail, e.hr); /* Print access date. */ pf("[%]\n", e.ad); - /* Clear unused fields. */ + /* Reset state. */ e.a = 0; -#define DO(s,n,m) \ - if(*m) fprintf(stderr, "%s: unused field %%"s" at line %d\n", \ - name, line); \ - *m = 0; - DO_FIELDS -#undef DO + #define DO(s,n,m) if(*m){ \ + fprintf(stderr, "%s: unused field %%"s" at line %d\n", \ + name, line); \ + *m = 0; \ + } + FOR_FIELDS + #undef DO +} + +/* Return pointer to translation struct. */ +struct trans * +gettrans(char *lg) +{ + if(strncmp(lg, "en", 2) == 0){ + if(!len){ + if(!(len = malloc(sizeof(struct trans)))) + err(1, "malloc"); + len->and = strdup("and"); + len->avail = strdup("Available: "); + len->ed = strdup("ed. "); + len->p = strdup("p. "); + len->pp = strdup("pp. "); + len->tr = strdup("Trans. "); + len->vo = strdup("vol. "); + } + return len; + }else if(strncmp(lg, "ru", 2) == 0){ + if(!lru){ + if(!(lru = malloc(sizeof(struct trans)))) + err(1, "malloc"); + lru->and = strdup("и"); + lru->avail = strdup("Доступный: "); + lru->ed = strdup("ред. "); + lru->p = strdup("c. "); + lru->pp = strdup("с. "); + lru->tr = strdup("Перев. "); + lru->vo = strdup("том "); + } + return lru; + }else if(strncmp(lg, "sv", 2) == 0){ + if(!lsv){ + if(!(lsv = malloc(sizeof(struct trans)))) + err(1, "malloc"); + lsv->and = strdup("och"); + lsv->avail = strdup("Tillgänglig: "); + lsv->ed = strdup("red. "); + lsv->p = strdup("s. "); + lsv->pp = strdup("ss. "); + lsv->tr = strdup("Övers. "); + lsv->vo = strdup("vol. "); + } + return lsv; + }else{ + fprintf(stderr, "%s: invalid language %s\n", name, lg); + exit(1); + } } /* -- cgit v1.2.3