@@ 0,0 1,171 @@
+#include <u.h>
+#include <libc.h>
+#include <stdio.h>
+#include <draw.h>
+#include <event.h>
+#include <cursor.h>
+
+int checkonly;
+char *file, *contents;
+
+typedef struct Slide {
+ char *cmd;
+ char *arg;
+ int nlines;
+ char *lines[];
+} Slide;
+
+char *
+nextline(char **p)
+{
+ char *line;
+ while(1){
+ line = *p;
+ while(**p != '\n' && **p != '\0') (*p)++;
+ if(**p == '\0')
+ return nil;
+
+ **p = '\0';
+ (*p)++;
+ return line;
+ }
+}
+
+Slide *
+nextslide(char **p)
+{
+ char *cmd, *arg, *line1, *line, *lineN;
+ int nlines, blines, i;
+ Slide *s;
+
+ while(1){
+ if((cmd = nextline(p)) == nil)
+ return nil;
+ if(cmd[0] != '%')
+ continue;
+ break;
+ }
+
+ cmd++;
+ arg = cmd;
+
+ while(*arg != ' ' && *arg != '\t' && *arg != '\0') arg++;
+ if(*arg == '\0')
+ arg = nil;
+ else
+ *(arg++) = '\0';
+
+ line1 = nextline(p);
+ if(line1 != nil && *line1 == '%'){
+ *p = line1;
+ line1[strlen(line1)] = '\n';
+ line1 = nil;
+ }
+ if(line1 == nil){
+ s = malloc(sizeof(Slide));
+ s->cmd = cmd;
+ s->arg = arg;
+ s->nlines = 0;
+ return s;
+ }
+ lineN = line1;
+ nlines = 1;
+ blines = 0;
+
+ while((line = nextline(p)) != nil){
+ if(*line == '\0'){
+ blines++;
+ continue;
+ }
+ if(*line == '%'){
+ *p = line;
+ line[strlen(line)] = '\n';
+ break;
+ }
+
+ nlines += blines;
+ blines = 0;
+ nlines++;
+ lineN = line;
+ }
+
+ s = malloc(sizeof(Slide) + sizeof(char*) * nlines);
+
+ s->cmd = cmd;
+ s->arg = arg;
+ s->nlines = nlines;
+
+ line = line1;
+ for(i = 0; line != lineN; i++){
+ s->lines[i] = line;
+ line += strlen(line) + 1;
+ }
+ s->lines[i] = lineN;
+
+ return s;
+}
+
+void
+checkfile(void)
+{
+ int i;
+ char *c2, *p;
+ Slide *s;
+
+ c2 = strdup(contents);
+ p = c2;
+
+ while((s = nextslide(&p)) != nil){
+ print("Slide: %s (%d lines)\n", s->cmd, s->nlines);
+ if(s->arg != nil)
+ print("\targ: %s\n", s->arg);
+ for(i = 0; i < s->nlines; i++)
+ print("\tline %d: %s\n", i, s->lines[i]);
+ }
+}
+
+void
+usage(void)
+{
+ fprint(2,"usage: %s [ -c ] filename\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ int fd;
+ Dir *d;
+
+ ARGBEGIN{
+ case 'c':
+ checkonly = 1;
+ break;
+ default:
+ usage();
+ }ARGEND
+
+ if(argc != 1)
+ usage();
+
+ file = argv[0];
+
+ if((fd = open(file, OREAD)) < 0)
+ sysfatal("%r");
+ if((d = dirfstat(fd)) == nil)
+ sysfatal("%r");
+
+ contents = malloc(d->length + 2);
+ if(readn(fd, contents, d->length) < 0)
+ sysfatal("%r");
+ // cursed but makes the handling nicer above
+ contents[d->length] = '\n';
+ contents[d->length + 1] = '\0';
+ free(d);
+ close(fd);
+
+ checkfile();
+
+ if(checkonly)
+ exits(nil);
+}