Click here to Skip to main content
15,881,172 members
Articles / Programming Languages / C#
Article

CHM Snatcher

Rate me:
Please Sign up or sign in to vote.
4.33/5 (5 votes)
12 Feb 2008CPOL7 min read 59.3K   1.1K   36   7
A way of mass-converting online content to CHM files for effectively delivering user help&manual, sharing company knowledge base and distributing any sort of documentation.

CHMSnatcherSampleImage.jpg

Introduction

This article presents one of the possibly fastest and most reliable ways of mass-converting almost any online content to the CHM format. The conversion is designed to be as automatic and cost-efficient as possible. Although the process described in this article is focused on the following products:

it, possibly, can be adjusted to any products applicable (f.e. DokuWiki as the online content authoring).

To orchestrate cooperation between the following three layers (and save our precious time), the CHM Snatcher, a custom built command-line tool has been created.

Why Convert to CHM Format?

Despite its enormous advantages, every online system (like company/hobby Wiki) has its limitations and complexity:

  • it requires a HTTP server,
  • a database server,
  • a server-side language interpreter/compiler (f.e. PHP, C#/ASP.NET), and
  • a connection to the Internet or to the intranet.

If someone wants to access to the content just to find some information, but, for some reason, he/she doesn't have the possibility to connect to the system (f.e. due to access restrictions, high server load), a problem emerges.

Before we Start

Several things are required to start working with CHM Snatcher:

The Solution Outline

The following diagram represents the general idea:

CHMSnatcherProcess.png

  • First, users edit the online content, so that the content is made available to be saved offline,
  • Then, the CHMSnatcher XML configuration file is being configured (please read the next section for details),
  • Then, CHMSnatcher command line utility is run in the pre-process mode:
    • iMacros macro file is generated,
    • HTML Project files are generated.
  • Then, user starts the Mozilla Firefox and, in iMacros add-on, selects the macro generated in the previous step, then runs it. The macro physically retrieves (processes) the URL targets (which can take a while).
  • Then, CHMSnatcher command line utility is run in the post-process mode:
    • appropriate replacements in the downloaded content is being made (f.e. a proper *.css file is replaced with another one),
    • CHM file is generated (by using the Microsoft HTML Help Workshop).

See that CHM Snatcher doesn't:

  • retrieve the web pages — it just generates a macro that is responsible for the retrieval (more precisely, the macro that is run by Mozilla Firefox, iMacros add-on),
  • generate the CHM files — again, it just generates necessary HTML Help Workshop project files that are compiled to CHM file by HTML Help Workshop.

Putting it all together: CHM Snatcher is just a "man in the middle," reducing user's effort, coordinating various tools.

CHM Snatcher Overview

As stated above, CHM Snatcher is a command line utility. Currently, it supports only two commands:

CHMSnatcher.exe preProcess [path to XML configuration file]
CHMSnatcher.exe postProcess [path to XML configuration file]

Every of the two commands require a XML configuration file. Here comes an example with a more detailed description:

XML
<snatchProject>
 <snatchExpression value="http://en.wikipedia.org/wiki/{0}?printable=yes" />
 <outputFolder value="C:\Temp\VintageGameSystems" />
 <helpProjectName value="Vintage Game Systems" />
 <iMacrosScriptFileName
value="C:\Documents and Settings\Profile\My Documents\iMacros\Macros\VintageGamesSystems.iim" />
 <pages>
  <page urlName="Video_game_system" title="Video game system - overview" />
   <page urlName="" title="Nintendo">
   <page urlName="Nintendo" title="Nintendo - Company Info" />
   <page urlName="NES" title="NES" />
   <page urlName="SNES" title="SNES" />
   <page urlName="Nintendo_64" title="Nintendo 64" />
  </page>
 </pages>
 <postProcessing>
  <replaceAll searchedFile="commonPrint.css" replacementFile="Replacements\commonPrint.css" />
  <compile pathToHTMLHelpWorkshop="C:\Program Files\HTML Help Workshop" />
 </postProcessing>
</snatchProject>
  • The snatchExpression tag is used to configure the way the CHM Snatcher will create an URL for every retrieved page (see the pages tag) — f.e. here we want to retrieve pages in printable version. Note that {0} parameter is mandatory — it will be replaced with page.@urlName attribute for every page.
  • The outputFolder tag decides:
    • where the Microsoft HTML Help Workshop project files will be generated,
    • where the HTML page files, retrieved by Mozilla Firefox iMacros, will be saved to (note that it will be saved in the Pages subfolder of the outputFolder.@value)
  • The helpProjectName tag describes the name of the help project, it will influence:
    • the *.hhp, *.hhc and *.chm file names,
    • CHM document name (displayed in the generated document title bar).
  • The iMacrosScriptFileName denotes the place, where the *.iim macro file will be generated. It is recommended to set it to the same directory where the Mozilla Firefox iMacros add-on looks for macros — please note that the path will certainly differ on your system.
  • The pages tag encapsulates the pages in a tree hierarchy, exactly the way these will be represented in the document tree of the CHM file.
  • The page.@urlName attribute represents a fragment of the URL for a page, that will be glued together with snatchExpression.@value attribute. page.@title attribute represents a page title as it will be displayed in the left-side CHM document tree of the generated CHM file. Please note that page.@urlName can be left empty.
  • The postProcessing tag encapulates actions that will be done AFTER user retrieved that pages with Mozilla Firefox iMacros add-on.
    • The replaceAll tag denotes file replacement action: all replaceAll.@searchedFile files that are found in the outputFolder.@value folder will be replaced by replaceAll.@replacementFile file. Why do we need replacements? In the example presented the Wikipedia printable pages contain no margins, which is good for printing, but looks clumsy in the CHM file. Thus, every *.css file that was downloaded will be replaced by a custom *.css file.
    • The compile tag represents the compile action. To make it run successfully, the compile.@pathToHTMLHelpWorkshop attribute must be set properly. Please note that CHM Snatcher assumes the *.hhp file will be [helpProjectName.@value].hpp.

The following table describes what tags/attributes in tags are mandatory.

XML entity nameMandatory
snatchExpression.@valueyes
outputFolder.@valueyes
helpProjectName.@valueyes
iMacrosScriptFileName.@valueyes
page.@urlNameyes
page.@titleyes
replaceAllno
compileno

Using the Code

The source code submitted to the CodeProject is quite straightforward: it contains some manipulation on XML documents and a lot of file content generation (File and StringBuilder core Framework classes are used the most extensively). The interesting places at a glance:

  • CHMSnatcher.PreProcessor.FillTreeOfPages() and CHMSnatcher.PreProcessor.FillListOfPages() methods use recursion to build/analyze the tree of pages,
  • CHMSnatcher.PreProcessor.GenerateHppProject() and CHMSnatcher.PreProcessor.GenerateHppTableOfContents() methods generate HTML Help Workshop files — no third-party library was required to do the job, since HTML Help Workshop files are just pain text files with unsophisticated structure (see it yourself).

Points of Interest

I think some things can be done even better:

  • There can be a convenient GUI added on top of the engine.
  • Saving the web pages offline could be embedded into CHM Snatcher (by a third party library) or, which should be even simpler, made by a command-line tool. Unfortunately, some tools like HTTrack didn't work well for me (the save results were far from perfect — there were missing images, css files etc.). But, maybe you know an offline grabber that would the job ?
  • Post processing plug-ins/scripts can be useful (f.e. imagine replacing some tags in the retrieved *.html files — read a note below).

Note that CHM Snatcher can be used to archive probably most of the CodeProject pages. However, a little problem emerges with the downloaded offline page versions. Namely, some JavaScript scripts that are embedded inside the downloaded HTML files make the CHM document display nasty JavaScript error dialogs, which is, of course, unacceptable. One of the ways to overcome it is to replace <script ... </script> tags in the downloaded HTML documents with the following <!-- script .... </script -->. Nevertheless, such post-processing task has not been not implemented so far, so, feel free extending !

To the Readers

I hope you liked the article and found it useful. However, if you think otherwise and want to express it by rating, please leave a comment why you think this article deserves a particular, low grade. I think uncommented low grades are definitely not the way to go — please help to improve!

Anyway, thanks for reading !

History

  • 2th of February 2008 - First version created.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Poland Poland
Tomasz Szatkowski is a software developer working in the city of Gdynia, Tricity, northern Poland.

He is interested in pursuing ever evolving technology and applying it to everyday problems.

His most recent interest focus on Flex GUI interfaces, Microsoft WCF, middleware, SaaS model in software delivery.

Comments and Discussions

 
QuestionJust right but unclear Pin
Member 1354994430-Nov-17 4:20
Member 1354994430-Nov-17 4:20 
QuestionWorks well Pin
Member 115058687-Mar-15 2:58
Member 115058687-Mar-15 2:58 
GeneralHas some good potential Pin
scrawny3-Sep-14 21:49
scrawny3-Sep-14 21:49 
GeneralMy vote of 1 Pin
John Carmack16-Oct-11 6:56
John Carmack16-Oct-11 6:56 
GeneralMediawiki on the intranet Pin
Poonamol30-Jun-08 1:28
Poonamol30-Jun-08 1:28 
GeneralUpdate pending [modified] Pin
TSzatkowski14-Feb-08 21:59
TSzatkowski14-Feb-08 21:59 
GeneralInteresting idea - It doesn't work for me [modified] Pin
Steve Messer12-Feb-08 6:48
Steve Messer12-Feb-08 6:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.