Difference between revisions of "Extension:PdfBook"
m (cat) |
(0.0.10 - bug preventing other action hooks from working) |
||
Line 7: | Line 7: | ||
if (!defined('MEDIAWIKI')) die('Not an entry point.'); | if (!defined('MEDIAWIKI')) die('Not an entry point.'); | ||
− | define('PDFBOOK_VERSION','0.0. | + | define('PDFBOOK_VERSION','0.0.10, 2008-04-16'); |
− | $wgPdfBookMagic | + | $wgPdfBookMagic = "book"; |
− | $wgExtensionFunctions[] = 'wfSetupPdfBook'; | + | $wgExtensionFunctions[] = 'wfSetupPdfBook'; |
$wgHooks['LanguageGetMagic'][] = 'wfPdfBookLanguageGetMagic'; | $wgHooks['LanguageGetMagic'][] = 'wfPdfBookLanguageGetMagic'; | ||
$wgExtensionCredits['parserhook'][] = array( | $wgExtensionCredits['parserhook'][] = array( | ||
− | 'name' => 'Pdf Book', | + | 'name' => 'Pdf Book', |
'author' => '[http://www.organicdesign.co.nz/nad User:Nad]', | 'author' => '[http://www.organicdesign.co.nz/nad User:Nad]', | ||
'description' => 'Composes a book from articles in a category and exports as a PDF book', | 'description' => 'Composes a book from articles in a category and exports as a PDF book', | ||
− | 'url' | + | 'url' => 'http://www.mediawiki.org/wiki/Extension:Pdf_Book', |
'version' => PDFBOOK_VERSION | 'version' => PDFBOOK_VERSION | ||
); | ); | ||
Line 35: | Line 35: | ||
$wgLogHeaders['pdf'] = 'pdflogpagetext'; | $wgLogHeaders['pdf'] = 'pdflogpagetext'; | ||
$wgLogActions['pdf/book'] = 'pdflogentry'; | $wgLogActions['pdf/book'] = 'pdflogentry'; | ||
− | + | } | |
# Expand the book-magic | # Expand the book-magic | ||
Line 44: | Line 44: | ||
foreach (func_get_args() as $arg) if (!is_object($arg)) { | foreach (func_get_args() as $arg) if (!is_object($arg)) { | ||
if (preg_match('/^(.+?)\\s*=\\s*(.+)$/',$arg,$match)) $argv[$match[1]] = $match[2]; else $argv[] = $arg; | if (preg_match('/^(.+?)\\s*=\\s*(.+)$/',$arg,$match)) $argv[$match[1]] = $match[2]; else $argv[] = $arg; | ||
− | + | } | |
# Return result with available parser flags | # Return result with available parser flags | ||
Line 55: | Line 55: | ||
isHTML => false | isHTML => false | ||
); | ); | ||
− | + | } | |
function onUnknownAction($action,$article) { | function onUnknownAction($action,$article) { | ||
Line 92: | Line 92: | ||
if ($result instanceof ResultWrapper) $result = $result->result; | if ($result instanceof ResultWrapper) $result = $result->result; | ||
while ($row = $db->fetchRow($result)) $articles[] = Title::newFromID($row[0]); | while ($row = $db->fetchRow($result)) $articles[] = Title::newFromID($row[0]); | ||
− | + | } | |
else { | else { | ||
$text = $article->fetchContent(); | $text = $article->fetchContent(); | ||
Line 98: | Line 98: | ||
if (preg_match_all('/^\\*\\s*\\[{2}\\s*([^\\|\\]]+)\\s*.*?\\]{2}/m',$text,$links)) | if (preg_match_all('/^\\*\\s*\\[{2}\\s*([^\\|\\]]+)\\s*.*?\\]{2}/m',$text,$links)) | ||
foreach ($links[1] as $link) $articles[] = Title::newFromText($link); | foreach ($links[1] as $link) $articles[] = Title::newFromText($link); | ||
− | + | } | |
# Format the article's as a single HTML document with absolute URL's | # Format the article's as a single HTML document with absolute URL's | ||
Line 124: | Line 124: | ||
$ttext = basename($ttext); | $ttext = basename($ttext); | ||
$html .= utf8_decode("<h1>$ttext</h1>$text\n"); | $html .= utf8_decode("<h1>$ttext</h1>$text\n"); | ||
− | |||
} | } | ||
+ | } | ||
# If format=html in query-string, return html content directly | # If format=html in query-string, return html content directly | ||
Line 133: | Line 133: | ||
header("Content-Disposition: attachment; filename=\"$book.html\""); | header("Content-Disposition: attachment; filename=\"$book.html\""); | ||
print $html; | print $html; | ||
− | + | } | |
else { | else { | ||
# Write the HTML to a tmp file | # Write the HTML to a tmp file | ||
Line 153: | Line 153: | ||
passthru($cmd); | passthru($cmd); | ||
@unlink($file); | @unlink($file); | ||
− | |||
} | } | ||
− | + | return false; | |
− | |||
} | } | ||
+ | |||
+ | return true; | ||
+ | } | ||
# Return a property for htmldoc using global, request or passed default | # Return a property for htmldoc using global, request or passed default | ||
Line 164: | Line 165: | ||
if (isset($GLOBALS["wgPdfBook$name"])) return $GLOBALS["wgPdfBook$name"]; | if (isset($GLOBALS["wgPdfBook$name"])) return $GLOBALS["wgPdfBook$name"]; | ||
return $default; | return $default; | ||
− | + | } | |
# Needed in some versions to prevent Special:Version from breaking | # Needed in some versions to prevent Special:Version from breaking | ||
function __toString() { return 'PdfBook'; } | function __toString() { return 'PdfBook'; } | ||
− | + | } | |
− | |||
# Called from $wgExtensionFunctions array when initialising extensions | # Called from $wgExtensionFunctions array when initialising extensions | ||
Line 175: | Line 175: | ||
global $wgPdfBook; | global $wgPdfBook; | ||
$wgPdfBook = new PdfBook(); | $wgPdfBook = new PdfBook(); | ||
− | + | } | |
# Needed in MediaWiki >1.8.0 for magic word hooks to work properly | # Needed in MediaWiki >1.8.0 for magic word hooks to work properly | ||
Line 182: | Line 182: | ||
$magicWords[$wgPdfBookMagic] = array(0,$wgPdfBookMagic); | $magicWords[$wgPdfBookMagic] = array(0,$wgPdfBookMagic); | ||
return true; | return true; | ||
− | + | } |
Revision as of 10:11, 16 April 2008
<?php
- Extension:PdfBook
Template:PhpCategory:Extensions created with Template:Extension
- - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
- - Author: User:NadCategory:Extensions in progress
- - Started: 2007-08-08
if (!defined('MEDIAWIKI')) die('Not an entry point.');
define('PDFBOOK_VERSION','0.0.10, 2008-04-16');
$wgPdfBookMagic = "book"; $wgExtensionFunctions[] = 'wfSetupPdfBook'; $wgHooks['LanguageGetMagic'][] = 'wfPdfBookLanguageGetMagic';
$wgExtensionCredits['parserhook'][] = array( 'name' => 'Pdf Book', 'author' => 'User:Nad', 'description' => 'Composes a book from articles in a category and exports as a PDF book', 'url' => 'http://www.mediawiki.org/wiki/Extension:Pdf_Book', 'version' => PDFBOOK_VERSION );
class PdfBook {
# Constructor function PdfBook() { global $wgHooks,$wgParser,$wgPdfBookMagic; $wgParser->setFunctionHook($wgPdfBookMagic,array($this,'magicBook')); $wgHooks['UnknownAction'][] = $this;
# Add a new pdf log type global $wgLogTypes,$wgLogNames,$wgLogHeaders,$wgLogActions; $wgLogTypes[] = 'pdf'; $wgLogNames ['pdf'] = 'pdflogpage'; $wgLogHeaders['pdf'] = 'pdflogpagetext'; $wgLogActions['pdf/book'] = 'pdflogentry'; }
# Expand the book-magic function magicBook(&$parser) {
# Populate $argv with both named and numeric parameters $argv = array(); foreach (func_get_args() as $arg) if (!is_object($arg)) { if (preg_match('/^(.+?)\\s*=\\s*(.+)$/',$arg,$match)) $argv[$match[1]] = $match[2]; else $argv[] = $arg; }
# Return result with available parser flags return array( $text, found => true, nowiki => false, noparse => false, noargs => false, isHTML => false ); }
function onUnknownAction($action,$article) { global $wgOut,$wgUser,$wgTitle,$wgParser; global $wgServer,$wgArticlePath,$wgScriptPath,$wgUploadPath,$wgUploadDirectory,$wgScript;
if ($action == 'pdfbook') {
# Log the export $msg = $wgUser->getUserPage()->getPrefixedText().' exported as a PDF book'; $log = new LogPage('pdf',false); $log->addEntry('book',$wgTitle,$msg);
# Initialise PDF variables $layout = '--firstpage toc'; $left = $this->setProperty('LeftMargin', '1cm'); $right = $this->setProperty('RightMargin', '1cm'); $top = $this->setProperty('TopMargin', '1cm'); $bottom = $this->setProperty('BottomMargin','1cm'); $font = $this->setProperty('Font', 'Arial'); $size = $this->setProperty('FontSize', '8'); $link = $this->setProperty('LinkColour', '217A28'); $levels = $this->setProperty('TocLevels', '2'); $exclude = $this->setProperty('Exclude', array()); if (!is_array($exclude)) $exclude = split('\\s*,\\s*',$exclude);
# Select articles from members if a category or links in content if not $articles = array(); $title = $article->getTitle(); $opt = ParserOptions::newFromUser($wgUser); if ($title->getNamespace() == NS_CATEGORY) { $cat = $title->getDBkey(); $db = &wfGetDB(DB_SLAVE); $cl = $db->tableName('categorylinks'); $result = $db->query("SELECT cl_from FROM $cl WHERE cl_to = '$cat' ORDER BY cl_sortkey"); if ($result instanceof ResultWrapper) $result = $result->result; while ($row = $db->fetchRow($result)) $articles[] = Title::newFromID($row[0]); } else { $text = $article->fetchContent(); $text = $wgParser->preprocess($text,$title,$opt); if (preg_match_all('/^\\*\\s*\\[{2}\\s*([^\\|\\]]+)\\s*.*?\\]{2}/m',$text,$links)) foreach ($links[1] as $link) $articles[] = Title::newFromText($link); }
# Format the article's as a single HTML document with absolute URL's $book = $title->getText(); $html = ; $wgArticlePath = $wgServer.$wgArticlePath; $wgScriptPath = $wgServer.$wgScriptPath; $wgUploadPath = $wgServer.$wgUploadPath; $wgScript = $wgServer.$wgScript; foreach ($articles as $title) { $ttext = $title->getPrefixedText(); if (!in_array($ttext,$exclude)) { $article = new Article($title); $text = $article->fetchContent(); $text = preg_replace('//s','@@'.'@@$1@@'.'@@',$text); # preserve HTML comments $text .= ; $opt->setEditSection(false); # remove section-edit links $wgOut->setHTMLTitle($ttext); # use this so DISPLAYTITLE magic works $out = $wgParser->parse($text,$title,$opt,true,true); $ttext = $wgOut->getHTMLTitle(); $text = $out->getText(); $text = preg_replace('|(<img[^>]+?src=")(/.+?>)|',"$1$wgServer$2",$text); $text = preg_replace('|@{4}([^@]+?)@{4}|s',,$text); # HTML comments hack $text = preg_replace('|<table|','<table border borderwidth=2 cellpadding=3 cellspacing=0',$text); $ttext = basename($ttext);
$html .= utf8_decode("
$ttext
$text\n");
} }
# If format=html in query-string, return html content directly if (isset($_REQUEST['format']) && $_REQUEST['format'] == 'html') { $wgOut->disable(); header("Content-Type: text/html"); header("Content-Disposition: attachment; filename=\"$book.html\""); print $html; } else { # Write the HTML to a tmp file $file = "$wgUploadDirectory/".uniqid('pdf-book'); $fh = fopen($file,'w+'); fwrite($fh,$html); fclose($fh);
# Send the file to the client via htmldoc converter $wgOut->disable(); header("Content-Type: application/pdf"); header("Content-Disposition: attachment; filename=\"$book.pdf\""); $cmd = "--left $left --right $right --top $top --bottom $bottom"; $cmd .= " --header ... --footer .1. --headfootsize 8 --quiet --jpeg --color"; $cmd .= " --bodyfont $font --fontsize $size --linkstyle plain --linkcolor $links"; $cmd .= " --toclevels $levels --format pdf14 --numbered $layout"; $cmd = "htmldoc -t pdf --charset iso-8859-1 $cmd $file"; putenv("HTMLDOC_NOCGI=1"); passthru($cmd); @unlink($file); } return false; }
return true; }
# Return a property for htmldoc using global, request or passed default function setProperty($name,$default) { if (isset($_REQUEST["pdf$name"])) return $_REQUEST["pdf$name"]; if (isset($GLOBALS["wgPdfBook$name"])) return $GLOBALS["wgPdfBook$name"]; return $default; }
# Needed in some versions to prevent Special:Version from breaking function __toString() { return 'PdfBook'; } }
- Called from $wgExtensionFunctions array when initialising extensions
function wfSetupPdfBook() { global $wgPdfBook; $wgPdfBook = new PdfBook(); }
- Needed in MediaWiki >1.8.0 for magic word hooks to work properly
function wfPdfBookLanguageGetMagic(&$magicWords,$langCode = 0) { global $wgPdfBookMagic; $magicWords[$wgPdfBookMagic] = array(0,$wgPdfBookMagic); return true; }