alias "source" to "server" in booki-twiki-gateway.cgi, to match espri
[objavi2.git] / wk_objavi.qs
blob08292e3027dc8fc82c5e6163d9ba3124d029c4e9
1 // Console: wk_objavi
2 // Description: shift margins left and right and add page numbers for wkhtmltopdf PDFs
4 /* ^^^^ previous lines are pdfedit magic. Let them be!
6 Part of Objavi2, which makes pdf versions of FLOSSManuals books.
8 This file is QSAscript for pdfedit. It makes pdfs more book-like,
9 adding gutters and page numbers.
11 Copyright (C) 2009 Douglas Bagnall
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or (at
16 your option) any later version.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License along
24 with this program; if not, write to the Free Software Foundation, Inc.,
25 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26  */
30 run("libobjavi.qs");
32 run( "pdfoperator.qs" ); // pdfedit stdlib, from /usr/share/pdfedit
34 function get_page_inverse_transform(page){
35     /*This is somewhat inefficient if the only transformation is at
36      the beginning of stream 0, which seems invariably to be the case.
37      */
39     var stream = page.getContentStream(page.getContentStreamCount() - 1);
40     var op = stream.getLastOperator();
41     //from /usr/share/pdfedit/pdfoperator.qs
42     var transform = get_cmToDetransformation(page, op);
43     var transform = getDetransformationMatrix(page, op);
44     return transform;
47 function number_check(parser, name, default_value){
48     return function(s){
49         var x = parser(s);
50         if (isNaN(x) && name)
51             throw(name + ' should be a number! (not "' + s + '")');
52         if (default_value != undefined)
53             return x || default_value;
54         return x;
55     };
59 const OPERATIONS = {
60     adjust_for_direction: 1,
61     resize: 2,
62     transform: 4,
63     shift: 8,
64     page_numbers: 16,
65     index: 32,
66     even_pages: 64,
68     dummy: 128,
69     all: 0xffff
72 const DEFAULT_OPERATION = 0;
74 function convert_operation(x){
75     if (! x){
76         x = 'all';
77     }
78     var words = x.lower().split(',');
79     var ops = 0;
80     for (var i = 0; i < words.length; i++){
81         var op = OPERATIONS[words[i]];
82         if (op)
83             ops |= op;
84     }
85     return ops;
89 function onConsoleStart() {
90     print("in wk_objavi");
92     var convertors = {
93         offset: number_check(parseFloat, 'offset'),
94         dir: function(x){return x.upper();},
95         number_style: function(x){return x.lower();},
96         centre_first: function(x){return x.lower() == 'true';},
97         centre_last: function(x){return x.lower() == 'true';},
98         number_start: number_check(parseInt, 'number_start', 1),
99         number_bottom: number_check(parseFloat, 'number_bottom'),
100         number_margin: number_check(parseFloat, 'number_margin'),
101         width: number_check(parseFloat, 'width'),
102         height: number_check(parseFloat, 'height'),
103         operation: convert_operation
104     };
106     var options = {
107         offset: DEFAULT_OFFSET,
108         dir:    DEFAULT_DIR,
109         number_style: DEFAULT_NUMBER_STYLE,
110         number_start: 1,
111         number_bottom: 20,
112         number_margin: 60,
113         filename: '',
114         output_filename: undefined,
115         width: COMIC_WIDTH,
116         height: COMIC_HEIGHT,
117         engine: DEFAULT_ENGINE,
118         centre_first: 'false',
119         centre_last: 'false',
120         operation: DEFAULT_OPERATION
121     };
123     options = parse_options(parameters(), options, convertors);
125     /* Rather than overwrite the file, copy it first to a similar name
126     and work on that ("saveas" doesn't work) */
127     var re = /^(.+)\.pdf$/i;
128     var m = re.search(options.filename);
129     if (m == -1){
130         throw(options.filename + " doesn't look like a pdf filename");
131     }
132     var newfilename = options.output_filename;
133     if (newfilename == undefined)
134         newfilename = re.cap(1) + '-PDFEDIT.pdf';
135     if (newfilename != options.filename)
136         Process.execute("cp " + options.filename + ' ' + newfilename);
138     var pdf = this.loadPdf(newfilename, 1);
141     function doing_op(op){
142         var ret = options.operation & OPERATIONS[op];
143         if (ret)
144             print("doing " + op);
145         return ret;
146     }
148     if (doing_op('even_pages')){
149         even_pages(pdf);
150     }
152     if (doing_op('adjust_for_direction')){
153         adjust_for_direction(pdf, options.offset, options.dir);
154     }
156     if (doing_op('resize')){
157         process_pdf(pdf, shift_page_mediabox, {offset: 0,
158                                                width: options.width,
159                                                height: options.height,
160                                                flip: undefined
161                                               });
162     }
163     if (doing_op('transform')){
164         process_pdf(pdf, transform_page, {offset: options.offset,
165                                           dir: options.dir,
166                                           flip: "offset"
167                                          },
168                                          (options.centre_first) ? 1 : undefined,
169                                          (options.centre_last) ? 1 : undefined
170                    );
171     }
172     if (doing_op('shift')){
173         process_pdf(pdf, shift_page_mediabox, {offset: options.offset,
174                                                flip: "offset",
175                                                width: options.width,
176                                                height: options.height
177                                               },
178                                               (options.centre_first) ? 1 : undefined,
179                                               (options.centre_last) ? 1 : undefined
180                    );
181     }
182     if (doing_op('page_numbers') &&
183         options.number_style != 'none'){
184         number_pdf_pages(pdf, options.dir, options.number_style,
185                          options.number_start, options.number_margin, options.number_bottom
186                         );
187     }
188     if (doing_op('index')){
189         save_text_index(pdf, newfilename+'.index');
190     }
192     pdf.save();
194     pdf.unloadPdf();