bug-texinfo
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Makeinfo --html produces broken external refs


From: Sergey Poznyakoff
Subject: Makeinfo --html produces broken external refs
Date: Thu, 05 Jul 2007 16:35:48 +0300

Hello,

Cross-references to external documents produced by makeinfo --html are
almost always broken. This is because (1) the hostname part of a
reference is always supposed to be localhost, and (2) the href is build
using this approach (xref.c around line 270):

  else if (splitting)
    execute_string ("\"../%s/", file_arg);
  else
    execute_string ("\"%s.html", file_arg);

which is wrong even when referencing to the document within the same
host. Indeed, in split mode '../%s' would refer to
`${base_url}/manual', which surely will not contain the document in
question. Consider the following test document:

-- cut here --
\input texinfo 
@smallbook
@setfilename xref.info
@settitle External cross references

@node Top, , (dir), (dir)

@xref{tar invocation, Invoking GNU tar, Invoking GNU tar, tar,
GNU tar: an archiver tool}, for the information about how to invoke GNU tar.

@bye
-- -- cut here --

Assuming its html variants were installed at the usual locations
www.gnu.org/software/xref/manual/xref.html and
www.gnu.org/software/xref/manual/html_node/*, the xref in question would
point to:

(in split page) www.gnu.org/software/xref/tar/tar-invocation.html
(in monolithic page) www.gnu.org/software/xref/tar.html#tar-invocation

which both are far from what was intended.

As a real-life illustration of this, please see GNU tar's documentation:

  
http://www.gnu.org/software/tar/manual/html_node/transform.html#index-transform-383

which contains a broken link to the `sed' documentation (look for `The
"s" command').

This situation could slightly be improved by fixing the above code as:

  else if (splitting)
    execute_string ("\"../../../%s/manual/html_mode/", file_arg);
  else
    execute_string ("\"../../../%s/manual/%s.html", file_arg, file_arg);

But this approach has two drawbacks: first, it is impossible to refer to
a document located on another host, and, secondly, not all projects
follow the hardcoded directory layout. In particular, Texinfo does not!

Therefore, in addition to the above change, I propose to introduce two
new commands:

@setxrefurl URL
  Sets the base url for 5-argument xrefs in monolithic html mode.
  
@setxrefspliturl URL
  Sets the base url for 5-argument xrefs in split html mode.

The URL in the above commands can be either a literal string, in which
case it is simply prepended to the reference, or it can be a name of
a single-argument macro. In the latter case, this macro is called with
the 5-th xref parameter as its argument, and the result of its expansion
is prepended to the reference to form the actual href. This will allow
to refer to any URLs both within and outside the local host. To
illustrate this, here is how the above example will look like:

-- cut here --
\input texinfo 
@smallbook
@setfilename xref.info
@settitle External cross references

@c Produce the base url for referencing the monolithic html page of 
@c project NAME
@macro xbasemono{name}
http://www.gnu.org/software/\name\/manual/\name\.html
@end macro

@c Produce the base url for referencing a split html page of 
@c project NAME
@macro xbasesplit{name}
http://www.gnu.org/software/\name\/manual/html_node/
@end macro

@c Set the above urls
@setxrefurl xbasemono
@setxrefspliturl xbasesplit

@node Top, , (dir), (dir)

@xref{tar invocation, Invoking GNU tar, Invoking GNU tar, tar,
GNU tar: an archiver tool}, for the information about how to invoke GNU tar.

@bye
-- -- cut here --

A patch implementing this follows. There are obviously several things
left to do, such as updating texinfo.tex to ignore the two new commands
and writing the docs. I will promptly supply these if the proposed
approach looks feasible to you.


Regards,
Sergey

2007-07-05  Sergey Poznyakoff  <address@hidden>

        * makeinfo/cmds.c (command_table): Register new commands
        setxrefurl and setxrefspliturl.
        * makeinfo/cmds.h (cm_setxrefurl, cm_setxrefspliturl): New
        prototypes.
        * makeinfo/xref.c (xref_mono_base, xref_split_base): New
        variables
        (cm_setxrefurl, cm_setxrefspliturl, get_xref_html_base)
        (expand_external_ref): New functions
        (cm_xref): Handle external references using the appropriate
        xref_.*_base. By default, fallback to hardcoded locations
        suitable for most GNU projects on www.gnu.org/software. 

