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