Changeset 489024
- Timestamp:
- 01/12/2012 09:26:07 PM (14 years ago)
- Location:
- latex-everything/trunk
- Files:
-
- 2 edited
- 1 copied
- 1 moved
-
default-latex-single.php (moved) (moved from latex-everything/trunk/default-template.php)
-
default-latex-term.php (copied) (copied from latex-everything/trunk/default-template.php)
-
latex-document.php (modified) (8 diffs)
-
latex-everything.php (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
latex-everything/trunk/latex-document.php
r489023 r489024 2 2 3 3 define( 'PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); // Plugin directory with trailing slash 4 define( 'PDFLATEX', '/usr/texbin/pdflatex' ); 5 6 define( 'LE_POST_TYPE', 1 ); 4 5 define( 'LE_SINGLE_TYPE', 1 ); 7 6 define( 'LE_TERM_TYPE', 2 ); 8 7 … … 14 13 var $doc_type; 15 14 16 var $latex_file; 15 var $pdflatex_path; 16 var $pdftk_path; 17 18 var $latex_files; 17 19 var $pdf_file; 18 20 var $uploaded_file; 21 var $tmp_files; 19 22 20 23 var $unwanted_filter_functions = Array( 'wptexturize', 'convert_chars', 'esc_html', 'ent2ncr', '_wp_specialchars', 'sanitize_text_field', 'capital_P_dangit' ); 21 24 var $removed_filters; 22 25 26 var $combine_latex_files_callback; 27 23 28 function __construct ( $id, $taxonomy='' ) { 29 $this->tmp_files = array(); 30 $this->latex_files = array(); 31 $this->combine_latex_files_callback = array( &$this, 'concatenate_latex_files' ); 32 33 if ( !$this->pdflatex_path = exec( 'which pdflatex' ) ) 34 return new WP_Error( 'LE_Latex_Document::__construct', 'pdflatex not found' ); 35 if ( !$this->pdftk_path = exec( 'which pdftk' ) ) 36 return new WP_Error( 'LE_Latex_Document::__construct', 'pdftk not found' ); 37 24 38 if ( !$taxonomy ) { // Have post 25 $this->doc_type = LE_ POST_TYPE;39 $this->doc_type = LE_SINGLE_TYPE; 26 40 $source = get_post( $id ); 27 41 } else { // Have term … … 37 51 function __destruct () { 38 52 // Unlink temporary files 39 /* 40 unlink( $this->latex_file ); 41 unlink( $this->pdf_file ); 42 unlink( $this->latex_file . '.aux' ); 43 unlink( $this->latex_file . '.log' ); 44 */ 45 } 46 53 if ( ! WP_DEBUG ) { 54 array_map( 'unlink', $this->latex_files ); 55 array_map( 'unlink', $this->tmp_files ); 56 } 57 } 47 58 48 59 function generate() { 49 60 50 $latex_result = $this->make_latex_file(); 51 if ( is_wp_error( $latex_result ) ) { 52 return $latex_result; 53 } 54 55 error_log( "Before latex_file_to_pdf_file()" ); 56 $pdf_result = $this->latex_file_to_pdf_file(); 57 if ( is_wp_error( $pdf_result ) ) { 58 return $pdf_result; 59 } 60 61 $attach_id = $this->attach_pdf_file(); 62 if ( is_wp_error( $attach_id ) ) { 63 return $attach_id; 64 } 65 error_log( "After attach_pdf_file()" ); 66 return 0; // Return no error 67 } 68 69 function make_latex_file () { 70 $template = $this->_get_latex_template(); 71 72 // Render the template 73 if ( $this->doc_type == LE_POST_TYPE ) { 74 $args = array( 'orderby' => 'date', 75 'order' => 'DESC', 76 'posts_per_pate' => -1, 77 ); 78 if ( $this->source->post_type == 'page' ) 79 $args['page_id'] = $this->source->ID; 80 else 81 $args['p'] = $this->source->ID; 61 // Generate latex file(s). 62 if ( $this->doc_type == LE_SINGLE_TYPE ) { 63 $posts = array ( $this->source ); 82 64 } else { 65 // Generate single latex files for each of a term's posts, because Latex 66 // wasn't designed to generate multi-article documents. 83 67 $args = array( 'tax_query' => array( array( 84 68 'taxonomy' => $this->source->taxonomy, … … 88 72 'order' => 'DESC', 89 73 'posts_per_page' => -1, 74 'post_type' => null, 90 75 ); 91 } 76 $posts = get_posts( $args ); 77 } 78 foreach ( $posts as $post ) { 79 $latex_result = $this->make_latex_file( $post->ID, $post->post_type ); 80 if ( is_wp_error( $latex_result ) ) 81 return $latex_result; 82 else 83 $this->latex_files[] = $latex_result; 84 } 85 86 // Typset latex file(s) 87 if ( $this->doc_type == LE_SINGLE_TYPE ) { 88 $pdf_file = $this->typeset_file( $this->latex_files[0] ); 89 } else { 90 if ( is_callable( $this->combine_latex_files_callback ) ) 91 $pdf_file = call_user_func( $this->combine_latex_files_callback, &$this ); 92 } 93 if ( !$pdf_file ) 94 return new WP_Error( 'LE_Latex_Document::generate', "Error: No pdf file generated." ); 95 else if ( is_wp_error( $pdf_file ) ) 96 return $pdf_file; 97 else 98 $this->pdf_file = $pdf_file; 99 100 $attach_id = $this->attach_pdf_file(); 101 if ( is_wp_error( $attach_id ) ) { 102 return $attach_id; 103 } 104 return 0; // Return no error 105 } 106 107 /* Writes a latex file for a single post. 108 */ 109 function make_latex_file ($id, $post_type ) { 110 $template = $this->_get_latex_template( ); 111 112 // Query the post 113 $args = array( 'orderby' => 'date', 114 'order' => 'DESC', 115 ); 116 if ( $post_type == 'page' ) 117 $args['page_id'] = $id; 118 else 119 $args['p'] = $id; 92 120 query_posts( $args ); 121 122 // Render the template 93 123 $this->_set_up_latex_filters(); 94 124 ob_start(); … … 96 126 $latex = ob_get_clean(); 97 127 $this->_undo_latex_filters(); 128 98 129 wp_reset_query(); 99 130 100 131 // Get the name of a temporary file. 101 102 if ( !$this->latex_file = tempnam( sys_get_temp_dir(), 'le-' ) ) // Should fall back on system's temp dir if /tmp does not exist 132 if ( !$latex_file = tempnam( sys_get_temp_dir(), 'le-' ) ) 103 133 return new WP_Error( 'tempnam', 'Could not create temporary file.' ); 104 $dir = dirname( $ this->latex_file );134 $dir = dirname( $latex_file ); 105 135 106 136 // Open and write the latex the temporary file. 107 137 if ( !WP_DEBUG ) 108 $f = @fopen( $ this->latex_file, 'w' );109 else 110 $f = fopen( $ this->latex_file, 'w' );138 $f = @fopen( $latex_file, 'w' ); 139 else 140 $f = fopen( $latex_file, 'w' ); 111 141 if ( !$f ) 112 142 return new WP_Error( 'fopen', 'Could not open temporary file for writing' ); … … 119 149 fclose($f); 120 150 121 return $ this->latex_file;151 return $latex_file; 122 152 } 123 153 124 154 function _get_latex_template () { 155 $templates = array(); 156 $templates[] = 'latex'; 157 if ( $this->doc_type == LE_SINGLE_TYPE ) { 158 $templates[] = "latex-single"; 159 $templates[] = "latex-single-{$this->source->post_type}"; 160 $templates[] = "latex-single-{$this->source->post_type}-{$this->source->post_name}"; 161 $templates[] = "latex-single-{$this->source->post_type}-{$this->source->ID}"; 162 } else { 163 $templates[] = "latex-term"; 164 $templates[] = "latex-term-{$this->source->taxonomy}"; 165 $templates[] = "latex-term-{$this->source->taxonomy}-{$this->source->slug}"; 166 $templates[] = "latex-term-{$this->source->taxonomy}-{$this->source->term_id}"; 167 } 125 168 $template = get_query_template('latex'); 126 169 if ( empty( $template) ) { 127 $template = PLUGIN_DIR . 'default-template.php'; 170 if ( $this->doc_type == LE_SINGLE_TYPE ) 171 $template = PLUGIN_DIR . 'default-latex-single.php'; 172 else 173 $template = PLUGIN_DIR . 'default-latex-term.php'; 128 174 } 129 175 return $template; … … 157 203 } 158 204 159 function latex_file_to_pdf_file () { 160 error_log( "latex_file_to_pdf_file" ); 161 $dir = dirname( $this->latex_file ); 205 /* Calls pdflatex once on $latex_file, returning the path to the generated pdf, or a WP_Error. 206 * The optional $latex_cmd argument can be used when a command other than the default 207 * "[path/to/pdflatex] --interaction=nonstopmode [filename]" is needed. 208 */ 209 function typeset_file ( $latex_file, $latex_cmd='' ) { 210 $dir = dirname( $latex_file ); 162 211 163 212 // Tell Latex to search in the theme directory for class/style files. 164 213 putenv('TEXINPUTS=.:' . get_stylesheet_directory() . ':' . get_template_directory() . ':'); 165 $cmd = sprintf( 'cd %s; %s --interaction=nonstopmode %s 2>&1', $dir, PDFLATEX, $this->latex_file); 214 if ( !$latex_cmd ) 215 $latex_cmd = sprintf( "%s --interaction=nonstopmode %s", $this->pdflatex_path, $latex_file ); 216 $cmd = sprintf( 'cd %s; %s 2>&1', $dir, $latex_cmd ); 166 217 167 218 exec( $cmd, $latex_output, $v ); 168 219 169 220 if ( $v != 0 ) { // There was an error 170 $latex_output = join( "\n", $latex_output );221 $latex_output = implode( "\n", $latex_output ); 171 222 return new WP_Error( 'pdflatex', $latex_output ); 172 223 } 173 224 174 $this->pdf_file = $dir . '/' . basename($this->latex_file, '.tex') . '.pdf'; 175 return $this->pdf_file; 225 $pdf_file = $dir . '/' . basename($latex_file, '.tex') . '.pdf'; 226 227 $this->tmp_files[] = "{$latex_file}.log"; 228 $this->tmp_files[] = "{$latex_file}.aux"; 229 $this->tmp_files[] = $pdf_file; 230 231 return $pdf_file; 232 } 233 234 /* Typsets the latex files in $doc seperately then concatenates them with 235 * pdftk. Also ensures the page numbering is corret for each file. 236 */ 237 function concatenate_latex_files ( $doc ) { 238 // Get a temporary filename for the concatenated pdf. 239 if ( !$tmp_file = tempnam( sys_get_temp_dir(), 'le-' ) ) 240 return new WP_Error( 'tempnam', 'Could not create temporary file.' ); 241 $concatenated_pdf = "{$tmp_file}.pdf"; 242 unlink( $tmp_file ); 243 244 // Typset all of the latex files to be concatenated, fixing page numbers. 245 $pdf_files = array(); 246 $current_page = 1; 247 foreach ( $doc->latex_files as $latex_file ) { 248 $latex_cmd = "{$doc->pdflatex_path} --interaction=nonstopmode \"\AtBeginDocument{\setcounter{page}{{$current_page}}}\input{{$latex_file}}\""; 249 $pdf_files[] = $doc->typeset_file( $latex_file, $latex_cmd ); 250 $current_page += $this->_pages_in_pdf( end( $pdf_files ) ); 251 } 252 253 // Concatenate with pdftk 254 $cmd = sprintf( '%s %s cat output %s', $this->pdftk_path, implode( ' ', $pdf_files ), $concatenated_pdf ); 255 exec( $cmd, $pdftk_output, $v ); 256 if ( $v != 0 ) { // There was an error 257 $pdftk_output = implode( "\n", $pdftk_output ); 258 return new WP_Error( 'pdftk', $pdftk_output ); 259 } 260 261 $doc->tmp_files[] = $concatenated_pdf; 262 return $concatenated_pdf; 263 } 264 265 function _pages_in_pdf ( $pdf ) { 266 $cmd = "{$this->pdftk_path} {$pdf} dump_data"; 267 exec( $cmd, $pdftk_output, $v ); 268 $pdftk_output = implode( "\n", $pdftk_output ); 269 if ( preg_match('/NumberOfPages: (\d+)/', $pdftk_output, $matches ) ){ 270 return (int) $matches[1]; 271 } 272 return 0; 176 273 } 177 274 178 275 function attach_pdf_file () { 179 error_log( "attach_pdf_file()" ); 180 if ( $this->doc_type == LE_POST_TYPE ) { 181 $filename = $this->source->post_name . '.pdf'; 276 if ( $this->doc_type == LE_SINGLE_TYPE ) { 277 $filename = "{$this->source->post_name}.pdf"; 182 278 $title = $this->source->post_title; 183 279 $parent = $this->source->ID; 184 error_log( "Filename: {$filename}" );185 error_log( "Title: {$title}" );186 error_log( "Parent: {$parent}" );187 280 } else { 188 $filename = $this->source->slug . '.pdf'; 189 $title = "{$this->source->taxonomy} {$this->source->name}"; 281 $filename = "{$this->source->taxonomy}-{$this->source->slug}.pdf"; 282 $tax_name = ucwords( $this->source->taxonomy ); 283 $title = "{$tax_name} {$this->source->name}"; 190 284 $parent = 0; 191 285 } … … 202 296 // Check whether this post has an older file and attachment 203 297 // object we can update 204 if ( $this->doc_type == LE_POST_TYPE ) { 205 $args = array( 'post_type' => 'attachment', 206 'numberposts' => -1, 207 'post_status' => null, 208 'post_parent' => $this->source->ID ); 209 $attachments = get_posts($args); 210 if ($attachments) { 211 foreach ( $attachments as $attachment ) { 212 $attached_file = get_attached_file( $attachment->ID ); 213 if ( basename( $attached_file ) == $filename ) { 214 $this->uploaded_file = $attached_file; 215 $attachment_data['ID'] = $attachment->ID; 216 } 298 $args = array( 'post_type' => 'attachment', 299 'numberposts' => -1, 300 'post_status' => null, ); 301 if ( $this->doc_type == LE_SINGLE_TYPE ) 302 $args['post_parent'] = $this->source->ID; 303 else 304 $args['post_parent'] = 0; 305 $attachments = get_posts($args); 306 if ($attachments) { 307 foreach ( $attachments as $attachment ) { 308 $attached_file = get_attached_file( $attachment->ID ); 309 if ( basename( $attached_file ) == $filename ) { 310 $this->uploaded_file = $attached_file; 311 $attachment_data['ID'] = $attachment->ID; 217 312 } 218 313 } -
latex-everything/trunk/latex-everything.php
r489023 r489024 11 11 12 12 // TODO: Make documentation of API and install process. 13 // TODO: Extend generation to object other than posts - pages? categories? You'd just need to extend the 14 // templating and the "get latex stuff" API. You might also have to use WP-Cron more (more PDF 15 // being written at once), and hence improve the error handling to actually save error messages. 13 // TODO: Oh fsck, Latex wasn't supposed to typeset multiple papers. Find a way around it. Probably just typset the buggers seperately and glueing them together with combine. 16 14 17 15 global $latex_everything; … … 87 85 $this->create_document( $post_id ); 88 86 } 89 /*90 87 foreach( $this->taxonomies as $taxonomy ) { 91 88 if( $terms = get_the_terms( $post_id, $taxonomy ) ) { … … 97 94 } 98 95 } 99 */100 96 } 101 97 /* If le_error is in the query, a previous post save created an error
Note: See TracChangeset
for help on using the changeset viewer.