1 /*
2  * tumble: build a PDF file from image files
3  *
4  * Parser
5  * Copyright 2001, 2002, 2003, 2017 Eric Smith <spacewar@gmail.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.  Note that permission is
10  * not granted to redistribute this program under the terms of any
11  * other version of the General Public License.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
21  *
22  *  2009-03-13 [JDB] Add support for blank pages, overlay images, color
23  *                   mapping, color-key masking, and push/pop of input
24  *                   contexts.
25  */
26 
27 %{
28   #include <stdbool.h>
29   #include <stdint.h>
30   #include <stdio.h>
31   #include "semantics.h"
32 
33   extern int yylex (void);
34 %}
35 
36 %error-verbose
37 
38 %union {
39   int integer;
40   char character;
41   double fp;
42   char *string;
43   page_size_t size;
44   range_t range;
45   page_label_t page_label;
46   overlay_t overlay;
47   rgb_t rgb;
48   rgb_range_t rgb_range;
49 }
50 
51 %token <integer> INTEGER
52 %token <fp> FLOAT
53 %token <string> STRING
54 %token <character> CHARACTER
55 %token <size> PAGE_SIZE
56 
57 %token ELIPSIS
58 
59 %token CM
60 %token INCH
61 
62 %token EVEN
63 %token ODD
64 %token ALL
65 
66 %token PORTRAIT
67 %token LANDSCAPE
68 
69 %token FILE_KEYWORD
70 %token IMAGE
71 %token IMAGES
72 %token ROTATE
73 %token CROP
74 %token SIZE
75 %token RESOLUTION
76 %token BLANK
77 %token INPUT
78 
79 %token TRANSPARENT
80 %token COLORMAP
81 %token LABEL
82 %token OVERLAY
83 %token PAGE
84 %token PAGES
85 %token BOOKMARK
86 %token OUTPUT
87 
88 %token AUTHOR
89 %token CREATOR
90 %token TITLE
91 %token SUBJECT
92 %token KEYWORDS
93 
94 %type <range> range
95 %type <range> image_ranges
96 %type <range> page_ranges
97 
98 %type <fp> unit
99 
100 %type <fp> length
101 
102 %type <integer> orientation
103 
104 %type <size> page_size
105 
106 %type <rgb> rgb
107 
108 %type <rgb_range> rgb_range
109 %type <rgb_range> gray_range
110 %type <rgb_range> color_range
111 
112 %%
113 
114 statements:
115 	statement
116 	| statements statement ;
117 
118 statement:
119 	input_statement
120 	| output_statement ;
121 
122 
123 range:
124 	INTEGER ELIPSIS INTEGER { $$.first = $1; $$.last = $3; }
125 	| INTEGER { $$.first = $1; $$.last = $1; } ;
126 
127 image_ranges:
128 	range { input_images ($1); }
129 	| image_ranges ',' range { input_images ($3); } ;
130 
131 
132 input_file_clause:
133 	FILE_KEYWORD STRING  ';'  { input_set_file ($2); } ;
134 
135 image_clause:
136 	IMAGE INTEGER ';' { range_t range = { $2, $2 }; input_images (range); } ;
137 
138 images_clause:
139 	IMAGES image_ranges ';' ;
140 
141 rotate_clause:
142 	ROTATE INTEGER ';' { input_set_rotation ($2); } ;
143 
144 unit:
145 	/* empty */  /* default to INCH */ { $$ = 1.0; }
146 	| CM { $$ = (1.0 / 25.4); }
147 	| INCH { $$ = 1.0; } ;
148 
149 length:
150 	FLOAT unit { $$ = $1 * $2; } ;
151 
152 crop_clause:
153 	CROP PAGE_SIZE ';'
154 	| CROP PAGE_SIZE orientation ';'
155 	| CROP length ',' length ';'
156 	| CROP length ',' length ',' length ',' length ';' ;
157 
158 orientation:
159 	PORTRAIT { $$ = 0; }
160 	| LANDSCAPE { $$ = 1; } ;
161 
162 page_size:
163 	PAGE_SIZE { $$ = $1; }
164 	| PAGE_SIZE orientation { if ($2)
165                                     {
166                                       $$.width = $1.height;
167 				      $$.height = $1.width;
168                                     }
169                                   else
170                                     $$ = $1;
171                                 }
172 	| length ',' length { $$.width = $1; $$.height = $3; } ;
173 
174 size_clause:
175 	SIZE page_size ';' { input_set_page_size ($2); } ;
176 
177 resolution_clause:
178 	RESOLUTION FLOAT unit ;
179 
180 rgb_range:
181 	'(' range range range ')' { $$.red = $2; $$.green = $3; $$.blue = $4; }
182 
183 gray_range:
184 	'(' range ')' { $$.red = $2; $$.green = $2; $$.blue = $2; } ;
185 
186 color_range:
187     rgb_range
188     | gray_range;
189 
190 transparency_clause:
191     TRANSPARENT color_range ';' { input_set_transparency ($2); } ;
192 
193 modifier_clause:
194 	rotate_clause | crop_clause | size_clause | resolution_clause | transparency_clause;
195 
196 modifier_clauses:
197 	modifier_clause
198 	| modifier_clauses modifier_clause;
199 
200 modifier_clause_list:
201 	'{' modifier_clauses '}' ;
202 
203 part_clause:
204 	ODD { input_set_modifier_context (INPUT_MODIFIER_ODD); }
205           modifier_clause_list ';'
206           { input_set_modifier_context (INPUT_MODIFIER_ALL); }
207 	| EVEN { input_set_modifier_context (INPUT_MODIFIER_EVEN); }
208 	  modifier_clause_list ';'
209           { input_set_modifier_context (INPUT_MODIFIER_ALL); } ;
210 
211 blank_page_clause:
212 	BLANK { input_set_file (NULL); } size_clause ;
213 
214 input_clause:
215 	input_file_clause
216 	| image_clause
217 	| images_clause
218 	| part_clause
219 	| modifier_clause
220 	| blank_page_clause
221 	| input_clause_list ;
222 
223 input_clauses:
224 	input_clause
225 	| input_clauses input_clause ;
226 
227 input_clause_list:
228 	'{' { input_push_context (); }
229 	input_clauses '}' { input_pop_context (); } ;
230 
231 input_statement:
232 	INPUT input_clauses ;
233 
234 pdf_file_attribute:
235 	AUTHOR STRING { output_set_author ($2); }
236 	| CREATOR STRING { output_set_creator ($2); }
237 	| TITLE STRING { output_set_title ($2); }
238 	| SUBJECT STRING { output_set_subject ($2); }
239 	| KEYWORDS STRING { output_set_keywords ($2); } ;
240 
241 pdf_file_attribute_list:
242 	pdf_file_attribute
243 	| pdf_file_attribute_list pdf_file_attribute ;
244 
245 pdf_file_attributes:
246 	/* empty */
247 	| pdf_file_attribute_list ;
248 
249 output_file_clause:
250 	FILE_KEYWORD STRING { output_set_file ($2); }
251 	pdf_file_attributes ';' ;
252 
253 label_clause:
254 	LABEL ';' { page_label_t label = { NULL, '\0' }; output_set_page_label (label); }
255 	| LABEL STRING ';' { page_label_t label = { $2, '\0' }; output_set_page_label (label); }
256 	| LABEL CHARACTER ';' { page_label_t label = { NULL, $2 }; output_set_page_label (label); }
257 	| LABEL STRING ',' CHARACTER ';' { page_label_t label = { $2, $4 }; output_set_page_label (label); } ;
258 
259 overlay_clause_list:
260 	/* empty */
261 	| '{' overlay_clauses '}' ;
262 
263 overlay_clauses:
264 	overlay_clause
265 	| overlay_clauses overlay_clause ;
266 
267 overlay_clause:
268 	OVERLAY length ',' length ';' { overlay_t overlay = { $2, $4 }; output_overlay (overlay); } ;
269 
270 page_ranges:
271 	range { output_pages ($1); }
272 	| page_ranges ',' range { output_pages ($3); } ;
273 
274 page_clause:
275 	PAGE INTEGER { range_t range = { $2, $2 }; output_pages (range); } overlay_clause_list ';' ;
276 
277 pages_clause:
278 	PAGES page_ranges ';' ;
279 
280 bookmark_name:
281 	STRING { output_set_bookmark ($1); } ;
282 
283 bookmark_name_list:
284 	bookmark_name
285 	| bookmark_name_list ',' bookmark_name ;
286 
287 bookmark_clause:
288 	BOOKMARK { output_push_context (); bookmark_level++; }
289 	bookmark_name_list
290 	output_clause_list ';' { bookmark_level--; output_pop_context (); } ;
291 
292 rgb:
293 	'(' INTEGER INTEGER INTEGER ')' { $$.red = $2; $$.green = $3; $$.blue = $4; } ;
294 
295 colormap_clause:
296 	COLORMAP rgb ',' rgb ';' { output_set_colormap ($2, $4); } ;
297 
298 output_clause:
299 	output_file_clause
300 	| colormap_clause
301 	| label_clause
302 	| page_clause | pages_clause
303 	| bookmark_clause
304 	| output_clause_list ;
305 
306 output_clauses:
307 	output_clause
308 	| output_clauses output_clause ;
309 
310 output_clause_list:
311 	'{' { output_push_context (); }
312 	output_clauses '}' { output_pop_context (); } ;
313 
314 output_statement:
315 	OUTPUT output_clauses ;
316