MS Help - hhc fails on compiling an HTML file while building .chm - chm

I'm converting a WinHelp to html help using HTML Workshop and HHMod but there are some errors. Some files have been discarded, I'm guessing because the titles were duplicates (although the keys were different). But for this problem: .hhp wants a default file so I created a "html/empty.htm" by copying an existing (and valid) .htm file. This is a placeholder for items in the index that are just books to open. However, when trying to build the .chm, I get:
HHC5003: Error: Compilation failed while compiling empty.htm
The other 3000+ files compile just fine but they were created by the tools. Here is the .htm file that I created by hand:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=Windows-1252">
<TITLE>CIS Help</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<OBJECT TYPE="application/x-oleobject"
CLASSID="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<PARAM NAME="Keyword" VALUE="CIS HELP">
</OBJECT>
<H1><CODE><A NAME="CIS HELP"></A>CIS Help</CODE></H1>
<pre><code>Press the "+" sign to expand the book.
</code></pre>
</BODY>
</HTML>
Here is the snippet in the toc file (.hhc) that refers to this .htm:
<LI><OBJECT type="text/sitemap">
<param name="Name" value="CIS HELP">
<param name="Local" value="html/empty.htm">
</OBJECT>
CIS Help <BR>
(The toc goes on to define a number of UL layers below this.)
It's probably something obvious but I haven't been able to google any references on how to create a valid .htm file for .chm. Please note that I am a newbie to MS although not to programming.

For anyone else who runs into this problem:
Apparently, the stumbling block is using a file as a "default file" - HTML Help seems to automatically use the first file in the list as its default file but if you specify one, it chokes.
The docs I could find say that this happens if the default is used some unknown number, x, of times and that x may == 256. Unfortunately, x is probably a lot smaller since I don't have 256 items with no associated topic.

Related

Angular 9 domSanitazer Not allowed to load resource [duplicate]

