Changeset 489026
- Timestamp:
- 01/12/2012 09:27:00 PM (14 years ago)
- Location:
- latex-everything/trunk
- Files:
-
- 2 edited
-
latex-document.php (modified) (14 diffs)
-
latex-everything.php (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
latex-everything/trunk/latex-document.php
r489025 r489026 5 5 include('html-to-latex.php'); // Include functions to convert html to latex. 6 6 7 /* 8 * get_source 9 * get_posts 10 * typeset_all_files 11 * get_template 12 * get_attachment_title 13 * get_pdf_filename 14 * get_parent_post_id 15 */ 16 7 17 class LE_Latex_Document { 8 18 9 19 var $source; 10 var $title;11 var $filename;12 var $parent_post_id;13 20 14 21 var $pdflatex_path; 15 22 16 23 var $latex_files; 24 var $tmp_files; 17 25 var $pdf_file; 18 26 var $uploaded_file; 19 var $tmp_files;20 27 21 28 var $unwanted_filter_functions = Array( 'wptexturize', 'convert_chars', 'esc_html', 'ent2ncr', '_wp_specialchars', 'sanitize_text_field', 'capital_P_dangit' ); 22 29 var $removed_filters; 23 30 24 25 26 31 function __construct () { 32 33 $args = func_get_args(); 34 $source = call_user_func_array( array( $this, 'get_source' ), $args ); 35 if ( is_wp_error( $source ) ) 36 return $source; 37 $this->source = $source; 38 39 $this->latex_files = array(); 27 40 $this->tmp_files = array(); 28 $this->latex_files = array();29 41 30 42 if ( !$this->pdflatex_path = exec( 'which pdflatex' ) ) … … 45 57 46 58 /* This method is redefined by subclasses to generate and attach the pdf file. 47 * As a minimum the subclass needs to set48 * - $this->source49 * - $this->title50 * - $this->filename51 * - $this->parent_post_id52 59 */ 53 60 function generate() { 54 return WP_Error( 'LE_Latex_Document::generate', 'Method needs to be redefined by a subclass' ); 61 // Generate single latex files for each of a term's posts, because Latex 62 // wasn't designed to generate multi-article documents. 63 $posts = $this->get_posts(); 64 65 // Generate latex files. 66 foreach ( $posts as $post ) { 67 $latex_result = $this->make_latex_file( $post->ID, $post->post_type ); 68 if ( is_wp_error( $latex_result ) ) 69 return $latex_result; 70 $this->latex_files[] = $latex_result; 71 } 72 73 // Typeset latex files. 74 $pdf_file = $this->typeset_all_files(); 75 if ( is_wp_error( $pdf_file ) ) 76 return $pdf_file; 77 else 78 $this->pdf_file = $pdf_file; 79 80 // Attach pdf file 81 $attach_id = $this->attach_pdf_file(); 82 if ( is_wp_error( $attach_id ) ) 83 return $attach_id; 84 return 0; // Return no error 55 85 } 56 86 … … 58 88 */ 59 89 function make_latex_file ($id, $post_type ) { 60 $template = $this-> _get_template( );90 $template = $this->get_template( ); 61 91 62 92 // Query the post … … 71 101 72 102 // Render the template 73 $this-> _set_up_latex_filters();103 $this->set_up_latex_filters(); 74 104 ob_start(); 75 105 include( $template ); 76 106 $latex = ob_get_clean(); 77 $this-> _undo_latex_filters();107 $this->undo_latex_filters(); 78 108 79 109 wp_reset_query(); … … 102 132 } 103 133 104 function _get_template() {134 function get_template() { 105 135 return PLUGIN_DIR . 'default-latex.php'; 106 136 } … … 109 139 * Records which filters were removed so that they can be added again later. 110 140 */ 111 function _set_up_latex_filters() {141 function set_up_latex_filters() { 112 142 global $wp_filter; 113 143 foreach( $wp_filter as $tag => $priorities ) { … … 126 156 /* Add the filters back in again once Latex template processing has finished. 127 157 */ 128 function _undo_latex_filters() {158 function undo_latex_filters() { 129 159 global $wp_filter; 130 160 // (Doesn't quite get priorities right) … … 167 197 $attachment_data = array( 168 198 'post_mime_type' => $wp_filetype['type'], 169 'post_title' => $this-> title,199 'post_title' => $this->get_attachment_title(), 170 200 'post_name' => 'pdf', 171 201 'post_content' => '', … … 178 208 'numberposts' => -1, 179 209 'post_status' => null, 180 'post_parent' => $this-> parent_post_id, );210 'post_parent' => $this->get_parent_post_id(), ); 181 211 $attachments = get_posts($args); 182 212 if ($attachments) { 183 213 foreach ( $attachments as $attachment ) { 184 214 $attached_file = get_attached_file( $attachment->ID ); 185 if ( basename( $attached_file ) == $this-> filename) {215 if ( basename( $attached_file ) == $this->get_pdf_filename() ) { 186 216 $this->uploaded_file = $attached_file; 187 217 $attachment_data['ID'] = $attachment->ID; … … 193 223 if ( empty( $this->uploaded_file ) ) { 194 224 $upload_dir = wp_upload_dir(); 195 $this->uploaded_file = $upload_dir['path'] . '/' . $this-> filename;225 $this->uploaded_file = $upload_dir['path'] . '/' . $this->get_pdf_filename(); 196 226 } 197 227 198 228 // Create the attachment 199 229 copy( $this->pdf_file, $this->uploaded_file ); 200 $attach_id = wp_insert_attachment( $attachment_data, $this->uploaded_file, $this-> parent_post_id);230 $attach_id = wp_insert_attachment( $attachment_data, $this->uploaded_file, $this->get_parent_post_id() ); 201 231 if ( $attach_id == 0 ) { // Attachment error 202 232 return new WP_Error( 'wp_insert_attachment', 'Could not attach generated pdf' ); … … 210 240 class LE_Latex_Single_Document extends LE_Latex_Document { 211 241 212 function __construct( $id ) { 213 $source = get_post( $id ); 214 if ( is_wp_error( $source ) ) 215 return $source; 216 $this->source = $source; 217 218 $this->filename = "{$this->source->post_name}.pdf"; 219 $this->title = $this->source->post_title; 220 $this->parent_post_id = $this->source->ID; 242 function get_source( $id ) { 243 return get_post( $id ); 244 } 245 246 function get_posts() { 247 return array( $post = $this->source ); 248 } 249 250 function typeset_all_files() { 251 return $this->typeset_file( $this->latex_files[0] ); 252 } 221 253 222 return parent::__construct(); 223 } 224 225 function generate() { 226 $post = $this->source; 227 228 // Create latex file. 229 $latex_file = $this->make_latex_file( $post->ID, $post->post_type ); 230 if ( is_wp_error( $latex_file ) ) 231 return $latex_file; 232 $this->latex_files[] = $latex_file; 233 234 // Typset latex file. 235 $pdf_file = $this->typeset_file( $latex_file ); 236 if ( is_wp_error( $pdf_file ) ) 237 return $pdf_file; 238 else 239 $this->pdf_file = $pdf_file; 240 241 // Attach pdf file 242 $attach_id = $this->attach_pdf_file(); 243 if ( is_wp_error( $attach_id ) ) 244 return $attach_id; 245 return 0; // Return no error 246 } 247 248 function _get_template() { 254 function get_template() { 249 255 $templates = array(); 250 256 $templates[] = 'latex'; … … 255 261 $template = get_query_template('latex-single', $templates); 256 262 if ( empty( $template) ) 257 $template = parent:: _get_template();263 $template = parent::get_template(); 258 264 return $template; 259 265 } 266 267 function get_pdf_filename() { 268 return "{$this->source->post_name}.pdf"; 269 } 270 271 function get_attachment_title() { 272 return $this->source->post_title; 273 } 274 275 function get_parent_post_id() { 276 return $this->source->ID; 277 } 260 278 } 261 279 262 class LE_Latex_Term_Document extends LE_Latex_Document { 263 264 var $combine_latex_files_callback; 280 class LE_Latex_Multiple_Document extends LE_Latex_Document { 281 265 282 var $pdftk_path; 266 283 267 function __construct( $id, $taxonomy ) { 268 $this->combine_latex_files_callback = array( &$this, 'concatenate_latex_files' ); 269 284 function __construct() { 270 285 if ( !$this->pdftk_path = exec( 'which pdftk' ) ) 271 286 return new WP_Error( 'LE_Latex_Term_Document::__construct', 'pdftk not found' ); 272 287 call_user_func_array( 'parent::__construct', func_get_args() ); 288 } 289 290 291 /* Typsets the latex files in $doc seperately then concatenates them with 292 * pdftk. Also ensures the page numbering is corret for each file. 293 */ 294 function typeset_all_files () { 295 // Get a temporary filename for the concatenated pdf. 296 if ( !$tmp_file = tempnam( sys_get_temp_dir(), 'le-' ) ) 297 return new WP_Error( 'tempnam', 'Could not create temporary file.' ); 298 $concatenated_pdf = "{$tmp_file}.pdf"; 299 unlink( $tmp_file ); 300 301 // Typset all of the latex files to be concatenated, fixing page numbers. 302 $pdf_files = array(); 303 $current_page = 1; 304 foreach ( $this->latex_files as $latex_file ) { 305 $latex_cmd = "{$this->pdflatex_path} --interaction=nonstopmode \"\AtBeginDocument{\setcounter{page}{{$current_page}}}\input{{$latex_file}}\""; 306 $pdf_file = $this->typeset_file( $latex_file, $latex_cmd ); 307 if ( is_wp_error( $pdf_file ) ) 308 return $pdf_file; 309 $pdf_files[] = $pdf_file; 310 $current_page += $this->pages_in_pdf( $pdf_file ); 311 } 312 313 // Concatenate with pdftk 314 $cmd = sprintf( '%s %s cat output %s', $this->pdftk_path, implode( ' ', $pdf_files ), $concatenated_pdf ); 315 exec( $cmd, $pdftk_output, $v ); 316 if ( $v != 0 ) { // There was an error 317 $pdftk_output = implode( "\n", $pdftk_output ); 318 return new WP_Error( 'pdftk', $pdftk_output ); 319 } 320 321 $this->tmp_files[] = $concatenated_pdf; 322 return $concatenated_pdf; 323 } 324 325 /* Tells you how many pages are in the pdf specified by the string argument. 326 */ 327 function pages_in_pdf ( $pdf ) { 328 $cmd = "{$this->pdftk_path} {$pdf} dump_data"; 329 exec( $cmd, $pdftk_output, $v ); 330 $pdftk_output = implode( "\n", $pdftk_output ); 331 if ( preg_match('/NumberOfPages: (\d+)/', $pdftk_output, $matches ) ){ 332 return (int) $matches[1]; 333 } 334 return 0; 335 } 336 337 function get_parent_post_id() { 338 return 0; 339 } 340 } 341 342 343 class LE_Latex_Post_Type_Document extends LE_Latex_Multiple_Document { 344 345 function get_source( $post_type ) { 346 $source = get_post_type_object( $post_type ); 347 if ( !$source ) 348 return new WP_Error( 'LE_Latex_Term_Document', 'Could not find post type' ); 349 return $source; 350 } 351 352 function get_posts() { 353 $args = array( 'orderby' => 'date', 354 'order' => 'DESC', 355 'posts_per_page' => -1, 356 'post_type' => $this->source->name, ); 357 return get_posts( $args ); 358 } 359 360 function get_template() { 361 $templates = array(); 362 $templates[] = 'latex'; 363 $templates[] = "latex-post-type"; 364 $templates[] = "latex-post-type-{$this->source->name}"; 365 $template = get_query_template('latex-term', $templates); 366 if ( empty( $template) ) 367 $template = parent::get_template(); 368 return $template; 369 } 370 371 function get_attachment_title() { 372 return $this->source->labels->name; 373 } 374 375 function get_pdf_filename() { 376 return "{$this->source->name}.pdf"; 377 } 378 } 379 380 class LE_Latex_Term_Document extends LE_Latex_Multiple_Document { 381 382 function get_source( $id, $taxonomy ) { 273 383 $source = get_term( $id, $taxonomy ); 274 if ( is_wp_error( $source ) ) 275 return $source; 276 277 $this->source = $source; 278 279 $this->filename = "{$this->source->taxonomy}-{$this->source->slug}.pdf"; 280 $this->tax_name = ucwords( $this->source->taxonomy ); 281 $this->title = "{$taxonomy} {$this->source->name}"; 282 $this->parent_post_id = 0; 283 284 parent::__construct(); 285 } 286 287 function generate() { 288 // Generate single latex files for each of a term's posts, because Latex 289 // wasn't designed to generate multi-article documents. 384 return $source; 385 } 386 387 function get_posts() { 290 388 $args = array( 'tax_query' => array( array( 291 389 'taxonomy' => $this->source->taxonomy, … … 295 393 'order' => 'DESC', 296 394 'posts_per_page' => -1, 297 'post_type' => null, 298 ); 299 $posts = get_posts( $args ); 300 301 // Generate latex files. 302 foreach ( $posts as $post ) { 303 $latex_result = $this->make_latex_file( $post->ID, $post->post_type ); 304 if ( is_wp_error( $latex_result ) ) 305 return $latex_result; 306 $this->latex_files[] = $latex_result; 307 } 308 309 // Typset latex files. 310 if ( is_callable( $this->combine_latex_files_callback ) ) 311 $pdf_file = call_user_func( $this->combine_latex_files_callback, &$this ); 312 if ( !$pdf_file ) 313 return new WP_Error( 'LE_Latex_Term_Document::generate', "Error: No pdf file generated." ); 314 else if ( is_wp_error( $pdf_file ) ) 315 return $pdf_file; 316 else 317 $this->pdf_file = $pdf_file; 318 319 // Attach pdf file 320 $attach_id = $this->attach_pdf_file(); 321 if ( is_wp_error( $attach_id ) ) 322 return $attach_id; 323 return 0; // Return no error 324 } 325 326 function _get_template() { 395 'post_type' => null, ); 396 return get_posts( $args ); 397 } 398 399 function get_template() { 327 400 $templates = array(); 328 401 $templates[] = 'latex'; … … 333 406 $template = get_query_template('latex-term', $templates); 334 407 if ( empty( $template) ) 335 $template = parent:: _get_template();408 $template = parent::get_template(); 336 409 return $template; 337 410 } 338 411 339 /* Typsets the latex files in $doc seperately then concatenates them with 340 * pdftk. Also ensures the page numbering is corret for each file. 341 */ 342 function concatenate_latex_files ( $doc ) { 343 // Get a temporary filename for the concatenated pdf. 344 if ( !$tmp_file = tempnam( sys_get_temp_dir(), 'le-' ) ) 345 return new WP_Error( 'tempnam', 'Could not create temporary file.' ); 346 $concatenated_pdf = "{$tmp_file}.pdf"; 347 unlink( $tmp_file ); 348 349 // Typset all of the latex files to be concatenated, fixing page numbers. 350 $pdf_files = array(); 351 $current_page = 1; 352 foreach ( $doc->latex_files as $latex_file ) { 353 $latex_cmd = "{$doc->pdflatex_path} --interaction=nonstopmode \"\AtBeginDocument{\setcounter{page}{{$current_page}}}\input{{$latex_file}}\""; 354 $pdf_file = $doc->typeset_file( $latex_file, $latex_cmd ); 355 if ( is_wp_error( $pdf_file ) ) 356 return $pdf_file; 357 $pdf_files[] = $pdf_file; 358 $current_page += $this->_pages_in_pdf( $pdf_file ); 359 } 360 361 // Concatenate with pdftk 362 $cmd = sprintf( '%s %s cat output %s', $this->pdftk_path, implode( ' ', $pdf_files ), $concatenated_pdf ); 363 exec( $cmd, $pdftk_output, $v ); 364 if ( $v != 0 ) { // There was an error 365 $pdftk_output = implode( "\n", $pdftk_output ); 366 return new WP_Error( 'pdftk', $pdftk_output ); 367 } 368 369 $doc->tmp_files[] = $concatenated_pdf; 370 return $concatenated_pdf; 371 } 372 373 /* Tells you how many pages are in the pdf specified by the string argument. 374 */ 375 function _pages_in_pdf ( $pdf ) { 376 $cmd = "{$this->pdftk_path} {$pdf} dump_data"; 377 exec( $cmd, $pdftk_output, $v ); 378 $pdftk_output = implode( "\n", $pdftk_output ); 379 if ( preg_match('/NumberOfPages: (\d+)/', $pdftk_output, $matches ) ){ 380 return (int) $matches[1]; 381 } 382 return 0; 383 } 384 412 function get_attachment_title() { 413 $tax_name = ucwords( $this->source->taxonomy ); 414 return "{$tax_name} {$this->source->name}"; 415 } 416 417 function get_pdf_filename() { 418 return "{$this->source->taxonomy}-{$this->source->slug}.pdf"; 419 } 385 420 } 386 421 -
latex-everything/trunk/latex-everything.php
r489025 r489026 11 11 12 12 // TODO: Make documentation of API and install process. 13 // TODO: Allow access to the post_type and term pdfs. 14 // TODO: Use wp-cron to trigger the generation of some stuff, since php is running out of memory. 13 15 // TODO: Allow people to define what is Latexed. 16 14 17 15 18 include('latex-document.php'); … … 88 91 if( in_array( $post_type, $this->post_types ) ) { 89 92 $docs[] = new LE_Latex_Single_Document( $post_id ); 93 $docs[] = new LE_Latex_Post_Type_Document( $post_type ); 90 94 } 91 95 foreach( $this->taxonomies as $taxonomy ) { … … 95 99 else 96 100 foreach( $terms as $term ) 97 $docs[] = new LE_Latex_Term_Document( $term, $taxonomy ); 101 $i = 1; 102 $docs[] = new LE_Latex_Term_Document( $term->term_id, $taxonomy ); 98 103 } 99 104 }
Note: See TracChangeset
for help on using the changeset viewer.