I've browsed around with search and can't find a previous report of this.
Our help system links to a number of ancillary files (code for simulation models); these reside in subdirectories of the help location (so that the links work on all platforms). Everything works fine from .chm files on Win machines, and html webhelp on the Mac with Safari. But on the Mac with Firefox 5, the links don't work.
What seems to be happening is the following. A typical link in the generated html looks like:
<span class="f_BodyText"><a href="Models\FunctionExamples\ABS.mdl" class="filelink">ABS.mdl</a> - models from the User's Guide, organized by chapter</span>
Note the backslash in the href.
On Windows, this gets automatically rewritten to an absolute path on the local file system:
file:///C:/Documents%20and%20Settings/Fid/My%20Documents/_Vensim/Documentation/Manual/HTML/Models/FunctionExamples/ABS.mdl
On Safari, the same process works, and again the \ are rewritten as /. But in Firefox 5, the \es in the link don't get rewritten, so the resulting link fails, as in
file:///Volumes/SharedDocs/HTML/Models\FunctionExamples\ABS.mdl
Is there a known workaround for this (other than manually search/replacing the \ each time we build)? Where does the path modification actually happen?
Thanks
Tom
webhelp file links don't work on Mac Firefox 5
Moderators: Alexander Halser, Tim Green
-
- Posts: 5
- Joined: Wed May 11, 2011 10:37 pm
- Tim Green
- Site Admin
- Posts: 23181
- Joined: Mon Jun 24, 2002 9:11 am
- Location: Bruehl, Germany
- Contact:
Re: webhelp file links don't work on Mac Firefox 5
Hi Tom,
Actually, it's the other way round: When you enter a path in the file link or Internet link dialog the path is exported exactly as you enter it without conversion. Since the path is being interpreted by a browser it actually needs forward slashes. Windows browsers know about the forward/backward slash dichotomy on Windows and make allowance for it, but browsers on Mac, Linux and and other Unix-based operating systems don't necessarily make this assumption (although some do because of the large number of Windows programmers around...). If you use standard URL forward slashes in your links it should work across all systems.
Actually, it's the other way round: When you enter a path in the file link or Internet link dialog the path is exported exactly as you enter it without conversion. Since the path is being interpreted by a browser it actually needs forward slashes. Windows browsers know about the forward/backward slash dichotomy on Windows and make allowance for it, but browsers on Mac, Linux and and other Unix-based operating systems don't necessarily make this assumption (although some do because of the large number of Windows programmers around...). If you use standard URL forward slashes in your links it should work across all systems.
Regards,
Tim (EC Software Documentation & User Support)
Private support:
Please do not email or PM me with private support requests -- post to the forum directly.
Tim (EC Software Documentation & User Support)
Private support:
Please do not email or PM me with private support requests -- post to the forum directly.
-
- Posts: 5
- Joined: Wed May 11, 2011 10:37 pm
Re: webhelp file links don't work on Mac Firefox 5
Ahh ... that makes sense. I think I must have been thinking in the wrong file system paradigm when I started adding directory nesting to my links manually, because the Edit Hyperlink dialog actually doesn't reflect folder hierarchy when you use its browse button. Thanks!
-
- Posts: 5
- Joined: Wed May 11, 2011 10:37 pm
Re: webhelp file links don't work on Mac Firefox 5
I may have spoken too soon ... it seems that / doesn't work for nested link references in .chm ?
- Tim Green
- Site Admin
- Posts: 23181
- Joined: Mon Jun 24, 2002 9:11 am
- Location: Bruehl, Germany
- Contact:
Re: webhelp file links don't work on Mac Firefox 5
It doesn't work in CHM because Microsoft's CHM system has a known "relative paths bug" that has been uncorrected since the CHM system was released with Windows 98. You can fix this problem with my relative paths bug correction script. Note that this is designed for use with CHM which is Windows only, because only CHM has this problem, so it uses backslashes. You will need to insert two versions of each link with conditional text tags: One with forward slashes for HTML and one with backslashes for CHM.,Tom Fiddaman wrote:I may have spoken too soon ... it seems that / doesn't work for nested link references in .chm ?
Regards,
Tim (EC Software Documentation & User Support)
Private support:
Please do not email or PM me with private support requests -- post to the forum directly.
Tim (EC Software Documentation & User Support)
Private support:
Please do not email or PM me with private support requests -- post to the forum directly.
-
- Posts: 5
- Joined: Wed May 11, 2011 10:37 pm
Re: webhelp file links don't work on Mac Firefox 5
Thanks again. I'm good to go now. Fortunately I don't need path access outside the help folder, just nested within it. So, all I had to do was insert conditional text to create \ links for chm and / links for webhelp.
I wrote a bit of Java to process all my XML topics, making a single link with \ or / into conditional text with appropriate slashes for each build. I'm sure it's neither the best tool nor the best code for this, but here it is for what it's worth:
I wrote a bit of Java to process all my XML topics, making a single link with \ or / into conditional text with appropriate slashes for each build. I'm sure it's neither the best tool nor the best code for this, but here it is for what it's worth:
Code: Select all
package conditionalhelplinks;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import org.apache.commons.io.FileUtils;
import java.util.Date;
import java.text.SimpleDateFormat;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import org.w3c.dom.NamedNodeMap;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
/**
*
* @author Fid
*/
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// location of topics to be made conditional
File dir = new File("c:\\Documents and Settings\\Fid\\My Documents\\_vensim\\documentation\\manual\\topics");
// first copy all the originals to a directory for backup
File origDir = new File(dir.getAbsolutePath().concat("\\orig"));
// filter for xml files (normally this is all the Topics directory contains anyway, I think)
FileFilter fileFilter = new FileFilter() {
public boolean accept(File file) {
return file.getName().endsWith(".xml");
}
};
File[] files = dir.listFiles(fileFilter);
if (files == null) {
// Either dir does not exist or is not a directory
System.out.println("null file list for " + dir.getAbsolutePath());
} else {
System.out.println("processing " + files.length + " files");
// cutoff date for processing xml files (only edit files newer than this date)
Long c = new Long("1308930874109");
long cutoff = c.longValue();
// count of files processed
int n = 0;
// iterate over file list
for (int i = 0; i < files.length; i++) {
// Get filename of file or directory
File file = files[i];
String fname = file.getName();
// check date and process if needed
long mod = file.lastModified();
if (mod > cutoff) {
// increment file count
n++;
Date modDate = new Date(mod);
SimpleDateFormat sdf = new SimpleDateFormat("EEEE yyyy/MM/dd hh:mm:ss aa zz : zzzzzz");
System.out.println(n + " " + fname + " " + mod + " " + sdf.format(modDate));
try {
FileUtils.copyFileToDirectory(file, origDir, true); // make backup
// parse the xml
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(file);
// get the list of nodes that are links
NodeList links = doc.getElementsByTagName("link");
// iterate over links
for (int j = 0; j < links.getLength(); j++) {
Node node = links.item(j);
System.out.println(node.toString());
//Node parent = node.getParentNode();
//System.out.println("\t^ "+parent.toString());
// check whether a node has already been made conditional (in which case previous node should be a conditional-text)
Node prev = node.getPreviousSibling();
if (prev == null) { // no previous sibling
hrefMakeConditional(node, doc);
} else {
System.out.println("\t<- " + prev.toString() + " " + prev.getNodeName());
if ( ! prev.getNodeName().equalsIgnoreCase("conditional-text")) { // skip items that are already conditional
// TODO: conceivably this could go wrong if a link node has a prior node that is an ENDIF or some other condition, but ignore this potential hazard
hrefMakeConditional(node, doc);
}
}
}
// write output
Transformer transformer = TransformerFactory.newInstance().newTransformer();
//transformer.setOutputProperty(OutputKeys.INDENT, "yes");
//initialize StreamResult with File object to save to file
File dest = new File(dir.getAbsolutePath() + "\\mod\\" + fname); // output goes to a "mod" subdirectory - at end of process, files in mod should be copied up to replace the originals in Topics
StreamResult result = new StreamResult(dest);
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);
} catch (TransformerException ex) {
ex.printStackTrace();
} catch (ParserConfigurationException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} catch (SAXException ex) {
ex.printStackTrace();
}
}
}
}
}
static void hrefMakeConditional(Node node, Document doc) {
// TODO could also check whether there are any \ / to worry about at all, before processing
if (checkFileLink(node)) {
// add IF conditional
Element ifElm = doc.createElement("conditional-text");
ifElm.setAttribute("type", "IF");
ifElm.setAttribute("value", "CHM");
node.getParentNode().insertBefore(ifElm, node);
// give this node backslashes for .chm format
pathSetSeparator(node, false);
// add ELSE conditional
Element elseElm = doc.createElement("conditional-text");
elseElm.setAttribute("type", "ELSE");
insertAfter(node, elseElm);
// make a clone with frontslashes for webhelp html
Node webNode = node.cloneNode(true);
pathSetSeparator(webNode, true);
insertAfter(elseElm, webNode);
// add ENDIF
Element endElm = doc.createElement("conditional-text");
endElm.setAttribute("type", "END");
insertAfter(webNode, endElm);
}
}
static void insertAfter(Node nexist, Node nnew) {
//System.out.println("inserting " + nnew.toString() + " after " + nexist.toString() + " which has sibling " + nexist.getNextSibling());
if (nexist.getNextSibling() == null) {
nexist.getParentNode().appendChild(nnew); // no next sibling; make it last in list
} else {
nexist.getParentNode().insertBefore(nnew, nexist.getNextSibling()); // insert before next sibling
}
}
static void pathSetSeparator(Node node, boolean frontSlash) {
// get the href from the link and change all /\ to a consistent form
// note that this assumes that links don't contain any quoted \/ or escaped \\ or other confusing slashy stuff
if (node.hasAttributes()) {
NamedNodeMap attribs = node.getAttributes();
Node type = attribs.getNamedItem("type");
if (type != null) {
if (type.getNodeValue().equalsIgnoreCase("filelink")) {
System.out.println("\t" + node.toString() + "-> conditional");
Node href = attribs.getNamedItem("href"); // TODO: check for null
String hrefString = href.getNodeValue();
if (frontSlash) {
href.setNodeValue(hrefString.replace('\\', '/'));
} else {
href.setNodeValue(hrefString.replace('/', '\\'));
}
} else {
System.out.println("\t\tnot a filelink");
}
} else {
System.out.println("\t\tERROR! null type");
}
} else {
System.out.println("\t\tERROR! no attributes");
}
}
static boolean checkFileLink(Node node) {
// check whether the node is a 'filelink' (don't want to process 'topiclink' or other links)
if (node.hasAttributes()) {
NamedNodeMap attribs = node.getAttributes();
Node type = attribs.getNamedItem("type");
if (type != null) {
if (type.getNodeValue().equalsIgnoreCase("filelink")) {
return true;
}
}
}
return false;
}
}
- Tim Green
- Site Admin
- Posts: 23181
- Joined: Mon Jun 24, 2002 9:11 am
- Location: Bruehl, Germany
- Contact:
Re: webhelp file links don't work on Mac Firefox 5
Hi Tom,
Great to hear, and thanks for posting the Java listing. You might want to post it in the Templates and Utilities section as well. Things like this tend to "go under" quite quickly in the general forum and it's a nice resource for others to use.
Great to hear, and thanks for posting the Java listing. You might want to post it in the Templates and Utilities section as well. Things like this tend to "go under" quite quickly in the general forum and it's a nice resource for others to use.
Regards,
Tim (EC Software Documentation & User Support)
Private support:
Please do not email or PM me with private support requests -- post to the forum directly.
Tim (EC Software Documentation & User Support)
Private support:
Please do not email or PM me with private support requests -- post to the forum directly.