It works if the html file is local (on my C drive), but not if the html file is on a server and the image file is local. Why is that?
Any possible workarounds?
It would be a security vulnerability if the client could request local file system files and then use JavaScript to figure out what's in them.
The only way around this is to build an extension in a browser. Firefox extensions and IE extensions can access local resources. Chrome is much more restrictive.
shouldn't you use "file://C:/localfile.jpg" instead of "C:/localfile.jpg"?
Browsers aren't allowed to access the local file system unless you're accessing a local html page. You have to upload the image somewhere. If it's in the same directory as the html file, then you can use <img src="localfile.jpg"/>
C: is not a recognized URI scheme. Try file://c|/... instead.
Honestly the easiest way was to add file hosting to the server.
Open IIS
Add a Virtual Directory under Default Web Site
virtual path will be what you want to browse to in the browser. So if you choose "serverName/images you will be able to browse to it by going to http://serverName/images
Then add the physical path on the C: drive
Add the appropriate permissions to the folder on the C: drive for "NETWORK SERVICE" and "IIS AppPool\DefaultAppPool"
Refresh Default Web Site
And you're done. You can now browse to any image in that folder by navigating to http://yourServerName/whateverYourFolderNameIs/yourImage.jpg and use that url in your img src
Hope this helps someone
we can use javascript's FileReader() and it's readAsDataURL(fileContent) function to show local drive/folder file.
Bind change event to image then call javascript's showpreview function.
Try this -
<!doctype html>
<html>
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=no;'>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
<title></title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
function showpreview(e) {
var reader = new FileReader();
reader.onload = function (e) {
$("#previewImage").attr("src", e.target.result);
}
//Imagepath.files[0] is blob type
reader.readAsDataURL(e.files[0]);
}
</script>
</head>
<body >
<div>
<input type="file" name="fileupload" value="fileupload" id="fileupload" onchange='showpreview(this)'>
</div>
<div>
</div>
<div>
<img width="50%" id="previewImage">
</div>
</body>
</html>
IE 9 : If you want that the user takes a look at image before he posts it to the server :
The user should ADD the website to "trusted Website list".
Newtang's observation about the security rules aside, how are you going to know that anyone who views your page will have the correct images at c:\localfile.jpg? You can't. Even if you think you can, you can't. It presupposes a windows environment, for one thing.
if you use Google chrome browser you can use like this
<img src="E://bulbpro/pic_bulboff.gif" width="150px" height="200px">
But if you use Mozila Firefox the you need to add "file " ex.
<img src="file:E://bulbpro/pic_bulboff.gif" width="150px" height="200px">
starts with file:/// and ends with filename should work:
<img src="file:///C:/Users/91860/Desktop/snow.jpg" alt="Snow" style="width:100%;">
I see two possibilities for what you are trying to do:
You want your webpage, running on a server, to find the file on the computer that you originally designed it?
You want it to fetch it from the pc that is viewing at the page?
Option 1 just doesn't make sense :)
Option 2 would be a security hole, the browser prohibits a web page (served from the web) from loading content on the viewer's machine.
Kyle Hudson told you what you need to do, but that is so basic that I find it hard to believe this is all you want to do.
If you're deploying a local website just for yourself or certain clients, you can get around this by running mklink /D MyImages "C:/MyImages" in the website root directory as an admin in cmd. Then in the html, do <img src="MyImages/whatever.jpg"> and the symbolic link established by mklink will connect the relative src link with the link on your C drive. It solved this issue for me, so it may help others who come to this question.
(Obviously this won't work for public websites since you can't run cmd commands on people's computers easily)
I have tried a lot of techniques and finally found one in C# side and JS Side.
You cannot give a physical path to src attribute but you can give the base64 string as a src to Img tag.
Lets look into the below C# code example.
<asp:Image ID="imgEvid" src="#" runat="server" Height="99px"/>
C# code
if (File.Exists(filepath)
{
byte[] imageArray = System.IO.File.ReadAllBytes(filepath);
string base64ImageRepresentation = Convert.ToBase64String(imageArray);
var val = $"data: image/png; base64,{base64ImageRepresentation}";
imgEvid.Attributes.Add("src", val);
}
Hope this will help
background-image: url(${localImage});
If you want to add a file as background to your website locally.
You need to upload the image aswell, then link to the image on the server.
what about having the image be something selected by the user? Use a input:file tag and then after they select the image, show it on the clientside webpage? That is doable for most things. Right now i am trying to get it working for IE, but as with all microsoft products, it is a cluster fork().

HTML file Tries to Find HTML File in Wrong Location

Somehow my HTML file is trying to locate another separate HTML file in the wrong folder location even when I set the iframe source to the correct location!
I was reorganizing all my files into a new folder but the two files are all in the same folder. I doublechecked that the source file name was correct and the location was correct and I was viewing the correct files and everything, but it still attempted to find a file name that didn't exist in the wrong folder (It previously worked before the reorganization).
I tried everything and the page said: Firefox can't find the file at /E:/Art/Animation & Computing/Website/Programming Files/Backup Files/Drawing-Content.html.
The correct location and file name is: E:\Art\Animation & Computing\Website\Programming Files\Literature.html.
Here is the first file that calls the other file:
<!DOCTYPE html>
<html>
<body>
<header>
<div>
<h1>Literature</h1>
<iframe src="Literature.html" name="targetframe" allowTransparency="true" frameborder="0" width="1000px" height="7000px">
</iframe>
</div>
</header>
</body>
</html>
Here is the second file that is being called:
<p>Here is all the literature content and it should be displayed after the Literature header</p>
<img src="whole-pic-copy.jpg">
Just saying, the entire reason I'm implementing a separate HTML file into an HTML file is because I have long lists of code (this is just a part of the code) and I want to organize it so it is easy to manage. And also, this method worked perfectly before and now it isn't so I just want to focus on trying to debug this. Do I have to clear the history or something, because it seems to remember the past location and name of the file.
Well the file which is missing is Drawing-Content.html but what I suppose since you renamed it to Literature.html the first page (the page that is calling) is cached. So you need to clear the cache in your browser, make sure you saved your files correctly and then reload that page :)
You can do it with jquery as well:
<div id="literature"></div>
<script>
$(function () {
$("#literature).load("includes/literature.html");
});
</script>

open topic in merged chm file in master chm file window

I would like to open topic in merged chm file in master chm file windows.
I have main chm file of application help. So this main chm file includes sub chm file. And I would like to open the topic in sub (merged) chm file in the window of main chm file by calling htmlhelp function.
The following is header file in main chm project.And operation\ACORD_geometry.chm is merged chm file. Now I'm using Adobe robohelp.
[ALIAS]
IDH_operation_geometry=operation\ACORD_geometry.chm:\HID_geometrytab_functions.htm
[MAP]
#define IDH_operation_geometry 9001
And I call htmlhelp function by following way. But The topic don't open. .\help\3DFEMGeo.chm is main chm file.
HtmlHelp(Application.Handle, '.\help\3DFEMGeo.chm', HH_HELP_CONTEXT, 9001);
Please teach me the way to open topic in the sub chm.
Creating modular help systems has some benefits by merging indexes and TOCs of multiple help projects, but overcoming the wall is difficult some times. Some parts of the following instructions have been posted many years ago by Sean Stagmer. For context-sensitive help see also content and links at the bottom:
http://www.help-info.de/en/Help_Info_HTMLHelp/hh_context-id.htm
Long story short (HTH - please try for your needs and environment):
// *** BEGIN CODE SNIPPET
...
HID_TOPIC_ID1="ms-its:Master.chm::/SubHelpSubject1.chm::/Topic_1.htm#Topic1"
HID_TOPIC_ID2="ms-its:Master.chm::/SubHelpSubject2.chm::/Topic_2.htm#Topic2"
...
// *** END CODE SNIPPET
And the stories long version:
RoboHelp e.g. and many other Help Authoring Tools (HAT's) are a IDE front end for utilizing the Microsoft HTML Help compiler (hhw.exe). The designers of RoboHelp's older versions did a pretty good job of separating the technical aspects of building an HTML compiled help file, but left out several features available if you used the underlying tool directly.
Specifically, modular help. I assume that most people who investigated this topic learned about adding the following to their help project file (the .hhp) to begin designing a modular HTML help system:
// *** BEGIN CODE SNIPPET
[MERGE FILES]
SubHelpSubject1.chm
SubHelpSubject2.chm
...
// *** END CODE SNIPPET
Now, tackling the subject of context-sensitive help AND merged files in a modular design adds a new twist: How can the topic ID be mapped to the appropriate merged HTML file? Being modular, the topic ID is not in the master/host help file, but is instead integrated into it through the merged sub-help project's .chm file. This is accomplished by placing the following code in the master/host master's TOC file:
// *** BEGIN CODE SNIPPET
...
<LI>
<OBJECT type="text/sitemap">
<param name="Name" value="SubHelpSubject1">
</OBJECT>
<OBJECT type="text/sitemap">
<param name="Merge" value="SubHelpSubject1.chm::\SubHelpSubject1.hhc">
</OBJECT>
<LI>
<OBJECT type="text/sitemap">
<param name="Name" value="SubHelpSubject2">
</OBJECT>
<OBJECT type="text/sitemap">
<param name="Merge" value="SubHelpSubject2.chm::\SubHelpSubject2.hhc">
</OBJECT>
...
// *** END CODE SNIPPET
With these two additions (the MERGE FILES statement and the addition to the TOC file) the correct resolving of topic id's to their help topic information is complete, EXCEPT that you notice that the HTML help window shows ONLY the TOC for the sub-help project it mapped to! The master/host TOC doesn't show up at all. What gives?
The answer lies in the alias file for the master/host project. Being a good little HTML help content developer, you knew to map the topic id of interest to the appropriate sub-help file by modifying the simple alias syntax like this:
// *** BEGIN CODE SNIPPET
...
HID_TOPIC_ID1=Topic_1.htm
HID_TOPIC_ID2=Topic_2.htm
...
// *** END CODE SNIPPET
...to this:
// *** BEGIN CODE SNIPPET
...
HID_TOPIC_ID1="ms-its:SubHelpSubject1.chm::/Topic_1.htm#Topic1"
HID_TOPIC_ID2="ms-its:SubHelpSubject2.chm::/Topic_2.htm#Topic2"
...
// *** END CODE SNIPPET
That little 'ms-its:' thing is very much like the 'http:' or 'ftp:' text you type into a web browser: it's known as an Asynchronous Pluggable Protocol from Microsoft. The '::/' portion of it is a reference; a kind of 'level of indirection' or 'reference alias' in C++ parlance. So, to solve the problem of having the context-sensitive help topic BOTH map to the correct help topic html text AND keep the TOC synchronized with the master, you must add an additional level of indirection to make it work, as shown below:
// *** BEGIN CODE SNIPPET
...
HID_TOPIC_ID1="ms-its:Master.chm::/SubHelpSubject1.chm::/Topic_1.htm#Topic1"
HID_TOPIC_ID2="ms-its:Master.chm::/SubHelpSubject2.chm::/Topic_2.htm#Topic2"
...
// *** END CODE SNIPPET
This can be read as meaning this: "When displaying the help topic HID_TOPIC_ID1 information, open Master.chm, then navigate to SubHelpSubject1.chm's HTML file Topic_1.htm, then move down the page to the bookmark Topic1."
Hooray! Your topic pops up, and the master/host TOC is visible as well!
Like thinking in C++ terms the alias file looks very much like how we would reference functionality in a C++ class:
Result = BaseClass::SubClass1::Subclass2::DoFunctionCall();
As a side note, this syntax is being replaced by XML - HTML help will reference a 'Collection' as specified in a collection file (.col), which has XML entries in it. Much easier to read and follow than the obtuse PERL-like syntax in the alias file.

Why can't I do <img src="C:/localfile.jpg">?

It works if the html file is local (on my C drive), but not if the html file is on a server and the image file is local. Why is that?
Any possible workarounds?
It would be a security vulnerability if the client could request local file system files and then use JavaScript to figure out what's in them.
The only way around this is to build an extension in a browser. Firefox extensions and IE extensions can access local resources. Chrome is much more restrictive.
shouldn't you use "file://C:/localfile.jpg" instead of "C:/localfile.jpg"?
Browsers aren't allowed to access the local file system unless you're accessing a local html page. You have to upload the image somewhere. If it's in the same directory as the html file, then you can use <img src="localfile.jpg"/>
C: is not a recognized URI scheme. Try file://c|/... instead.
Honestly the easiest way was to add file hosting to the server.
Open IIS
Add a Virtual Directory under Default Web Site
virtual path will be what you want to browse to in the browser. So if you choose "serverName/images you will be able to browse to it by going to http://serverName/images
Then add the physical path on the C: drive
Add the appropriate permissions to the folder on the C: drive for "NETWORK SERVICE" and "IIS AppPool\DefaultAppPool"
Refresh Default Web Site
And you're done. You can now browse to any image in that folder by navigating to http://yourServerName/whateverYourFolderNameIs/yourImage.jpg and use that url in your img src
Hope this helps someone
we can use javascript's FileReader() and it's readAsDataURL(fileContent) function to show local drive/folder file.
Bind change event to image then call javascript's showpreview function.
Try this -
<!doctype html>
<html>
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=no;'>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
<title></title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
function showpreview(e) {
var reader = new FileReader();
reader.onload = function (e) {
$("#previewImage").attr("src", e.target.result);
}
//Imagepath.files[0] is blob type
reader.readAsDataURL(e.files[0]);
}
</script>
</head>
<body >
<div>
<input type="file" name="fileupload" value="fileupload" id="fileupload" onchange='showpreview(this)'>
</div>
<div>
</div>
<div>
<img width="50%" id="previewImage">
</div>
</body>
</html>
IE 9 : If you want that the user takes a look at image before he posts it to the server :
The user should ADD the website to "trusted Website list".
Newtang's observation about the security rules aside, how are you going to know that anyone who views your page will have the correct images at c:\localfile.jpg? You can't. Even if you think you can, you can't. It presupposes a windows environment, for one thing.
if you use Google chrome browser you can use like this
<img src="E://bulbpro/pic_bulboff.gif" width="150px" height="200px">
But if you use Mozila Firefox the you need to add "file " ex.
<img src="file:E://bulbpro/pic_bulboff.gif" width="150px" height="200px">
starts with file:/// and ends with filename should work:
<img src="file:///C:/Users/91860/Desktop/snow.jpg" alt="Snow" style="width:100%;">
I see two possibilities for what you are trying to do:
You want your webpage, running on a server, to find the file on the computer that you originally designed it?
You want it to fetch it from the pc that is viewing at the page?
Option 1 just doesn't make sense :)
Option 2 would be a security hole, the browser prohibits a web page (served from the web) from loading content on the viewer's machine.
Kyle Hudson told you what you need to do, but that is so basic that I find it hard to believe this is all you want to do.
If you're deploying a local website just for yourself or certain clients, you can get around this by running mklink /D MyImages "C:/MyImages" in the website root directory as an admin in cmd. Then in the html, do <img src="MyImages/whatever.jpg"> and the symbolic link established by mklink will connect the relative src link with the link on your C drive. It solved this issue for me, so it may help others who come to this question.
(Obviously this won't work for public websites since you can't run cmd commands on people's computers easily)
I have tried a lot of techniques and finally found one in C# side and JS Side.
You cannot give a physical path to src attribute but you can give the base64 string as a src to Img tag.
Lets look into the below C# code example.
<asp:Image ID="imgEvid" src="#" runat="server" Height="99px"/>
C# code
if (File.Exists(filepath)
{
byte[] imageArray = System.IO.File.ReadAllBytes(filepath);
string base64ImageRepresentation = Convert.ToBase64String(imageArray);
var val = $"data: image/png; base64,{base64ImageRepresentation}";
imgEvid.Attributes.Add("src", val);
}
Hope this will help
background-image: url(${localImage});
If you want to add a file as background to your website locally.
You need to upload the image aswell, then link to the image on the server.
what about having the image be something selected by the user? Use a input:file tag and then after they select the image, show it on the clientside webpage? That is doable for most things. Right now i am trying to get it working for IE, but as with all microsoft products, it is a cluster fork().

How can I use templates to generate static web pages?

I want to add one HTML file into another.
For example: I have header.html and footer.html
Now I am trying to create aboutus.html where I want to add these two HTML files
there is no dynamic code in these file except JavaScript.
How can I do this without using any scripting language except JavaScript and CSS?
Server Side Includes (SSI) exist for this particular functionality. However, you need to have the server configured for such includes. Apache supports it. Not sure about other web servers.
or Server Side Includes (SSI), all embedding is done there on the server side...
In the case of web sites with no dynamic content but have common elements, I generate the final pages on my development machine using Perl's Template Toolkit and upload the resulting static HTML files to the server. Works beautifully.
For example:
header.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
<title>[% title %]</title>
<link rel="stylesheet" href="/site.css" type="text/css">
<meta name="description" content="[% description %]">
<meta name="keywords" content="[% keywords.join(',') %]">
</head>
<body>
<div id="banner">
<p>Banner</p>
</div>
footer.html
<address>
Last update:
[%- USE date -%]
[%- date.format(date.now, '%Y-%m-%d %H:%M:%S') -%]
</address>
</body>
</html>
aboutus.html
[%- INCLUDE header.tt.html
title = 'About Us'
description = 'What we do, how we do it etc.'
keywords = 'rock, paper, scissors'
-%]
<h1>About us</h1>
<p>We are nice people.</p>
You can now use tpage or ttree to build your pages.
The only way to do this on the client side without javascript is to use frames or iframes. If you want to use javascript, you can use AJAX. Most javascript frameworks provide corresponding convenience methods (e.g. jQuery's load function).
Obviously there are many server side solutions, including the popular SSI extension for apache (see other posts).
I'm not entirely sure what it is you want but an entirely client side method of doing it would be to embed them with the <object> tag.
<html>
<head>
<title>About Us</title>
</head>
<body>
<object data="header.html"><!--Something to display if the object tag fails to work. Possibly an iFrame--></object>
<!--Content goes here...-->
<object data="footer.html"></object>
</body>
</html>
I do not think that this would work if either header.html or footer.html have javascript that accesses the parent document. Getting it to work the other way might be possible though.
Check out ppk's website (quirksmode.org), and go to the javascript archives,
(http://quirksmode.org/js/contents.html). He uses an ajax function he wrote called sendRequest (found at http://quirksmode.org/quirksmode.js). Since IE9+ plays nice with standards, I've simplified it some:
function sendRequest(url,callback,postData) {
var req = new XMLHttpRequest();
if (!req) return;
var method = (postData) ? "POST" : "GET";
req.open(method,url,true);
req.setRequestHeader('User-Agent','XMLHTTP/1.0');
if (postData)
req.setRequestHeader('Content-type','application/x-www-form-urlencoded');
req.onreadystatechange = function () {
if (req.readyState != 4) return;
if (req.status != 200 && req.status != 304) {
// alert('HTTP error ' + req.status);
return;
}
callback(req);
}
if (req.readyState == 4) return;
req.send(postData);
}
Then use the sendRequest function by wrapping the setFooter, setHeader functions and any other content functions around it.
why not use php or any other side scripting language?
doing this with javascript will not all users allow to watch your page.
Whilst this can be done with JS in a number of ways (AJAX, iframe insertion) it would be a very bad idea not to do this within the mark-up directly or (much) better on the server side.
A page reliant on JS for it's composition will not be fully rendered on a significant proportion of user's browsers, and equally importantly will not be correctly interpreted by google et al, if they like it at all.
You can do it, but please, please, don't.
Obviously header.html and footer.html are not html files -- with full fledged headers etc. If you have just html snippets and you want to include them so you can create different pages - like aboutus.html, terms.html, you have a couple of options:
Use a framework like Rails - which allows you to use layouts and partials. [** heavy **]
Write a simple tool that will generate all the files by concat-ing the appropriate files.
I assume you are doing this to avoid duplicating header and footer content.
Another way would be using ajax to include the remote html files.
Framesets would be the way to do this without any script or serverside influences.
<frameset rows="100,*,100">
<frame name="header" src="header.html" />
<frame name="content" src="content.html" />
<frame name="footer" src="footer.html" />
</frameset>
HTML5 framesets:http://www.w3schools.com/tags/html5_frameset.asp
This is a very dated solution, most web hosts will support server side includes or you could use php to include your files
http://php.net/manual/en/function.include.php
Cheers