Index: makeinfo/cmds.c
===================================================================
RCS file: /cvsroot/texinfo/texinfo/makeinfo/cmds.c,v
retrieving revision 1.73
diff -p -u -r1.73 cmds.c
--- makeinfo/cmds.c     1 Jul 2007 21:20:31 -0000       1.73
+++ makeinfo/cmds.c     5 Jul 2007 13:13:58 -0000
@@ -352,6 +352,8 @@ COMMAND command_table[] = {
   { "w", cm_w, BRACE_ARGS },
   { "xml", cm_xml, NO_BRACE_ARGS },
   { "xref", cm_xref, BRACE_ARGS },
+  { "setxrefurl", cm_setxrefurl, NO_BRACE_ARGS },
+  { "setxrefspliturl", cm_setxrefspliturl, NO_BRACE_ARGS },
 
   /* Deprecated commands.  These used to be for italics.  */
   { "iappendix", cm_ideprecated, NO_BRACE_ARGS },
Index: makeinfo/cmds.h
===================================================================
RCS file: /cvsroot/texinfo/texinfo/makeinfo/cmds.h,v
retrieving revision 1.12
diff -p -u -r1.12 cmds.h
--- makeinfo/cmds.h     1 Jul 2007 21:20:32 -0000       1.12
+++ makeinfo/cmds.h     5 Jul 2007 13:13:58 -0000
@@ -83,7 +83,10 @@ extern void cm_anchor (int arg),
   cm_pxref (int arg),
   cm_ref (int arg),
   cm_inforef (int arg),
-  cm_uref (int arg);
+  cm_uref (int arg),
+  cm_setxrefurl (void),
+  cm_setxrefspliturl (void);   
+
 
 /* Special insertions.  */
 extern void cm_LaTeX (int arg),
Index: makeinfo/xref.c
===================================================================
RCS file: /cvsroot/texinfo/texinfo/makeinfo/xref.c,v
retrieving revision 1.12
diff -p -u -r1.12 xref.c
--- makeinfo/xref.c     1 Jul 2007 21:20:33 -0000       1.12
+++ makeinfo/xref.c     5 Jul 2007 13:13:58 -0000
@@ -31,6 +31,27 @@
 int px_ref_flag = 0;
 int ref_flag = 0;
 
+char *xref_mono_base;
+char *xref_split_base;
+
+void
+cm_setxrefurl (void)
+{
+  get_rest_of_line (0, &xref_mono_base);
+}
+
+void
+cm_setxrefspliturl (void)
+{
+  get_rest_of_line (0, &xref_split_base);
+}
+
+static char *
+get_xref_html_base ()
+{
+  return splitting ? xref_split_base : xref_mono_base;
+}
+
 /* Called in the multiple-argument case to make sure we generate a valid
    Info reference.  In the single-argument case, the :: we output
    suffices for the Info readers to find the end of the reference.  */
@@ -98,6 +119,16 @@ get_xref_token (int expand)
   return string;
 }
 
+static void
+expand_external_ref (const char *ref, const char *file_arg)
+{
+  MACRO_DEF *mdef;
+                     
+  if ((mdef = find_macro (ref)) && mdef->argcount == 1)
+    execute_string ("\"@%s{%s}", ref, file_arg);
+  else
+    execute_string ("\"%s", ref);
+}
 
 /* NOTE: If you wonder why the HTML output is produced with such a
    peculiar mix of calls to add_word and execute_string, here's the
@@ -233,6 +264,8 @@ cm_xref (int arg)
                      Normalization Form C.  See the HTML Xref nodes in
                      the manual.  */
                   char *file_arg = arg4;
+                 char *base;
+                 
                   add_html_elt ("<a href=");
 
                   {
@@ -252,17 +285,20 @@ cm_xref (int arg)
                 warning (_("Empty file name for HTML cross reference in `%s'"),
                            arg4);
 
-                  /* Note that if we are splitting, and the referenced
+                 if (*arg5 && (base = get_xref_html_base ()))
+                   expand_external_ref (base, file_arg);
+
+                 /* Note that if we are splitting, and the referenced
                      tag is an anchor rather than a node, we will
                      produce a reference to a file whose name is
                      derived from the anchor name.  However, only
                      nodes create files, so we are referencing a
                      non-existent file.  cm_anchor, which see, deals
                      with that problem.  */
-                  if (splitting)
-                    execute_string ("\"../%s/", file_arg);
+                  else if (splitting)
+                    execute_string ("\"../../../%s/", file_arg);
                   else
-                    execute_string ("\"%s.html", file_arg);
+                    execute_string ("\"../../../%s.html", file_arg);
                   /* Do not collapse -- to -, etc., in references.  */
                   in_fixed_width_font++;
                   tem = expansion (arg1, 0); /* expand @-commands in node */


    




reply via email to

[Prev in Thread] Current Thread [Next in Thread]