1*a1acfa9bSespie /* xref.c -- cross references for Texinfo.
2*a1acfa9bSespie $Id: xref.c,v 1.1.1.1 2006/07/17 16:03:49 espie Exp $
3*a1acfa9bSespie
4*a1acfa9bSespie Copyright (C) 2004 Free Software Foundation, Inc.
5*a1acfa9bSespie
6*a1acfa9bSespie This program is free software; you can redistribute it and/or modify
7*a1acfa9bSespie it under the terms of the GNU General Public License as published by
8*a1acfa9bSespie the Free Software Foundation; either version 2, or (at your option)
9*a1acfa9bSespie any later version.
10*a1acfa9bSespie
11*a1acfa9bSespie This program is distributed in the hope that it will be useful,
12*a1acfa9bSespie but WITHOUT ANY WARRANTY; without even the implied warranty of
13*a1acfa9bSespie MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*a1acfa9bSespie GNU General Public License for more details.
15*a1acfa9bSespie
16*a1acfa9bSespie You should have received a copy of the GNU General Public License
17*a1acfa9bSespie along with this program; if not, write to the Free Software Foundation,
18*a1acfa9bSespie Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19*a1acfa9bSespie
20*a1acfa9bSespie #include "system.h"
21*a1acfa9bSespie #include "cmds.h"
22*a1acfa9bSespie #include "float.h"
23*a1acfa9bSespie #include "html.h"
24*a1acfa9bSespie #include "index.h"
25*a1acfa9bSespie #include "macro.h"
26*a1acfa9bSespie #include "makeinfo.h"
27*a1acfa9bSespie #include "node.h"
28*a1acfa9bSespie #include "xml.h"
29*a1acfa9bSespie #include "xref.h"
30*a1acfa9bSespie
31*a1acfa9bSespie /* Flags which control initial output string for xrefs. */
32*a1acfa9bSespie int px_ref_flag = 0;
33*a1acfa9bSespie int ref_flag = 0;
34*a1acfa9bSespie
35*a1acfa9bSespie /* Called in the multiple-argument case to make sure we generate a valid
36*a1acfa9bSespie Info reference. In the single-argument case, the :: we output
37*a1acfa9bSespie suffices for the Info readers to find the end of the reference. */
38*a1acfa9bSespie static void
add_xref_punctuation(void)39*a1acfa9bSespie add_xref_punctuation (void)
40*a1acfa9bSespie {
41*a1acfa9bSespie if (px_ref_flag || ref_flag) /* user inserts punct after @xref */
42*a1acfa9bSespie {
43*a1acfa9bSespie /* Check if there's already punctuation. */
44*a1acfa9bSespie int next_char = next_nonwhitespace_character ();
45*a1acfa9bSespie
46*a1acfa9bSespie if (next_char == -1)
47*a1acfa9bSespie /* EOF while looking for punctuation, let's
48*a1acfa9bSespie insert a period instead of crying. */
49*a1acfa9bSespie add_char ('.');
50*a1acfa9bSespie else if (next_char != ',' && next_char != '.')
51*a1acfa9bSespie /* period and comma terminate xrefs, and nothing else. Instead
52*a1acfa9bSespie of generating an Info reference that can't be followed,
53*a1acfa9bSespie though, just insert a period. Not pretty, but functional. */
54*a1acfa9bSespie add_char ('.');
55*a1acfa9bSespie }
56*a1acfa9bSespie }
57*a1acfa9bSespie
58*a1acfa9bSespie /* Return next comma-delimited argument, but do not cross a close-brace
59*a1acfa9bSespie boundary. Clean up whitespace, too. If EXPAND is nonzero, replace
60*a1acfa9bSespie the entire brace-delimited argument list with its expansion before
61*a1acfa9bSespie looking for the next comma. */
62*a1acfa9bSespie char *
get_xref_token(int expand)63*a1acfa9bSespie get_xref_token (int expand)
64*a1acfa9bSespie {
65*a1acfa9bSespie char *string = 0;
66*a1acfa9bSespie
67*a1acfa9bSespie if (docbook)
68*a1acfa9bSespie xml_in_xref_token = 1;
69*a1acfa9bSespie
70*a1acfa9bSespie if (expand)
71*a1acfa9bSespie {
72*a1acfa9bSespie int old_offset = input_text_offset;
73*a1acfa9bSespie int old_lineno = line_number;
74*a1acfa9bSespie
75*a1acfa9bSespie get_until_in_braces ("}", &string);
76*a1acfa9bSespie if (curchar () == '}') /* as opposed to end of text */
77*a1acfa9bSespie input_text_offset++;
78*a1acfa9bSespie if (input_text_offset > old_offset)
79*a1acfa9bSespie {
80*a1acfa9bSespie int limit = input_text_offset;
81*a1acfa9bSespie
82*a1acfa9bSespie input_text_offset = old_offset;
83*a1acfa9bSespie line_number = old_lineno;
84*a1acfa9bSespie only_macro_expansion++;
85*a1acfa9bSespie replace_with_expansion (input_text_offset, &limit);
86*a1acfa9bSespie only_macro_expansion--;
87*a1acfa9bSespie }
88*a1acfa9bSespie free (string);
89*a1acfa9bSespie }
90*a1acfa9bSespie
91*a1acfa9bSespie get_until_in_braces (",", &string);
92*a1acfa9bSespie if (curchar () == ',')
93*a1acfa9bSespie input_text_offset++;
94*a1acfa9bSespie fix_whitespace (string);
95*a1acfa9bSespie
96*a1acfa9bSespie if (docbook)
97*a1acfa9bSespie xml_in_xref_token = 0;
98*a1acfa9bSespie
99*a1acfa9bSespie return string;
100*a1acfa9bSespie }
101*a1acfa9bSespie
102*a1acfa9bSespie
103*a1acfa9bSespie /* NOTE: If you wonder why the HTML output is produced with such a
104*a1acfa9bSespie peculiar mix of calls to add_word and execute_string, here's the
105*a1acfa9bSespie reason. get_xref_token (1) expands all macros in a reference, but
106*a1acfa9bSespie any other commands, like @value, @@, etc., are left intact. To
107*a1acfa9bSespie expand them, we need to run the arguments through execute_string.
108*a1acfa9bSespie However, characters like <, &, > and others cannot be let into
109*a1acfa9bSespie execute_string, because they will be escaped. See the mess? */
110*a1acfa9bSespie
111*a1acfa9bSespie /* Make a cross reference. */
112*a1acfa9bSespie void
cm_xref(int arg)113*a1acfa9bSespie cm_xref (int arg)
114*a1acfa9bSespie {
115*a1acfa9bSespie if (arg == START)
116*a1acfa9bSespie {
117*a1acfa9bSespie char *arg1 = get_xref_token (1); /* expands all macros in xref */
118*a1acfa9bSespie char *arg2 = get_xref_token (0);
119*a1acfa9bSespie char *arg3 = get_xref_token (0);
120*a1acfa9bSespie char *arg4 = get_xref_token (0);
121*a1acfa9bSespie char *arg5 = get_xref_token (0);
122*a1acfa9bSespie char *tem;
123*a1acfa9bSespie
124*a1acfa9bSespie /* "@xref{,Foo,, Bar, Baz} is not valid usage of @xref. The
125*a1acfa9bSespie first argument must never be blank." --rms.
126*a1acfa9bSespie We hereby comply by disallowing such constructs. */
127*a1acfa9bSespie if (!*arg1)
128*a1acfa9bSespie line_error (_("First argument to cross-reference may not be empty"));
129*a1acfa9bSespie
130*a1acfa9bSespie if (docbook)
131*a1acfa9bSespie {
132*a1acfa9bSespie if (!ref_flag)
133*a1acfa9bSespie add_word (px_ref_flag || printing_index
134*a1acfa9bSespie ? (char *) _("see ") : (char *) _("See "));
135*a1acfa9bSespie
136*a1acfa9bSespie if (!*arg4 && !*arg5)
137*a1acfa9bSespie {
138*a1acfa9bSespie char *arg1_id = xml_id (arg1);
139*a1acfa9bSespie
140*a1acfa9bSespie if (*arg2 || *arg3)
141*a1acfa9bSespie {
142*a1acfa9bSespie xml_insert_element_with_attribute (XREFNODENAME, START,
143*a1acfa9bSespie "linkend=\"%s\"", arg1_id);
144*a1acfa9bSespie free (arg1_id);
145*a1acfa9bSespie execute_string ("%s", *arg3 ? arg3 : arg2);
146*a1acfa9bSespie xml_insert_element (XREFNODENAME, END);
147*a1acfa9bSespie }
148*a1acfa9bSespie else
149*a1acfa9bSespie {
150*a1acfa9bSespie xml_insert_element_with_attribute (XREF, START,
151*a1acfa9bSespie "linkend=\"%s\"", arg1_id);
152*a1acfa9bSespie xml_insert_element (XREF, END);
153*a1acfa9bSespie free (arg1_id);
154*a1acfa9bSespie }
155*a1acfa9bSespie }
156*a1acfa9bSespie else if (*arg5)
157*a1acfa9bSespie {
158*a1acfa9bSespie add_word_args (_("See section ``%s'' in "), *arg3 ? arg3 : arg1);
159*a1acfa9bSespie xml_insert_element (CITE, START);
160*a1acfa9bSespie add_word (arg5);
161*a1acfa9bSespie xml_insert_element (CITE, END);
162*a1acfa9bSespie }
163*a1acfa9bSespie else if (*arg4)
164*a1acfa9bSespie {
165*a1acfa9bSespie /* Very sad, we are losing xrefs made to ``info only'' books. */
166*a1acfa9bSespie }
167*a1acfa9bSespie }
168*a1acfa9bSespie else if (xml)
169*a1acfa9bSespie {
170*a1acfa9bSespie if (!ref_flag)
171*a1acfa9bSespie add_word_args ("%s", px_ref_flag ? _("see ") : _("See "));
172*a1acfa9bSespie
173*a1acfa9bSespie xml_insert_element (XREF, START);
174*a1acfa9bSespie xml_insert_element (XREFNODENAME, START);
175*a1acfa9bSespie execute_string ("%s", arg1);
176*a1acfa9bSespie xml_insert_element (XREFNODENAME, END);
177*a1acfa9bSespie if (*arg2)
178*a1acfa9bSespie {
179*a1acfa9bSespie xml_insert_element (XREFINFONAME, START);
180*a1acfa9bSespie execute_string ("%s", arg2);
181*a1acfa9bSespie xml_insert_element (XREFINFONAME, END);
182*a1acfa9bSespie }
183*a1acfa9bSespie if (*arg3)
184*a1acfa9bSespie {
185*a1acfa9bSespie xml_insert_element (XREFPRINTEDDESC, START);
186*a1acfa9bSespie execute_string ("%s", arg3);
187*a1acfa9bSespie xml_insert_element (XREFPRINTEDDESC, END);
188*a1acfa9bSespie }
189*a1acfa9bSespie if (*arg4)
190*a1acfa9bSespie {
191*a1acfa9bSespie xml_insert_element (XREFINFOFILE, START);
192*a1acfa9bSespie execute_string ("%s", arg4);
193*a1acfa9bSespie xml_insert_element (XREFINFOFILE, END);
194*a1acfa9bSespie }
195*a1acfa9bSespie if (*arg5)
196*a1acfa9bSespie {
197*a1acfa9bSespie xml_insert_element (XREFPRINTEDNAME, START);
198*a1acfa9bSespie execute_string ("%s", arg5);
199*a1acfa9bSespie xml_insert_element (XREFPRINTEDNAME, END);
200*a1acfa9bSespie }
201*a1acfa9bSespie xml_insert_element (XREF, END);
202*a1acfa9bSespie }
203*a1acfa9bSespie else if (html)
204*a1acfa9bSespie {
205*a1acfa9bSespie if (!ref_flag)
206*a1acfa9bSespie add_word_args ("%s", px_ref_flag ? _("see ") : _("See "));
207*a1acfa9bSespie }
208*a1acfa9bSespie else
209*a1acfa9bSespie add_word_args ("%s", px_ref_flag ? "*note " : "*Note ");
210*a1acfa9bSespie
211*a1acfa9bSespie if (!xml)
212*a1acfa9bSespie {
213*a1acfa9bSespie if (*arg5 || *arg4)
214*a1acfa9bSespie {
215*a1acfa9bSespie /* arg1 - node name
216*a1acfa9bSespie arg2 - reference name
217*a1acfa9bSespie arg3 - title or topic (and reference name if arg2 is NULL)
218*a1acfa9bSespie arg4 - info file name
219*a1acfa9bSespie arg5 - printed manual title */
220*a1acfa9bSespie char *ref_name;
221*a1acfa9bSespie
222*a1acfa9bSespie if (!*arg2)
223*a1acfa9bSespie {
224*a1acfa9bSespie if (*arg3)
225*a1acfa9bSespie ref_name = arg3;
226*a1acfa9bSespie else
227*a1acfa9bSespie ref_name = arg1;
228*a1acfa9bSespie }
229*a1acfa9bSespie else
230*a1acfa9bSespie ref_name = arg2;
231*a1acfa9bSespie
232*a1acfa9bSespie if (html)
233*a1acfa9bSespie { /* More to do eventually, down to Unicode
234*a1acfa9bSespie Normalization Form C. See the HTML Xref nodes in
235*a1acfa9bSespie the manual. */
236*a1acfa9bSespie char *file_arg = arg4;
237*a1acfa9bSespie add_html_elt ("<a href=");
238*a1acfa9bSespie
239*a1acfa9bSespie {
240*a1acfa9bSespie /* If there's a directory part, ignore it. */
241*a1acfa9bSespie char *p = strrchr (file_arg, '/');
242*a1acfa9bSespie if (p)
243*a1acfa9bSespie file_arg = p + 1;
244*a1acfa9bSespie
245*a1acfa9bSespie /* If there's a dot, make it a NULL terminator, so the
246*a1acfa9bSespie extension does not get into the way. */
247*a1acfa9bSespie p = strrchr (file_arg , '.');
248*a1acfa9bSespie if (p != NULL)
249*a1acfa9bSespie *p = 0;
250*a1acfa9bSespie }
251*a1acfa9bSespie
252*a1acfa9bSespie if (! *file_arg)
253*a1acfa9bSespie warning (_("Empty file name for HTML cross reference in `%s'"),
254*a1acfa9bSespie arg4);
255*a1acfa9bSespie
256*a1acfa9bSespie /* Note that if we are splitting, and the referenced
257*a1acfa9bSespie tag is an anchor rather than a node, we will
258*a1acfa9bSespie produce a reference to a file whose name is
259*a1acfa9bSespie derived from the anchor name. However, only
260*a1acfa9bSespie nodes create files, so we are referencing a
261*a1acfa9bSespie non-existent file. cm_anchor, which see, deals
262*a1acfa9bSespie with that problem. */
263*a1acfa9bSespie if (splitting)
264*a1acfa9bSespie execute_string ("\"../%s/", file_arg);
265*a1acfa9bSespie else
266*a1acfa9bSespie execute_string ("\"%s.html", file_arg);
267*a1acfa9bSespie /* Do not collapse -- to -, etc., in references. */
268*a1acfa9bSespie in_fixed_width_font++;
269*a1acfa9bSespie tem = expansion (arg1, 0); /* expand @-commands in node */
270*a1acfa9bSespie in_fixed_width_font--;
271*a1acfa9bSespie add_anchor_name (tem, 1);
272*a1acfa9bSespie free (tem);
273*a1acfa9bSespie add_word ("\">");
274*a1acfa9bSespie execute_string ("%s",ref_name);
275*a1acfa9bSespie add_word ("</a>");
276*a1acfa9bSespie }
277*a1acfa9bSespie else
278*a1acfa9bSespie {
279*a1acfa9bSespie execute_string ("%s:", ref_name);
280*a1acfa9bSespie in_fixed_width_font++;
281*a1acfa9bSespie execute_string (" (%s)%s", arg4, arg1);
282*a1acfa9bSespie add_xref_punctuation ();
283*a1acfa9bSespie in_fixed_width_font--;
284*a1acfa9bSespie }
285*a1acfa9bSespie
286*a1acfa9bSespie /* Free all of the arguments found. */
287*a1acfa9bSespie if (arg1) free (arg1);
288*a1acfa9bSespie if (arg2) free (arg2);
289*a1acfa9bSespie if (arg3) free (arg3);
290*a1acfa9bSespie if (arg4) free (arg4);
291*a1acfa9bSespie if (arg5) free (arg5);
292*a1acfa9bSespie return;
293*a1acfa9bSespie }
294*a1acfa9bSespie else
295*a1acfa9bSespie remember_node_reference (arg1, line_number, followed_reference);
296*a1acfa9bSespie
297*a1acfa9bSespie if (*arg3)
298*a1acfa9bSespie {
299*a1acfa9bSespie if (html)
300*a1acfa9bSespie {
301*a1acfa9bSespie add_html_elt ("<a href=\"");
302*a1acfa9bSespie in_fixed_width_font++;
303*a1acfa9bSespie tem = expansion (arg1, 0);
304*a1acfa9bSespie in_fixed_width_font--;
305*a1acfa9bSespie add_anchor_name (tem, 1);
306*a1acfa9bSespie free (tem);
307*a1acfa9bSespie add_word ("\">");
308*a1acfa9bSespie execute_string ("%s", *arg2 ? arg2 : arg3);
309*a1acfa9bSespie add_word ("</a>");
310*a1acfa9bSespie }
311*a1acfa9bSespie else
312*a1acfa9bSespie {
313*a1acfa9bSespie execute_string ("%s:", *arg2 ? arg2 : arg3);
314*a1acfa9bSespie in_fixed_width_font++;
315*a1acfa9bSespie execute_string (" %s", arg1);
316*a1acfa9bSespie add_xref_punctuation ();
317*a1acfa9bSespie in_fixed_width_font--;
318*a1acfa9bSespie }
319*a1acfa9bSespie }
320*a1acfa9bSespie else
321*a1acfa9bSespie {
322*a1acfa9bSespie if (html)
323*a1acfa9bSespie {
324*a1acfa9bSespie add_html_elt ("<a href=\"");
325*a1acfa9bSespie in_fixed_width_font++;
326*a1acfa9bSespie tem = expansion (arg1, 0);
327*a1acfa9bSespie in_fixed_width_font--;
328*a1acfa9bSespie add_anchor_name (tem, 1);
329*a1acfa9bSespie free (tem);
330*a1acfa9bSespie add_word ("\">");
331*a1acfa9bSespie if (*arg2)
332*a1acfa9bSespie execute_string ("%s", arg2);
333*a1acfa9bSespie else
334*a1acfa9bSespie {
335*a1acfa9bSespie char *fref = get_float_ref (arg1);
336*a1acfa9bSespie execute_string ("%s", fref ? fref : arg1);
337*a1acfa9bSespie free (fref);
338*a1acfa9bSespie }
339*a1acfa9bSespie add_word ("</a>");
340*a1acfa9bSespie }
341*a1acfa9bSespie else
342*a1acfa9bSespie {
343*a1acfa9bSespie if (*arg2)
344*a1acfa9bSespie {
345*a1acfa9bSespie execute_string ("%s:", arg2);
346*a1acfa9bSespie in_fixed_width_font++;
347*a1acfa9bSespie execute_string (" %s", arg1);
348*a1acfa9bSespie add_xref_punctuation ();
349*a1acfa9bSespie in_fixed_width_font--;
350*a1acfa9bSespie }
351*a1acfa9bSespie else
352*a1acfa9bSespie {
353*a1acfa9bSespie char *fref = get_float_ref (arg1);
354*a1acfa9bSespie if (fref)
355*a1acfa9bSespie { /* Reference is being made to a float. */
356*a1acfa9bSespie execute_string ("%s:", fref);
357*a1acfa9bSespie in_fixed_width_font++;
358*a1acfa9bSespie execute_string (" %s", arg1);
359*a1acfa9bSespie add_xref_punctuation ();
360*a1acfa9bSespie in_fixed_width_font--;
361*a1acfa9bSespie }
362*a1acfa9bSespie else
363*a1acfa9bSespie {
364*a1acfa9bSespie in_fixed_width_font++;
365*a1acfa9bSespie execute_string ("%s::", arg1);
366*a1acfa9bSespie in_fixed_width_font--;
367*a1acfa9bSespie }
368*a1acfa9bSespie }
369*a1acfa9bSespie }
370*a1acfa9bSespie }
371*a1acfa9bSespie }
372*a1acfa9bSespie /* Free all of the arguments found. */
373*a1acfa9bSespie if (arg1) free (arg1);
374*a1acfa9bSespie if (arg2) free (arg2);
375*a1acfa9bSespie if (arg3) free (arg3);
376*a1acfa9bSespie if (arg4) free (arg4);
377*a1acfa9bSespie if (arg5) free (arg5);
378*a1acfa9bSespie }
379*a1acfa9bSespie else
380*a1acfa9bSespie { /* Check that the next non-whitespace character is valid to follow
381*a1acfa9bSespie an xref (so Info readers can find the node names).
382*a1acfa9bSespie `input_text_offset' is pointing at the "}" which ended the xref
383*a1acfa9bSespie command. This is not used for @pxref or @ref, since we insert
384*a1acfa9bSespie the necessary punctuation above, if needed. */
385*a1acfa9bSespie int temp = next_nonwhitespace_character ();
386*a1acfa9bSespie
387*a1acfa9bSespie if (temp == -1)
388*a1acfa9bSespie warning (_("End of file reached while looking for `.' or `,'"));
389*a1acfa9bSespie else if (temp != '.' && temp != ',')
390*a1acfa9bSespie warning (_("`.' or `,' must follow @%s, not `%c'"), command, temp);
391*a1acfa9bSespie }
392*a1acfa9bSespie }
393*a1acfa9bSespie
394*a1acfa9bSespie void
cm_pxref(int arg)395*a1acfa9bSespie cm_pxref (int arg)
396*a1acfa9bSespie {
397*a1acfa9bSespie if (arg == START)
398*a1acfa9bSespie {
399*a1acfa9bSespie px_ref_flag++;
400*a1acfa9bSespie cm_xref (arg);
401*a1acfa9bSespie px_ref_flag--;
402*a1acfa9bSespie }
403*a1acfa9bSespie /* cm_xref isn't called with arg == END, which disables the code near
404*a1acfa9bSespie the end of cm_xref that checks for `.' or `,' after the
405*a1acfa9bSespie cross-reference. This is because cm_xref generates the required
406*a1acfa9bSespie character itself (when needed) if px_ref_flag is set. */
407*a1acfa9bSespie }
408*a1acfa9bSespie
409*a1acfa9bSespie void
cm_ref(int arg)410*a1acfa9bSespie cm_ref (int arg)
411*a1acfa9bSespie {
412*a1acfa9bSespie /* See the comments in cm_pxref about the checks for punctuation. */
413*a1acfa9bSespie if (arg == START)
414*a1acfa9bSespie {
415*a1acfa9bSespie ref_flag++;
416*a1acfa9bSespie cm_xref (arg);
417*a1acfa9bSespie ref_flag--;
418*a1acfa9bSespie }
419*a1acfa9bSespie }
420*a1acfa9bSespie
421*a1acfa9bSespie void
cm_inforef(int arg)422*a1acfa9bSespie cm_inforef (int arg)
423*a1acfa9bSespie {
424*a1acfa9bSespie if (arg == START)
425*a1acfa9bSespie {
426*a1acfa9bSespie char *node = get_xref_token (1); /* expands all macros in inforef */
427*a1acfa9bSespie char *pname = get_xref_token (0);
428*a1acfa9bSespie char *file = get_xref_token (0);
429*a1acfa9bSespie
430*a1acfa9bSespie /* (see comments at cm_xref). */
431*a1acfa9bSespie if (!*node)
432*a1acfa9bSespie line_error (_("First argument to @inforef may not be empty"));
433*a1acfa9bSespie
434*a1acfa9bSespie if (xml && !docbook)
435*a1acfa9bSespie {
436*a1acfa9bSespie xml_insert_element (INFOREF, START);
437*a1acfa9bSespie xml_insert_element (INFOREFNODENAME, START);
438*a1acfa9bSespie execute_string ("%s", node);
439*a1acfa9bSespie xml_insert_element (INFOREFNODENAME, END);
440*a1acfa9bSespie if (*pname)
441*a1acfa9bSespie {
442*a1acfa9bSespie xml_insert_element (INFOREFREFNAME, START);
443*a1acfa9bSespie execute_string ("%s", pname);
444*a1acfa9bSespie xml_insert_element (INFOREFREFNAME, END);
445*a1acfa9bSespie }
446*a1acfa9bSespie xml_insert_element (INFOREFINFONAME, START);
447*a1acfa9bSespie execute_string ("%s", file);
448*a1acfa9bSespie xml_insert_element (INFOREFINFONAME, END);
449*a1acfa9bSespie
450*a1acfa9bSespie xml_insert_element (INFOREF, END);
451*a1acfa9bSespie }
452*a1acfa9bSespie else if (html)
453*a1acfa9bSespie {
454*a1acfa9bSespie char *tem;
455*a1acfa9bSespie
456*a1acfa9bSespie add_word ((char *) _("see "));
457*a1acfa9bSespie /* html fixxme: revisit this */
458*a1acfa9bSespie add_html_elt ("<a href=");
459*a1acfa9bSespie if (splitting)
460*a1acfa9bSespie execute_string ("\"../%s/", file);
461*a1acfa9bSespie else
462*a1acfa9bSespie execute_string ("\"%s.html", file);
463*a1acfa9bSespie tem = expansion (node, 0);
464*a1acfa9bSespie add_anchor_name (tem, 1);
465*a1acfa9bSespie add_word ("\">");
466*a1acfa9bSespie execute_string ("%s", *pname ? pname : tem);
467*a1acfa9bSespie add_word ("</a>");
468*a1acfa9bSespie free (tem);
469*a1acfa9bSespie }
470*a1acfa9bSespie else
471*a1acfa9bSespie {
472*a1acfa9bSespie if (*pname)
473*a1acfa9bSespie execute_string ("*note %s: (%s)%s", pname, file, node);
474*a1acfa9bSespie else
475*a1acfa9bSespie execute_string ("*note (%s)%s::", file, node);
476*a1acfa9bSespie }
477*a1acfa9bSespie
478*a1acfa9bSespie free (node);
479*a1acfa9bSespie free (pname);
480*a1acfa9bSespie free (file);
481*a1acfa9bSespie }
482*a1acfa9bSespie }
483*a1acfa9bSespie
484*a1acfa9bSespie /* A URL reference. */
485*a1acfa9bSespie void
cm_uref(int arg)486*a1acfa9bSespie cm_uref (int arg)
487*a1acfa9bSespie {
488*a1acfa9bSespie if (arg == START)
489*a1acfa9bSespie {
490*a1acfa9bSespie extern int printing_index;
491*a1acfa9bSespie char *url = get_xref_token (1); /* expands all macros in uref */
492*a1acfa9bSespie char *desc = get_xref_token (0);
493*a1acfa9bSespie char *replacement = get_xref_token (0);
494*a1acfa9bSespie
495*a1acfa9bSespie if (docbook)
496*a1acfa9bSespie {
497*a1acfa9bSespie xml_insert_element_with_attribute (UREF, START, "url=\"%s\"",
498*a1acfa9bSespie text_expansion (url));
499*a1acfa9bSespie if (*replacement)
500*a1acfa9bSespie execute_string ("%s", replacement);
501*a1acfa9bSespie else if (*desc)
502*a1acfa9bSespie execute_string ("%s", desc);
503*a1acfa9bSespie else
504*a1acfa9bSespie execute_string ("%s", url);
505*a1acfa9bSespie xml_insert_element (UREF, END);
506*a1acfa9bSespie }
507*a1acfa9bSespie else if (xml)
508*a1acfa9bSespie {
509*a1acfa9bSespie xml_insert_element (UREF, START);
510*a1acfa9bSespie xml_insert_element (UREFURL, START);
511*a1acfa9bSespie execute_string ("%s", url);
512*a1acfa9bSespie xml_insert_element (UREFURL, END);
513*a1acfa9bSespie if (*desc)
514*a1acfa9bSespie {
515*a1acfa9bSespie xml_insert_element (UREFDESC, START);
516*a1acfa9bSespie execute_string ("%s", desc);
517*a1acfa9bSespie xml_insert_element (UREFDESC, END);
518*a1acfa9bSespie }
519*a1acfa9bSespie if (*replacement)
520*a1acfa9bSespie {
521*a1acfa9bSespie xml_insert_element (UREFREPLACEMENT, START);
522*a1acfa9bSespie execute_string ("%s", replacement);
523*a1acfa9bSespie xml_insert_element (UREFREPLACEMENT, END);
524*a1acfa9bSespie }
525*a1acfa9bSespie xml_insert_element (UREF, END);
526*a1acfa9bSespie }
527*a1acfa9bSespie else if (html)
528*a1acfa9bSespie { /* never need to show the url */
529*a1acfa9bSespie add_html_elt ("<a href=");
530*a1acfa9bSespie /* don't collapse `--' etc. in the url */
531*a1acfa9bSespie in_fixed_width_font++;
532*a1acfa9bSespie execute_string ("\"%s\"", url);
533*a1acfa9bSespie in_fixed_width_font--;
534*a1acfa9bSespie add_word (">");
535*a1acfa9bSespie execute_string ("%s", *replacement ? replacement
536*a1acfa9bSespie : (*desc ? desc : url));
537*a1acfa9bSespie add_word ("</a>");
538*a1acfa9bSespie }
539*a1acfa9bSespie else if (*replacement) /* do not show the url */
540*a1acfa9bSespie execute_string ("%s", replacement);
541*a1acfa9bSespie else if (*desc) /* show both text and url */
542*a1acfa9bSespie {
543*a1acfa9bSespie execute_string ("%s ", desc);
544*a1acfa9bSespie in_fixed_width_font++;
545*a1acfa9bSespie execute_string ("(%s)", url);
546*a1acfa9bSespie in_fixed_width_font--;
547*a1acfa9bSespie }
548*a1acfa9bSespie else /* no text at all, so have the url to show */
549*a1acfa9bSespie {
550*a1acfa9bSespie in_fixed_width_font++;
551*a1acfa9bSespie execute_string ("%s%s%s",
552*a1acfa9bSespie printing_index ? "" : "`",
553*a1acfa9bSespie url,
554*a1acfa9bSespie printing_index ? "" : "'");
555*a1acfa9bSespie in_fixed_width_font--;
556*a1acfa9bSespie }
557*a1acfa9bSespie if (url)
558*a1acfa9bSespie free (url);
559*a1acfa9bSespie if (desc)
560*a1acfa9bSespie free (desc);
561*a1acfa9bSespie if (replacement)
562*a1acfa9bSespie free (replacement);
563*a1acfa9bSespie }
564*a1acfa9bSespie }
565*a1acfa9bSespie
566*a1acfa9bSespie /* An email reference. */
567*a1acfa9bSespie void
cm_email(int arg)568*a1acfa9bSespie cm_email (int arg)
569*a1acfa9bSespie {
570*a1acfa9bSespie if (arg == START)
571*a1acfa9bSespie {
572*a1acfa9bSespie char *addr = get_xref_token (1); /* expands all macros in email */
573*a1acfa9bSespie char *name = get_xref_token (0);
574*a1acfa9bSespie
575*a1acfa9bSespie if (xml && docbook)
576*a1acfa9bSespie {
577*a1acfa9bSespie xml_insert_element_with_attribute (EMAIL, START, "url=\"mailto:%s\"", addr);
578*a1acfa9bSespie if (*name)
579*a1acfa9bSespie execute_string ("%s", name);
580*a1acfa9bSespie xml_insert_element (EMAIL, END);
581*a1acfa9bSespie }
582*a1acfa9bSespie else if (xml)
583*a1acfa9bSespie {
584*a1acfa9bSespie xml_insert_element (EMAIL, START);
585*a1acfa9bSespie xml_insert_element (EMAILADDRESS, START);
586*a1acfa9bSespie execute_string ("%s", addr);
587*a1acfa9bSespie xml_insert_element (EMAILADDRESS, END);
588*a1acfa9bSespie if (*name)
589*a1acfa9bSespie {
590*a1acfa9bSespie xml_insert_element (EMAILNAME, START);
591*a1acfa9bSespie execute_string ("%s", name);
592*a1acfa9bSespie xml_insert_element (EMAILNAME, END);
593*a1acfa9bSespie }
594*a1acfa9bSespie xml_insert_element (EMAIL, END);
595*a1acfa9bSespie }
596*a1acfa9bSespie else if (html)
597*a1acfa9bSespie {
598*a1acfa9bSespie add_html_elt ("<a href=");
599*a1acfa9bSespie /* don't collapse `--' etc. in the address */
600*a1acfa9bSespie in_fixed_width_font++;
601*a1acfa9bSespie execute_string ("\"mailto:%s\"", addr);
602*a1acfa9bSespie in_fixed_width_font--;
603*a1acfa9bSespie add_word (">");
604*a1acfa9bSespie execute_string ("%s", *name ? name : addr);
605*a1acfa9bSespie add_word ("</a>");
606*a1acfa9bSespie }
607*a1acfa9bSespie else
608*a1acfa9bSespie {
609*a1acfa9bSespie execute_string ("%s%s", name, *name ? " " : "");
610*a1acfa9bSespie in_fixed_width_font++;
611*a1acfa9bSespie execute_string ("<%s>", addr);
612*a1acfa9bSespie in_fixed_width_font--;
613*a1acfa9bSespie }
614*a1acfa9bSespie
615*a1acfa9bSespie if (addr)
616*a1acfa9bSespie free (addr);
617*a1acfa9bSespie if (name)
618*a1acfa9bSespie free (name);
619*a1acfa9bSespie }
620*a1acfa9bSespie }
621