ref: 825749e792f7641f276439a9da067475ce5f8113
parent: 4d6875d50c8bfce3ea6083d19f142dad1681f2d0
author: Ali Gholami Rudi <ali@rudi.ir>
date: Sat Jan 11 14:19:36 EST 2020
post: mark and name device functions Bookmarks: \X'mark description page offset level' Labels: \X'name name page offset'
--- a/pdf.c
+++ b/pdf.c
@@ -734,6 +734,14 @@
obj_end();
}
+void outname(char *name, int page, int off)
+{
+}
+
+void outmark(int n, char (*desc)[256], int *page, int *off, int *level)
+{
+}
+
void outinfo(char *kwd, char *val)
{
if (!strcmp("Author", kwd))
--- a/post.c
+++ b/post.c
@@ -27,6 +27,14 @@
static int ps_linewidth = 40; /* drawing line thickness in thousandths of an em */
static int o_pages; /* output pages */
+/* bookmark management */
+static char (*mark_desc)[256]; /* bookmark description */
+static int *mark_page; /* bookmark page */
+static int *mark_offset; /* bookmark offset */
+static int *mark_level; /* bookmark level */
+static int mark_n; /* number of bookmarks */
+static int mark_sz; /* allocated size of bookmark arrays */
+
static int next(void)
{
return getc(stdin);
@@ -294,6 +302,14 @@
if (path[0] && !strcmp("pdf", cmd))
outpdf(path, hwid, vwid);
}
+ if (!strcmp("name", cmd)) {
+ char name[1 << 10];
+ int page = 0, offset = 0;
+ int nspec;
+ nspec = sscanf(arg, "%s %d %d", name, &page, &offset);
+ if (name[0] && nspec > 1)
+ outname(name, page == o_pages ? 0 : page, offset);
+ }
if (!strcmp("link", cmd)) {
char link[1 << 12];
int hwid, vwid, nspec;
@@ -303,6 +319,21 @@
if (link[0] && nspec == 2)
outlink(link, hwid, vwid);
}
+ if (!strcmp("mark", cmd)) {
+ char *spec = arg;
+ if (mark_n == mark_sz) {
+ mark_sz = mark_sz == 0 ? 128 : mark_sz * 2;
+ mark_desc = mextend(mark_desc, mark_n, mark_sz, sizeof(mark_desc[0]));
+ mark_page = mextend(mark_page, mark_n, mark_sz, sizeof(mark_page[0]));
+ mark_offset = mextend(mark_offset, mark_n, mark_sz, sizeof(mark_offset[0]));
+ mark_level = mextend(mark_level, mark_n, mark_sz, sizeof(mark_level[0]));
+ }
+ spec = strcut(mark_desc[mark_n], spec);
+ sscanf(spec, "%d %d %d", &mark_page[mark_n],
+ &mark_offset[mark_n], &mark_level[mark_n]);
+ if (mark_desc[mark_n][0])
+ mark_n++;
+ }
if (!strcmp("info", cmd)) {
char *spec = arg;
char kwd[128];
@@ -439,6 +470,7 @@
postcmd(c);
if (o_pages)
docpageend(o_pages);
+ outmark(mark_n, mark_desc, mark_page, mark_offset, mark_level);
}
static struct paper {
@@ -530,5 +562,9 @@
post();
doctrailer(o_pages);
dev_close();
+ free(mark_desc);
+ free(mark_page);
+ free(mark_offset);
+ free(mark_level);
return 0;
}
--- a/post.h
+++ b/post.h
@@ -60,6 +60,8 @@
void outeps(char *eps, int hwid, int vwid);
void outpdf(char *pdf, int hwid, int vwid);
void outlink(char *dst, int hwid, int vwid);
+void outname(char *name, int page, int off);
+void outmark(int n, char (*desc)[256], int *page, int *off, int *level);
void outinfo(char *kwd, char *val);
void outpage(void);
void outmnt(int f);
--- a/ps.c
+++ b/ps.c
@@ -7,6 +7,7 @@
static char ps_title[256]; /* document title */
static char ps_author[256]; /* document author */
+static int ps_height; /* document height in basic units */
static int o_f, o_s, o_m; /* font and size */
static int o_h, o_v; /* current user position */
static int p_f, p_s, p_m; /* output postscript font */
@@ -322,6 +323,39 @@
}
}
+void outname(char *name, int page, int off)
+{
+ o_flush();
+ outf("[ /Dest /%s", name);
+ if (page > 0)
+ outf(" /Page %d", page);
+ if (off > 0)
+ outf(" /View [/XYZ null %d null]",
+ (ps_height - off) * 72 / dev_res);
+ outf(" /DEST pdfmark\n");
+}
+
+void outmark(int n, char (*desc)[256], int *page, int *off, int *level)
+{
+ int i, j;
+ o_flush();
+ for (i = 0; i < n; i++) {
+ int cnt = 0;
+ for (j = i + 1; j < n && level[j] > level[i]; j++)
+ if (level[j] == level[i] + 1)
+ cnt++;
+ outf("[ /Title (%s)", desc[i]);
+ if (page[i] > 0)
+ outf(" /Page %d", page[i]);
+ if (cnt > 0)
+ outf(" /Count %d", cnt);
+ if (off[i] > 0)
+ outf(" /View [/XYZ null %d null]",
+ (ps_height - off[i]) * 72 / dev_res);
+ outf(" /OUT pdfmark\n");
+ }
+}
+
void outinfo(char *kwd, char *val)
{
if (!strcmp("Author", kwd))
@@ -352,7 +386,7 @@
out(" /Title (%s)", ps_title);
if (ps_author[0])
out(" /Author (%s)", ps_author);
- out("/Creator (Neatroff) /DOCINFO pdfmark\n");
+ out(" /Creator (Neatroff) /DOCINFO pdfmark\n");
out("%%%%Trailer\n");
out("done\n");
out("%%%%DocumentFonts: %s\n", o_fonts);
@@ -463,6 +497,7 @@
/* pagewidth and pageheight are in tenths of a millimetre */
void docheader(char *title, int pagewidth, int pageheight, int linewidth)
{
+ ps_height = pageheight * dev_res / 254;
out("%%!PS-Adobe-2.0\n");
out("%%%%Version: 1.0\n");
if (title)