ref: 78a59118aea99a388d678ba9bdd54b24322cc25c
parent: 333bf8409e656a9676c60d94de7aaa0f0af1e58e
author: Ali Gholami Rudi <ali@rudi.ir>
date: Tue Nov 20 15:57:43 EST 2012
implement .fp
--- a/dev.c
+++ b/dev.c
@@ -46,7 +46,7 @@
if (fn_font[pos])
font_close(fn_font[pos]);
if (fn_name[pos] != name) /* ignore if fn_name[pos] is passed */
- strcpy(fn_name[pos], name);
+ strcpy(fn_name[pos], id);
fn_font[pos] = fn;
printf("x font %d %s\n", pos, name);
return pos;
--- a/out.c
+++ b/out.c
@@ -36,9 +36,18 @@
return 1;
}
-static int nextchar(char *s)
+static int out_next(void)
{
int c = tr_next();
+ if (c < 0)
+ return -1;
+ buf[buflen++] = c;
+ return c;
+}
+
+static int nextchar(char *s)
+{
+ int c = out_next();
int l = utf8len(c);
int i;
if (c < 0)
@@ -45,10 +54,8 @@
return 0;
s[0] = c;
for (i = 1; i < l; i++)
- s[i] = tr_next();
+ s[i] = out_next();
s[l] = '\0';
- memcpy(buf + buflen, s, l + 1);
- buflen += l;
return l;
}
@@ -62,14 +69,6 @@
return s + l;
}
-static char *readint(char *s, int *d)
-{
- *d = 0;
- while (isdigit(*s))
- *d = *d * 10 + *s++ - '0';
- return s;
-}
-
static int charwid(int wid, int sz)
{
/* the original troff rounds the widths up */
@@ -78,10 +77,30 @@
static int o_s, o_f;
+static char *read_escarg(char *s, char *d)
+{
+ if (*s == '(') {
+ s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ } else if (*s == '\'') {
+ s++;
+ while (*s >= 0 && *s != '\'')
+ *d++ = *s++;
+ if (*s == '\'')
+ s++;
+ } else {
+ *d++ = *s++;
+ }
+ *d = '\0';
+ return s;
+}
+
static void flush(char *s)
{
struct glyph *g;
char c[LLEN];
+ char arg[LINELEN];
int o_blank = 0;
printf("v%d\n", n_v);
printf("H%d\n", n_o + n_i);
@@ -89,19 +108,22 @@
s = utf8get(c, s);
if (c[0] == '\\') {
s = utf8get(c, s);
- if (c[0] == 's') {
- s = readint(s, &o_s);
- printf("s%d\n", o_s);
- continue;
- }
- if (c[0] == 'f') {
- s = readint(s, &o_f);
- printf("f%d\n", o_f);
- continue;
- }
if (c[0] == '(') {
s = utf8get(c, s);
s = utf8get(c + strlen(c), s);
+ } else if (strchr("sf", c[0])) {
+ s = read_escarg(s, arg);
+ if (c[0] == 's') {
+ o_s = tr_int(arg, o_s, '\0');
+ printf("s%d\n", o_s);
+ continue;
+ }
+ if (c[0] == 'f') {
+ o_f = dev_font(arg);
+ if (o_f >= 0)
+ printf("f%d\n", o_f);
+ continue;
+ }
}
}
g = dev_glyph(c, o_f);
@@ -178,27 +200,72 @@
down(tr_int(args[1], 0, 'v'));
}
+static void out_ps(char *s)
+{
+ n_s = tr_int(s, n_s, '\0');
+}
+
void tr_ps(int argc, char **args)
{
if (argc >= 2)
- n_s = tr_int(args[1], n_s, '\0');
- buflen += sprintf(buf + buflen, "\\s%d", n_s);
+ out_ps(args[1]);
+ buflen += sprintf(buf + buflen, "\\s(%2d", n_s);
}
+static int out_ft(char *name)
+{
+ int fn = dev_font(name);
+ if (fn >= 0)
+ n_f = fn;
+ return fn;
+}
+
void tr_ft(int argc, char **args)
{
int fn;
if (argc < 2)
return;
- fn = dev_font(args[1]);
+ fn = out_ft(args[1]);
if (fn >= 0)
- n_f = fn;
- buflen += sprintf(buf + buflen, "\\f%d", n_f);
+ buflen += sprintf(buf + buflen, "\\f%d", n_f);
}
+void tr_fp(int argc, char **args)
+{
+ if (argc < 3)
+ return;
+ if (dev_mnt(atoi(args[1]), args[2], argc > 3 ? args[3] : args[2]) < 0)
+ fprintf(stderr, "troff: failed to mount %s\n", args[2]);
+}
+
+static void escarg(char *s)
+{
+ int c;
+ c = out_next();
+ if (c == '(') {
+ *s++ = out_next();
+ *s++ = out_next();
+ *s = '\0';
+ return;
+ }
+ if (c == '\'') {
+ while (1) {
+ c = out_next();
+ if (c == '\'' || c < 0)
+ break;
+ *s++ = c;
+ }
+ *s = '\0';
+ return;
+ }
+ *s++ = c;
+ *s = '\0';
+}
+
void render(void)
{
char c[LLEN];
+ char arg[LINELEN];
struct glyph *g;
struct word *word = NULL;
int word_beg;
@@ -213,6 +280,13 @@
int l = nextchar(c);
l += nextchar(c + l);
c[l] = '\0';
+ } else if (strchr("sf", c[0])) {
+ escarg(arg);
+ if (c[0] == 'f')
+ out_ft(arg);
+ if (c[0] == 's')
+ out_ps(arg);
+ continue;
}
}
g = dev_glyph(c, n_f);
--- a/tr.c
+++ b/tr.c
@@ -137,6 +137,7 @@
void (*f)(int argc, char **args);
} cmds[] = {
{"br", tr_br},
+ {"fp", tr_fp},
{"ft", tr_ft},
{"nr", tr_nr},
{"ps", tr_ps},
--- a/xroff.h
+++ b/xroff.h
@@ -5,7 +5,9 @@
#define FNGLYPHS 512
#define FNNAME 32
#define LLEN 128
+#define LINELEN 1024
+
/* number registers */
extern int nreg[];
int num_get(int id);
@@ -84,3 +86,4 @@
void tr_nr(int argc, char **args);
void tr_ps(int argc, char **args);
void tr_ft(int argc, char **args);
+void tr_fp(int argc, char **args);