diff options
author | John Ankarström <john@ankarstrom.se> | 2021-07-20 13:33:35 +0200 |
---|---|---|
committer | John Ankarström <john@ankarstrom.se> | 2021-07-21 11:19:55 +0200 |
commit | 45a1cc39c6515c6f8462a1d833da1bd58af420b6 (patch) | |
tree | 1e3172f4138478ab5cb7eddc8fe959eb582aae0d | |
parent | 577a9653d0c22779a64d38e2338ed07ffbe0ecf5 (diff) | |
download | fref-45a1cc39c6515c6f8462a1d833da1bd58af420b6.tar.gz |
Add -l (language) flag
-rw-r--r-- | fref.1 | 88 | ||||
-rw-r--r-- | fref.lex | 127 |
2 files changed, 134 insertions, 81 deletions
@@ -7,6 +7,7 @@ . .Sh SYNOPSIS .Nm +.Op Fl l Ar lang . .Sh DESCRIPTION .Pp @@ -24,32 +25,19 @@ They are inserted in the places they are specified in the .Xr troff 1 source code. .Pp -.Pa fref.lex -contains a number of hardcoded strings -that should be manually changed -depending on the desired output language: -.Bl -tag -width AVAIL -offset indent -.It AND -.Dq and : -Inserted between next to last and last author. -.It AVAIL -.Dq available : -Inserted before a hypertext reference. -.It ED -.Dq editor : -Inserted before the name of the editor. -.It P -.Dq page : -Inserted before a single page. -.It PP -.Dq pages : -Inserted before multiple pages. -.It TR -.Dq translator : -Inserted before the name of the translator. -.It VOL -.Dq volume : -Inserted before the volume number. +The +.Fl l +flag controls the language of certain strings, such as +.Dq ed. , +.Dq pp. , +and +.Dq and . +The following values are supported: +.Bl -tag -width xx -offset indent +.It Em en +English (default) +.It Em sv +Swedish .El . .Sh SYNTAX @@ -68,38 +56,46 @@ non-field lines. The following fields are available: .Bl -tag -width xxx -offset indent .It Sy %ad -Access date. +Access date .It Sy %bo -Book. +Book .It Sy %ci -City. +City .It Sy %da -Date (year). +Date (year) .It Sy %ed -Editor. +Editor .It Sy %hr -Hypertext reference. +Hypertext reference .It Sy %jo -Journal. +Journal .It Sy %la -Label. +Label .It Sy %no -TODO: Issue number. +TODO: Issue number .It Sy %pp -Pages. +Pages .It Sy %pu -Publisher. +Publisher .It Sy %se -TODO: Series. +TODO: Series .It Sy %ti -Title. +Title .It Sy %tr -Translator. +Translator .It Sy %vo -Volume. +Volume .It Sy %xx -Extra information. +Extra information .El +.Pp +Note that +.Nm +performs no special formatting of the +.Sy %au +field. +Thus, it should be specified as +.Dq "last name, first name" . . .Sh EXAMPLES .Pp @@ -119,6 +115,8 @@ References %ci Bloomington %pu Indiana University Press %xx Extra information +\&.XP +\&.\\" ... .Ed .Pp results in the following output: @@ -128,10 +126,12 @@ References \&.XP Baudouin de Courtenay, J. (1972). The Difference between Phonetics and Psychophonetics. -\\fIA Baudouin de Courtenay Anthology\\fP (red. T. A. Sebeok et al.). -Övers. Edward Stankiewicz. +\\fIA Baudouin de Courtenay Anthology\\fP (ed. T. A. Sebeok et al.). +Trans. Edward Stankiewicz. Bloomington: Indiana University Press. Extra information. +\&.XP +\&.\\" ... .Ed . .Sh SEE ALSO @@ -16,18 +16,6 @@ #define MAX 255 /* Max field length. */ - /* - * The following string constants can be redefined to support - * other languages. - */ - #define AND "och" - #define AVAIL "Tillgänglig: " - #define ED "red." - #define P "s." - #define PP "ss." - #define TR "Övers." - #define VOL "vol." - #define DO_FIELDS \ DO("ad",ad,e.ad) /* Access date. */ \ DO("bo",bo,e.bo) /* Book. */ \ @@ -52,14 +40,14 @@ void harvard(void); 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. */ - /* - * e is a struct holding all fields of the current entry. - * It is zeroed at the end of each call to entry(). - */ + /* Fields of current entry. */ struct entry { #define DO(s,n,m) char n[MAX]; DO_FIELDS @@ -68,6 +56,17 @@ char au[MAX][MAX]; /* Authors. */ } e; + /* Translation strings. */ + struct translations { + char *and; + char *avail; + char *ed; + char *p; + char *pp; + char *tr; + char *vo; + } t; + %% \n lines++; ECHO; ^%.*\n line = ++lines; field(yytext); BEGIN(ENTRY); @@ -77,32 +76,74 @@ %% void -main(int argc, char *argv[0]) +main(int argc, char *argv[]) { + char *lang; + int c; + + /* Save program name. */ name = strrchr(argv[0], '/'); if(name) name++; else name = argv[0]; + /* Parse command-line options. */ + while((c = getopt(argc, argv, "l:")) != -1) + switch(c){ + case 'l': + lang = optarg; + break; + default: + fprintf(stderr, "usage: %s [-lLANG]\n", argv[0]); + exit(1); + } + 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. "); + } + + /* Clear entry struct. */ memset(&e, 0, sizeof(e)); + yylex(); } /* Save entry field. */ void -field(char *t) +field(char *s) { - t++; - t[strcspn(t, "\n")] = 0; + s++; + s[strcspn(s, "\n")] = 0; /* Fill corresponding field. */ -#define AS(a,b) if(strncmp(t, a, 2) == 0 && (t += 3)){ strcpy(b, t); 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 + /* + * As no field matched, an error is printed and the program exits + * with a positive value. + */ fprintf(stderr, "%s: unrecognized field %%%.2s at line %d\n", - name, t, lines); + name, s, lines); exit(1); } @@ -111,8 +152,8 @@ void entry() { /* - * Presently, fref supports only Harvard-style citations, but - * allows for future extensions. + Presently, fref supports only Harvard-style citations, but + this allows for future extensions. */ harvard(); } @@ -130,7 +171,7 @@ harvard() for(i = 0; i < e.a-2; i++) printf("%s, ", e.au[i]); if(i == e.a-2) - printf("%s "AND" ", e.au[i++]); + printf("%s %s ", e.au[i++], t.and); if(i == e.a-1) printf("%s", e.au[i]); @@ -141,16 +182,16 @@ harvard() if(*e.bo || *e.jo){ pf("%.\n", e.ti); pf("\\fI%\\fP", e.bo ? e.bo : e.jo); - pf(" ("ED" %)", e.ed); + pf(" (*%)", t.ed, e.ed); }else pf("\\fI%\\fP", e.ti); /* Print volume. */ - pf(", "VOL" %", e.vo); + pf(", *%", t.vo, e.vo); /* Print pages, converting hyphens to en dashes. */ if(*e.pp){ - printf(", %s ", strpbrk(e.pp, ",-") ? PP : 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]); @@ -160,7 +201,7 @@ harvard() pf(".\n"); /* Print translator. */ - pf(TR" %.\n", e.tr); + pf("*%.\n", t.tr, e.tr); /* Print city, publisher. */ (pf("%: %.\n", e.ci, e.pu) || pf("%.\n", e.pu)); @@ -169,7 +210,7 @@ harvard() pf("%.\n", e.xx); /* Print hypertext reference. */ - pf(AVAIL"%\n", e.hr); + pf("*%\n", t.avail, e.hr); /* Print access date. */ pf("[%]\n", e.ad); @@ -184,7 +225,12 @@ harvard() #undef DO } -/* Print formatted text if given fields are non-empty. Clear fields. */ +/* + * This function interpolates any number of strings into a formatted + * string, which is printed only if all interpolated strings are non-empty. + * Interpolation points are marked by % or *. If a string is interpolated + * using %, the function empties it after printing it. + */ int pf(char *fmt, ...) { @@ -192,16 +238,18 @@ pf(char *fmt, ...) int i, n, sz; va_list ap; - /* Count given fields. */ + /* Count interpolated strings. */ for(n = 0, p = fmt; *p; p++) - if(*p == '%') + if(*p == '%' || *p == '*') n++; - /* Allocate memory. */ if(!(fs = malloc(n))) err(1, "malloc"); - /* Verify that no field is empty. */ + /* + * The strings to be interpolated are saved in fs. + * If any string is empty, the function returns false. + */ va_start(ap, fmt); for(i = 0; i < n; i++){ p = va_arg(ap, char *); @@ -211,12 +259,17 @@ pf(char *fmt, ...) } va_end(ap); - /* Print fields according to format. */ + /* Print formatted string. */ for(i = 0; *fmt; fmt++) switch(*fmt){ case '%': printf("%s", fs[i]); - fs[i++][0] = 0; + fs[i][0] = 0; + i++; + break; + case '*': + printf("%s", fs[i]); + i++; break; default: putchar(*fmt); |