From eefdee2781943deedcd03faaa6dfa85b05498d73 Mon Sep 17 00:00:00 2001 From: Richard Quadling Date: Fri, 18 Feb 2011 11:47:44 +0000 Subject: [PATCH] New format EnhancedCHM - This format is the same as the CHM format but that it also includes usernotes. Tested with the normal stylesheet as well as the new stylesheets (reset.css, theme.css and doc.css). As the usernotes are compressed using BZip2, you will need bzip2.exe to decompress the file from php.net The source from http://bzip.org/downloads.html compiled very easily using MSVC++2008 Express Edition, though the manifest file isn't packed into the binary (I have a patch for that). Resultant CHM file is 26MB rather than 10MB. --- package_php.xml | 2 + phpdotnet/phd/Package/PHP/CHM.php | 8 +- phpdotnet/phd/Package/PHP/EnhancedCHM.php | 173 ++++++++++++++++++++++ phpdotnet/phd/Package/PHP/Factory.php | 1 + 4 files changed, 180 insertions(+), 4 deletions(-) create mode 100644 phpdotnet/phd/Package/PHP/EnhancedCHM.php diff --git a/package_php.xml b/package_php.xml index 59c3292..a664581 100644 --- a/package_php.xml +++ b/package_php.xml @@ -44,6 +44,7 @@ Prepare CHM rendering to use the new CSS rules (Richard Quadling) Disply a message when loading an external stylesheet (Richard Quadling) Incorporate stylesheet names supplied at the command line into the CHM file (Richard Quadling) + New output format EnhancedCHM - the same as CHM but with the User Notes (Requires bzip2.exe) (Richard Quadling) @@ -67,6 +68,7 @@ + diff --git a/phpdotnet/phd/Package/PHP/CHM.php b/phpdotnet/phd/Package/PHP/CHM.php index 33b694a..44e9b48 100644 --- a/phpdotnet/phd/Package/PHP/CHM.php +++ b/phpdotnet/phd/Package/PHP/CHM.php @@ -199,7 +199,7 @@ class Package_PHP_CHM extends Package_PHP_ChunkedXHTML public function __construct() { parent::__construct(); - $this->registerFormatName("PHP-CHM"); + $this->registerFormatName("PHP-CHM"); } public function __destruct() { @@ -247,7 +247,7 @@ class Package_PHP_CHM extends Package_PHP_ChunkedXHTML $stylesheet = $this->fetchStylesheet() . PHP_EOL; } - file_put_contents($this->outputdir . "style.css", $stylesheet . 'body { padding : 3px;}'); + file_put_contents($this->outputdir . "style.css", $stylesheet . 'body {padding : 3px;}' . PHP_EOL . '#usernotes {margin-left : inherit;}' . PHP_EOL); self::headerChm(); break; @@ -402,12 +402,12 @@ res' . DIRECTORY_SEPARATOR . 'style.css $header = parent::header($id); $patterns = array( - '/(.*)(\r|\n|\r\n|\n\r)(.*)<\/head>/', // Add CSS link to + '/(.*)(\r|\n|\r\n|\n\r)(.*)<\/head>/', // Add CSS link and to . '/($2$3', + '$1 $2 $2$3', '$1 class="docs"', ); diff --git a/phpdotnet/phd/Package/PHP/EnhancedCHM.php b/phpdotnet/phd/Package/PHP/EnhancedCHM.php new file mode 100644 index 0000000..0ed2e9b --- /dev/null +++ b/phpdotnet/phd/Package/PHP/EnhancedCHM.php @@ -0,0 +1,173 @@ +registerFormatName("PHP-EnhancedCHM"); + } + + public function update($event, $val = null) { + switch($event) { + case Render::INIT: + parent::update($event, $val); + + // Get http://www.php.net/backend/notes/all.bz2 and save it. + v('Downloading usernotes.', VERBOSE_MESSAGES); + if (false === ($userNotesArchive = file_get_contents('http://www.php.net/backend/notes/all.bz2'))) { + v('Failed to download usernotes.', E_USER_ERROR); + break; + } + + // Save the usernotes. + v('Saving usernotes.', VERBOSE_MESSAGES); + if (false === file_put_contents(Config::output_dir() . 'all.bz2', $userNotesArchive)) { + v('Failed to save usernotes.', E_USER_ERROR); + break; + } + + // Decompress the usernotes. + v('Decompressing usernotes.', VERBOSE_MESSAGES); + if (false === strpos(exec('bzip2.exe -dfkv ' . Config::output_dir() . 'all.bz2 2>&1'), 'all.bz2: done')) { + v('Failed to decompress usernotes.' . PHP_EOL . implode(PHP_EOL, $output), E_USER_ERROR); + break; + } + + // Extract the usernotes and store them by page and date. + v('Preparing usernotes.', VERBOSE_MESSAGES); + + // Create usernotes directory. + $this->userNotesDir = Config::output_dir() . 'usernotes' . DIRECTORY_SEPARATOR; + if(!file_exists($this->userNotesDir) || is_file($this->userNotesDir)) { + mkdir($this->userNotesDir) or v("Can't create the usernotes directory", E_USER_ERROR); + } + + // Remove any existing files. + foreach(glob($this->userNotesDir . '*' . DIRECTORY_SEPARATOR . '*') as $sectionFile) { + unlink($sectionFile); + } + + // Decompress the 'all' file into single files - one file per sectionid. + $userNotesFile = fopen(Config::output_dir() . 'all', 'rt'); + while($userNotesFile && !feof($userNotesFile) && false !== ($userNote = fgetcsv($userNotesFile, 0, '|'))) { + // Usernote index + // 0 = Note ID + // 1 = Section ID + // 2 = Rate + // 3 = Timestamp + // 4 = User + // 5 = Note + + $sectionHash = md5($userNote[1]); + $sectionDir = $this->userNotesDir . $sectionHash[0]; + + if (!file_exists($sectionDir)) { + mkdir($sectionDir); + } + + file_put_contents($sectionDir . DIRECTORY_SEPARATOR . $sectionHash, implode('|', $userNote) . PHP_EOL, FILE_APPEND); + } + + fclose($userNotesFile); + + $this->haveNotes = true; + v('Usernotes prepared.', VERBOSE_MESSAGES); + + // Use classes rather than colors. + ini_set('highlight.comment', 'comment'); + ini_set('highlight.default', 'default'); + ini_set('highlight.keyword', 'keyword'); + ini_set('highlight.string', 'string'); + ini_set('highlight.html', 'html'); + + break; + + default: + parent::update($event, $val); + } + } + + public function footer($id) { + $footer = parent::footer($id); + + // Find usernotes file. + $idHash = md5($id); + $userNotesFile = $this->userNotesDir . $idHash[0] . DIRECTORY_SEPARATOR . $idHash; + + if (!file_exists($userNotesFile)) { + $notes = '
There are no user contributed notes for this page.
'; + } else { + $notes = ''; + + foreach(file($userNotesFile) as $userNote) { + list($noteId, $noteSection, $noteRate, $noteTimestamp, $noteUser, $noteText) = explode('|', $userNote); + + if ($noteUser) { + $noteUser = '' . htmlspecialchars($noteUser) . ''; + } + $noteDate = '' . date("d-M-Y h:i", $noteTimestamp) . ''; + $anchor = ''; + + $noteText = str_replace( + array( + ' ', + '
', + '', + "\n ", + ' ', + ' ' + ), + array( + ' ', + "
\n", + '', + "\n ", + '  ', + '  ' + ), + preg_replace( + '!((mailto:|(http|ftp|nntp|news):\/\/).*?)(\s|<|\)|"|\\\\|\'|$)!', + '\1\4', + highlight_string(trim(base64_decode($noteText)), true)) + ); + + $notes .= <<< END_NOTE + {$anchor} +
+ {$noteUser} + {$noteDate} +
+
+{$noteText} +
+
+
+
+ +END_NOTE; + } + + $notes = '
' . $notes . '
'; + } + + return <<< USER_NOTES +
+
+

User Contributed Notes

+
+{$notes} +
+{$footer} +USER_NOTES; + + } +} diff --git a/phpdotnet/phd/Package/PHP/Factory.php b/phpdotnet/phd/Package/PHP/Factory.php index 58e2120..67857b6 100644 --- a/phpdotnet/phd/Package/PHP/Factory.php +++ b/phpdotnet/phd/Package/PHP/Factory.php @@ -15,6 +15,7 @@ class Package_PHP_Factory extends Format_Factory { 'chm' => 'Package_PHP_CHM', 'tocfeed' => 'Package_PHP_TocFeed', 'epub' => 'Package_PHP_Epub', + 'enhancedchm' => 'Package_PHP_EnhancedCHM', ); public function __construct() {