+ docstring url = getParam("target");
+ docstring name = getParam("name");
+ static docstring const backslash = from_ascii("\\");
+ static docstring const braces = from_ascii("{}");
+ static char_type const chars_url[2] = {'%', '#'};
+ static char_type const chars_name[6] = {
+ '&', '_', '$', '%', '#', '^'};
+
+ // For the case there is no name given, the target is set as name.
+ // Do this before !url.empty() and !name.empty() to handle characters
+ // like the "%" correctly.
+ if (name.empty())
+ name = url;
+
+ if (!url.empty()) {
+ // Replace the "\" character by its ASCII code according to the
+ // URL specifications because "\" is not allowed in URLs and by
+ // \href. Only do this when the following character is not also
+ // a "\", because "\\" is valid code
+ for (size_t i = 0, pos;
+ (pos = url.find('\\', i)) != string::npos;
+ i = pos + 2) {
+ if (url[pos + 1] != '\\')
+ url.replace(pos, 1, from_ascii("%5C"));
+ }
+
+ // The characters in chars_url[] need to be escaped in the url
+ // field because otherwise LaTeX will fail when the hyperlink is
+ // within an argument of another command, e.g. in a \footnote. It
+ // is important that they are escaped as "\#" and not as "\#{}".
+ for (int k = 0; k < 2; k++)
+ for (size_t i = 0, pos;
+ (pos = url.find(chars_url[k], i)) != string::npos;
+ i = pos + 2)
+ url.replace(pos, 1, backslash + chars_url[k]);
+
+ // add "http://" when the type is web (type = empty)
+ // and no "://" or "run:" is given
+ docstring type = getParam("type");
+ if (url.find(from_ascii("://")) == string::npos
+ && url.find(from_ascii("run:")) == string::npos
+ && type.empty())
+ url = from_ascii("http://") + url;
+
+ } // end if (!url.empty())
+
+ // The characters in chars_name[] need to be changed to a command when
+ // they are in the name field.
+ if (!name.empty()) {
+ // handle the "\" character, but only when the following character
+ // is not also a "\", because "\\" is valid code
+ docstring const textbackslash = from_ascii("\\textbackslash{}");
+ for (size_t i = 0, pos;
+ (pos = name.find('\\', i)) != string::npos;
+ i = pos + 2) {
+ if (name[pos + 1] != '\\')
+ name.replace(pos, 1, textbackslash);
+ }
+ // The characters in chars_name[] need to be changed to a command
+ // when they are in the name field.
+ // Therefore the treatment of "\" must be the first thing
+ for (int k = 0; k < 6; k++)
+ for (size_t i = 0, pos;
+ (pos = name.find(chars_name[k], i)) != string::npos;
+ i = pos + 2)
+ name.replace(pos, 1, backslash + chars_name[k] + braces);
+
+ // replace the tilde by the \sim character as suggested in the
+ // LaTeX FAQ for URLs
+ docstring const sim = from_ascii("$\\sim$");
+ for (size_t i = 0, pos;
+ (pos = name.find('~', i)) != string::npos;
+ i = pos + 1)
+ name.replace(pos, 1, sim);
+ pair<docstring, docstring> name_latexed =
+ runparams.encoding->latexString(name, runparams.dryrun);
+ name = name_latexed.first;
+ if (!name_latexed.second.empty() && !runparams.silent) {
+ // issue a warning about omitted characters
+ // FIXME: should be passed to the error dialog
+ frontend::Alert::warning(_("Uncodable characters"),
+ bformat(_("The following characters that are used in the href inset are not\n"
+ "representable in the current encoding and therefore have been omitted:\n%1$s."),
+ name_latexed.second));
+ }
+ } // end if (!name.empty())
+