Hierbei geht es um Tipps und Tricks bei der Erstellung von CHM-Dateien, so 'ne Art geziptes HTML, funktioniert ab Windows 98 bis heute. Unter Linux sind einige geeignete Betrachter verfügbar. Leider (oder zum Glück?) ist die Browser-Fähigkeit begrenzt, in etwa auf Internet Explorer 7.
Die bekannten Einschränkungen:
CHM wird ab Windows 98 durchgängig unterstützt, ist also quasi gemeinsam mit USB verfügbar. Die alte RTF-basierte Hilfe ist ab Vista nicht mehr da und muss extra installiert werden.
Auf der Wunschliste steht ja zumeist:
Siehe auch http://chmspec.nongnu.org/
[OPTIONS] Binary TOC=Yes Compiled file=gwbasic.chm Default Window=main Contents file=gwbasic.hhc Index file=gwbasic.hhk Default topic=default.html Full-text search=Yes Language=0x409 Englisch (USA) Title=GW-BASIC User's Guide [WINDOWS] main=,"gwbasic.hhc","gwbasic.hhk","default.html","default.html",,,,,0x62520,,0x70384E,,,,,,,,0 popup=,,,,,,,,,0,,0x80,,,,,,,, [FILES] gwbasic.hhp chapter1.html …Die Angaben bei main generieren alle erdenklichen (sinnvollen!) Extra-Knöpfe, nämlich Browse-Buttons, History zurück und vorwärts, Rückwärtssuche sowie Einstellen der Schriftgröße.
Das 0x80 bei popup generiert ein ToolWindow mit schmaler Titelzeile.
Wichtig zu wissen:
<HTML><HEAD><!-- Sitemap 1.0 --></HEAD><BODY><UL> <LI><OBJECT type="text/sitemap"><param name="Name" value="Chapters"><param name="Local" value="default.html"></OBJECT> <UL> <li><object type="text/sitemap"><param name="Name" value="1. Welcome"><param name="Local" value="Chapter1.html"></object> … </UL> <LI><OBJECT type="text/sitemap"><param name="Name" value="Appendicies"></OBJECT> <UL> <li><object type="text/sitemap"><param name="Name" value="A. Error Codes and Messages"><param name="Local" value="AppendixA.html"></object> </UL> <li><object type="text/sitemap"><param name="Name" value="Glossary"><param name="Local" value="Glossary.html#1"><param name="New" value="1"></object> </UL></BODY></HTML>Nicht jeder Knoten muss eine dahinter stehende URL haben. Leider gibt's da keinen Automatismus, mit dem Windows bspw. ein anderes Icon benutzt.
Alles in allem ziemlich geschwätzig; ein Texteditor mit regulären Ausdrücken und Wortersetzung ist hier zweckmäßig. Es kommt der Eindruck auf, das Microsoft die Programmierer quälen möchte. Eine simple ASCII-Datei mit verschiedenen Einrücktiefen und gewöhnlichen HTML-Links hätte es ja auch getan.
Hochkommas kann man weglassen, wo kein Leerzeichen eingeschlossen ist.
Wichtig zu wissen:
<OBJECT type="text/site properties"><param name="ImageType" value="Folder"></OBJECT>direkt nach
<BODY>
, aber eben nur bei ausgeschaltetem „Binary TOC“!
Andere Features sind ImageList
mit Image Width
. #
-Ankern.
<HTML><HEAD><!-- Sitemap 1.0 --></HEAD><BODY><UL> <li><object type="text/sitemap"><param name="Name" value="ABS"><param name="Local" value="ABS.html"></object> <li><object type="text/sitemap"><param name="Name" value="ASC"><param name="Local" value="ASC.html"></object> … </UL></BODY></HTML>Auch hier wieder viel Blabla. Reguläre Ausdrücke helfen, eine Wortliste entsprechend umzuformen.
Wichtig zu wissen:
<title>
-Tag
[Options] Title=
)
<META HTTP-EQUIV="Content-Type" content="text/html; charset=utf-8">
.
Um sicher zu gehen, dass UTF-8 benutzt wird,
genügt eine BOM.
<link rel=stylesheet href="cs.css">
<script src="js.js"></script>
falls erforderlich
<title>Titel</title>
.
Er wird bei .CHM schlichtweg nicht verwendet,
außer die Seite ist nicht im Inhaltsverzeichnis (*.hhc).
Dann und nur dann wird dieser im Index (*.hhk) oder bei der Ergebnisliste der Volltextsuche angezeigt.
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e"> <param name="New HTML file" value="USB-Funktionen.htm"> <param name="New HTML title" value="USB-Funktionen"> </object>
Die Angabe „HTML-Titel“ kann man sich sparen, wenn die HTML-Seite im Inhaltsverzeichnis erscheint; jener Titel wird immer dann verwendet, etwa bei der Auflösung von Mehrfachreferenzen im Index.
Unbedingt einen <body>
-Tag ganz am Anfang einbauen!
Sonst stürzt der Hilfe-Compiler ab.
Weiteres HTML-Gesülz wird nicht benötigt.
Zersägte Dateien klein halten:<style …
(und <body>
) unterbringen
<br clear=all style='page-break-before:always'>davor.
Die Links im Inhaltsverzeichnis und Index müssen sich auf die zersägten Dateinamen beziehen!
Womöglich kann man sogar Inhaltsverzeichnis und Index mit hineinstecken.
Hierzu muss man in der Registrierung einen Eintrag vornehmen. Für den Aufruf aus einer selbst geschriebenen Echse heraus muss dessen Name anstatt hh.exe stehen.
Windows Registry Editor Version 5.00 [HKEY_USERS\S-1-5-21-1559349094-3728892266-3505865260-1007\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION] "hh.exe"=dword:00002710 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION] "hh.exe"=dword:00002710Dieses Manko hat MS Help 2 (*.HxS) zwar nicht, aber hier sind die übrigen Probleme noch größer.
Von einem vorhergehenden Projekt kann man einfach die HHP-Datei kopieren und die Strings entsprechend anpassen.
Die [Files]-Sektion kann leer bleiben, da alle abhängigen Dateien automatisch hineingepackt werden. Nur die HHP-Datei wird als einzige nicht hineingesteckt (siehe nächster Tipp), da diese in compilierter Form in der „#SYSTEM“-Datei vorliegt.
Da die Total-Commander-Packer-Erweiterung ChmDir den bequemen Zugriff auf den Inhalt einer .CHM-Datei erlaubt, ist es zweckmäßig, bei [Files] auch die *.hhp-Datei hineinzustecken. So hat man jederzeit die komplette Quelle verfügbar, ohne dafür ein extra Verzeichnis herumschleppen zu müssen.
Das beißt sich allerdings mit der Möglichkeit, HTML-Dateien zu zersägen.
Die gleiche Funktionalität bietet 7zip im Windows-Explorer. Leider sind die Datumsangaben der Dateien futsch. Die üblichen Auspack-Programme setzen diese auf das Datum der CHM-Datei.
Unverständlich erscheint es, dass der Hilfe-Compiler die Inhalts- und Indexdateien (HHC und HHK) mit hineinsteckt, obwohl diese, bei aktiviertem Binary TOC, bereits in versteckten Binärdateien hineincompiliert sind. Man muss diese ggf. nachträglich mit dem Total-Commander-Tool herauslöschen.
Ist nunmehr als Teil meiner universellen h.js realisiert. Zeilen 308 … 466, also gar nicht übermäßig viel.
Manch einem trifft gewisses Unbehagen, CHM-Dateien zu erstellen, weil man für's Web alles noch einmal machen müsste. Kann man nicht CHM-Dateien im beliebigen Web-Browser darstellen?
Dies ist mittels viewchm.php und dem auf chmlib aufsetzenden unchm.c bei mir gelöst. Noch unfertig, keine Volltextsuche, und die Browse-Buttons funktionieren nicht. Hier ein (anderes) Beispiel. Die PHP-Datei benötigt derzeit Shell-Aufrufe und ist für hochsichere Server und kostenlose Webspaceanbieter nicht geeignet.
Da die typische CHM-Darstellung einer Frame-Aufteilung am besten nahekommt, ist es hier auch so implementiert. Das ist zweifelsohne Smartphone-inkompatibel. Eine gesonderte Smartphone-Unterstützung — erfordert eine völlig andere Präsentations-Struktur womöglich mit einem iframe für Inhalts- und Stichwortverzeichnis.
Manchmal will oder muss man HTML-Seiten erstellen, die sich in CHM-Umgebung anders verhalten sollen als bspw. mit dem vorangegangenen viewchm.php. Ganz einfach: Die URL einer CHM-Datei enthält stets zwei Doppelpunkte hintereinander, was auf einem Webserver sicherlich nie vorkommt.
var inside_chm = location.href.indexOf("::") >= 0;
Für das Erstellen einer Dokumentation ist es sehr nützlich, irrelevante Informationen automatisch ausblenden zu lassen. Beispiele:
Die Vorgehensweise ist, in die betreffenden Seiten ein <iframe>
mit einer immer gleichen Webseite einzubauen.
Da Cookies nicht funktionieren, speichert dieses iframe
seinen Zustand
in parent.name
!
Dadurch ist der Zustand leider nicht persistent
zwischen dem Schließen und erneutem Öffnen der CHM-Datei.
Nur damit viewchm.php nicht mit dem wechselnden Namen des rechten Frame-Fensters
durcheinanderkommt, besser mit Fallunterscheitung:
// Lesen: val = inside_chm ? parent.name : document.cookie; // Schreiben: if (inside_chm) parent.name = val; else document.cookie = val;
Und hier ein praktisches Beispiel.
Das geht nicht ohne Verrenkungen. Entweder eine (nur eine) externe HTML-Datei, damit Cookies funktionieren. Die passende URL beschaffen. Oder irgendwas mit ActiveX und Dateizugriff (muss ich noch mal finden).
Es ist natürlich mühselig, für jede einzelne Webseite das iframe
einzubinden.
Da jede Seite ohnehin einen Bezug zur global.css
und global.js
braucht,
kann das Javascript dieses iframe
dynamisch generieren.
Weiterhin ist es nützlich, für verschiedene Browser und verschiedene Größen von Eingabeelementen
das iframe
genau passend zu machen.
Da dies window.getComputedStyle
erfordert,
geht das nur mit neueren Browsern, also bspw. mit viewchm.php und aktuellem Browser.
if (window.getComputedStyle) { var cs = window.getComputedStyle(sel); // sel = Eine Combobox; Firefox liefert Höhe = "21px" var fr = parent.document.getElementsByTagName("iframe")[0]; fr.style.width = cs.width; fr.style.height = cs.height; // Größe anpassen fr.style.right = 0; fr.style.top = 0; // in die obere rechte Ecke platzieren (das <iframe> hat CSS position:fixed) }