ref: 6bf47606dec88a77390df6dae6ab27f9533cf0a1
parent: 145d0b3982f80b4630feb5229216e4fe81de2ddb
author: cinap_lenrek <cinap_lenrek@centraldogma>
date: Sat Sep 17 07:04:22 EDT 2011
page: experimental epub support
--- a/sys/src/cmd/page.c
+++ b/sys/src/cmd/page.c
@@ -167,7 +167,7 @@
void
pipeline(int fd, char *fmt, ...)
{
- char buf[128], *argv[4];
+ char buf[NPATH], *argv[4];
va_list arg;
int pfd[2];
@@ -205,6 +205,16 @@
close(pfd[0]);
}
+char*
+shortname(char *s)
+{
+ char *x;
+ if(x = strrchr(s, '/'))
+ if(x[1] != 0)
+ return x+1;
+ return s;
+}
+
int
popenfile(Page*);
@@ -270,7 +280,53 @@
return p->open(p);
}
+int
+popenepub(Page *p)
+{
+ char buf[NPATH], *s, *e;
+ int n, fd;
+ fd = p->fd;
+ p->fd = -1;
+ s = buf;
+ e = buf+sizeof(buf)-1;
+ s += snprint(s, e-s, "%s/", (char*)p->data);
+ free(p->data);
+ p->data = nil;
+ pipeline(fd, "awk '/\\<rootfile/{"
+ "if(match($0, /full\\-path\\=\\\"([^\\\"]+)\\\"/)){"
+ "print substr($0, RSTART+11,RLENGTH-12);exit}}'");
+ n = read(fd, s, e - s);
+ close(fd);
+ if(n <= 0)
+ return -1;
+ while(n > 0 && s[n-1] == '\n')
+ n--;
+ s += n;
+ *s = 0;
+ if((fd = open(buf, OREAD)) < 0)
+ return -1;
+ pipeline(fd, "awk '/\\<item/{"
+ "if(match($0, /id\\=\\\"([^\\\"]+)\\\"/)){"
+ "id=substr($0, RSTART+4, RLENGTH-5);"
+ "if(match($0, /href\\=\\\"([^\\\"]+)\\\"/)){"
+ "item[id]=substr($0, RSTART+6, RLENGTH-7)}}};"
+ "/\\<itemref/{"
+ "if(match($0, /idref\\=\\\"([^\\\"]+)\\\"/)){"
+ "ref=substr($0, RSTART+7, RLENGTH-8);"
+ "print item[ref]; fflush}}'");
+ s = strrchr(buf, '/')+1;
+ while((n = read(fd, s, e-s)) > 0){
+ while(n > 0 && s[n-1] == '\n')
+ n--;
+ s[n] = 0;
+ addpage(p, shortname(buf), popenfile, strdup(buf), -1);
+ }
+ close(fd);
+ return -1;
+}
+
+
typedef struct Ghost Ghost;
struct Ghost
{
@@ -534,6 +590,15 @@
if(d->mode & DMDIR){
free(d);
d = nil;
+
+ snprint(buf, sizeof(buf), "%s/META-INF/container.xml", file);
+ if((tfd = open(buf, OREAD)) >= 0){
+ close(fd);
+ p->fd = tfd;
+ p->open = popenepub;
+ return p->open(p);
+ }
+
if((n = dirreadall(fd, &d)) < 0)
goto Err1;
qsort(d, n, sizeof d[0], dircmp);
@@ -558,6 +623,10 @@
p->data = "lp -dstdout";
p->open = popengs;
}
+ else if(memcmp(buf, "<?xml", 5) == 0){
+ p->data = "htmlfmt -c utf8 | lp -dstdout";
+ p->open = popengs;
+ }
else if(memcmp(buf, "\xF7\x02\x01\x83\x92\xC0\x1C;", 8) == 0){
p->data = "dvips -Pps -r0 -q1 -f1";
p->open = popengs;
@@ -573,8 +642,7 @@
else if(memcmp(buf, "PK\x03\x04", 4) == 0){
p->data = "fs/zipfs";
p->open = popentape;
- }
- else if(memcmp(buf, "GIF", 3) == 0)
+ }else if(memcmp(buf, "GIF", 3) == 0)
p->data = "gif -t9";
else if(memcmp(buf, "\111\111\052\000", 4) == 0)
p->data = "fb/tiff2pic | fb/3to1 rgbv | fb/pcp -tplan9";
@@ -1052,16 +1120,6 @@
void drawerr(Display *, char *msg)
{
sysfatal("draw: %s", msg);
-}
-
-char*
-shortname(char *s)
-{
- char *x;
- if(x = strrchr(s, '/'))
- if(x[1] != 0)
- return x+1;
- return s;
}
void