shithub: riscv

Download patch

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