This is the mail archive of the
docbook-apps@lists.oasis-open.org
mailing list .
bookmark and index problems (and a partial solution)
- From: dgatwood at mac dot com
- To: docbook-apps at lists dot oasis-open dot org
- Date: Wed, 06 Nov 2002 15:59:15 -0800
- Subject: DOCBOOK-APPS: bookmark and index problems (and a partial solution)
I'm currently using openjade/docbook-dsssl to transform docbook xml
into PDFs. I'm using the TeX backend with jadetex and pdfjadetex.
Almost everything works, but there are a few nagging problems that I
need to work around (or ideally fix).
My first problem has been reported here before (I saw it in the
archive), but no one could reproduce it or suggest a fix. The PDF
bookmarks aren't nesting properly. Specifically, sections are being
promoted to the top level as if they were chapters. I haven't been
able to work around this yet. Any suggestions?
My next problem is that certain cross-references never get resolved.
Specifically, TeX can't resolve any cross-references that resulted from
a ulink that points to a title element, to an indexterm tag that
appears within a title element, or to an indexterm tag that appears
within an entry tag in a table or informaltable. I tried
unsuccessfully to work around this in a very quick-and-dirty fashion
with some changes in the customization layer, but I ended up breaking
other things unacceptably in the process. Any ideas?
My third problem, which I've pretty much fixed, is with duplication of
page numbers in the index. The fix is in three parts: a new perl
indexing tool (which is too long to include here), some jadetex.cfg
macros, and some customization layer additions.
Instead of making the primaryie (or secondaryie or...) tag look like
"word, ulink, ulink-ulink, ulink", my indexing tool outputs it as
"word, <quote><ulink/><quote><ulink/><ulink/></quote><ulink/></quote>".
In other words, pairs are wrapped in a quote element so that they can
be easily processed together, and the whole list of links are wrapped
in a quote element to allow for easy insertion of some TeX code to
reset certain counters before processing the list.
The use of quote tags is, of course, completely unnecessary, but it
made the scheme portions much simpler so that I could focus on the
nightmarish TeX macros. Feel free to make this work for the normal
indexing tool's output if anyone is feeling particularly masochistic.
The only nasty quirk is that it doesn't handle undefined references too
gracefully, i.e. you get two sets of "??" instead of one. Yet another
reason to make sure one doesn't get undefined references....
Anyway, here are the macros and customization layer changes. (Yes, I
know that the DAGsetstartpage and DAGsetendpage should ideally just be
a single function. I'll probably clean that up this afternoon.)
Thoughts?
In jadetex.cfg:
---------------------------------------------------------------------
\newcounter{DAGlastpage}
\newboolean{DAGlastWasPair}
\newcount{\DAGshow}
\newcounter{DAGstartpage}
\newcounter{DAGendpage}
\makeatletter
\def\DAGsetstartpage#1{\expandafter\DAGsetstartpagesub\csname
p@#1\endcsname{#1}}
\def\@qqq{qqq}
\def\DAGsetstartpagesub#1#2{%
\ifx#1\relax
\immediate\write\@mainaux{\string\pagelabel{#2}{qqq}}%
\protect\G@refundefinedtrue
\nfss@text{\reset@font\bfseries ??}%
\@latex@warning{Reference `#2' on page \thepage \space
undefined}%
\else
\ifx#1\@qqq
\protect\G@refundefinedtrue
\nfss@text{\reset@font\bfseries ??}%
\@latex@warning{Reference `#2' on page \thepage \space undefined}%
\else
\setcounter{DAGstartpage}{#1}%
\fi
\fi
}
% insert DAGsetendpage here.
\def\DAGsetendpage#1{\expandafter\DAGsetendpagesub\csname
p@#1\endcsname{#1}}
\def\@qqq{qqq}
\def\DAGsetendpagesub#1#2{%
\ifx#1\relax
\immediate\write\@mainaux{\string\pagelabel{#2}{qqq}}%
\protect\G@refundefinedtrue
\nfss@text{\reset@font\bfseries ??}%
\@latex@warning{Reference `#2' on page \thepage \space
undefined}%
\else
\ifx#1\@qqq
\protect\G@refundefinedtrue
\nfss@text{\reset@font\bfseries ??}%
\@latex@warning{Reference `#2' on page \thepage \space undefined}%
\else
\setcounter{DAGendpage}{#1}%
\fi
\fi
}
\makeatother
---------------------------------------------------------------------
in the customization layer:
---------------------------------------------------------------------
(element (primaryie quote)
(make sequence
(make formatting-instruction data: (string-append
"\\setcounter{DAGlastpage}{-2}"))
(make formatting-instruction data: (string-append
"\\setcounter{DAGstartpage}{-1}"))
(make formatting-instruction data: (string-append
"\\setcounter{DAGendpage}{-1}"))
(make formatting-instruction data: (string-append
"\\setboolean{DAGlastWasPair}{false}\\DAGshow=1"))
(process-children)))
(element (secondaryie quote)
(make sequence
(make formatting-instruction data: (string-append
"\\setcounter{DAGlastpage}{-2}"))
(make formatting-instruction data: (string-append
"\\setcounter{DAGstartpage}{-1}"))
(make formatting-instruction data: (string-append
"\\setcounter{DAGendpage}{-1}"))
(make formatting-instruction data: (string-append
"\\setboolean{DAGlastWasPair}{false}\\DAGshow=1"))
(process-children)))
(element (tertiaryie quote)
(make sequence
(make formatting-instruction data: (string-append
"\\setcounter{DAGlastpage}{0}"))
(make formatting-instruction data: (string-append
"\\setcounter{DAGstartpage}{1}"))
(make formatting-instruction data: (string-append
"\\setcounter{DAGendpage}{1}"))
(make formatting-instruction data: (string-append
"\\setboolean{DAGlastWasPair}{false}\\DAGshow=1"))
(process-children)))
(element (primaryie quote ulink)
(make sequence
;; (make formatting-instruction data: (string-append
"\\arabic{DAGlastpage}xxx"))
(make formatting-instruction data: (string-append "\\def\\Label{"
(attribute-string (normalize "role") (current-node)) "}"))
(make formatting-instruction data: (string-append
"\\makeatletter\\ifx\\Label\\@empty"))
(make formatting-instruction data: (string-append
"\\DAGsetstartpage{\\Element}"))
(make formatting-instruction data: (string-append
"\\else\\DAGsetstartpage{\\Label}"))
(make formatting-instruction data: (string-append
"\\fi\\makeatother\\DAGshow=1"))
(make formatting-instruction data: (string-append
"\\ifthenelse{\\value{DAGstartpage}=\\value{DAGlastpage}}{"))
(make formatting-instruction data: (string-append
"\\DAGshow=0}{\\DAGshow=1\\setboolean{DAGlastWasPair}{false}"))
(make formatting-instruction data: (string-append
"\\setcounter{DAGlastpage}{\\value{DAGstartpage}}}"))
(make formatting-instruction data: (string-append
"\\ifthenelse{\\DAGshow=1}{"))
(literal ", ")
;; (literal "(")
;; (make formatting-instruction data: (string-append
"\\arabic{DAGstartpage}:\\arabic{DAGlastpage}"))
;; (literal ")")
(indexentry-link (current-node))
(make formatting-instruction data: (string-append "}{}"))))
(element (secondaryie quote ulink)
(make sequence
;; (make formatting-instruction data: (string-append
"\\arabic{DAGlastpage}xxx"))
(make formatting-instruction data: (string-append "\\def\\Label{"
(attribute-string (normalize "role") (current-node)) "}"))
(make formatting-instruction data: (string-append
"\\makeatletter\\ifx\\Label\\@empty"))
(make formatting-instruction data: (string-append
"\\DAGsetstartpage{\\Element}"))
(make formatting-instruction data: (string-append
"\\else\\DAGsetstartpage{\\Label}"))
(make formatting-instruction data: (string-append
"\\fi\\makeatother\\DAGshow=1"))
(make formatting-instruction data: (string-append
"\\ifthenelse{\\value{DAGstartpage}=\\value{DAGlastpage}}{"))
(make formatting-instruction data: (string-append
"\\DAGshow=0}{\\DAGshow=1\\setboolean{DAGlastWasPair}{false}"))
(make formatting-instruction data: (string-append
"\\setcounter{DAGlastpage}{\\value{DAGstartpage}}}"))
(make formatting-instruction data: (string-append
"\\ifthenelse{\\DAGshow=1}{"))
(literal ", ")
;; (literal "(")
;; (make formatting-instruction data: (string-append
"\\arabic{DAGstartpage}:\\arabic{DAGlastpage}"))
;; (literal ")")
(indexentry-link (current-node))
(make formatting-instruction data: (string-append "}{}"))))
(element (tertiaryie quote ulink)
(make sequence
;; (make formatting-instruction data: (string-append
"\\arabic{DAGlastpage}xxx"))
(make formatting-instruction data: (string-append "\\def\\Label{"
(attribute-string (normalize "role") (current-node)) "}"))
(make formatting-instruction data: (string-append
"\\makeatletter\\ifx\\Label\\@empty"))
(make formatting-instruction data: (string-append
"\\DAGsetstartpage{\\Element}"))
(make formatting-instruction data: (string-append
"\\else\\DAGsetstartpage{\\Label}"))
(make formatting-instruction data: (string-append
"\\fi\\makeatother\\DAGshow=1"))
(make formatting-instruction data: (string-append
"\\ifthenelse{\\value{DAGstartpage}=\\value{DAGlastpage}}{"))
(make formatting-instruction data: (string-append
"\\DAGshow=0}{\\DAGshow=1\\setboolean{DAGlastWasPair}{false}"))
(make formatting-instruction data: (string-append
"\\setcounter{DAGlastpage}{\\value{DAGstartpage}}}"))
(make formatting-instruction data: (string-append
"\\ifthenelse{\\DAGshow=1}{"))
(literal ", ")
;; (literal "(")
;; (make formatting-instruction data: (string-append
"\\arabic{DAGstartpage}:\\arabic{DAGlastpage}"))
;; (literal ")")
(indexentry-link (current-node))
(make formatting-instruction data: (string-append "}{}"))))
;; Here there be dragons
(element (primaryie quote quote)
(let ((links (select-elements (descendants (current-node)) "ulink")))
(let ((firstlink (node-list-first links)))
(let ((lastlink (node-list-first (node-list-rest links))))
(make sequence
(make formatting-instruction data: (string-append "\\def\\Label{"
(attribute-string (normalize "role") firstlink) "}"))
(make formatting-instruction data: (string-append
"\\makeatletter\\ifx\\Label\\@empty"))
(make formatting-instruction data: (string-append
"\\DAGsetstartpage{\\Element}"))
(make formatting-instruction data: (string-append
"\\else\\DAGsetstartpage{\\Label}"))
(make formatting-instruction data: (string-append
"\\fi\\makeatother\\DAGshow=1"))
(make formatting-instruction data: (string-append "\\def\\Label{"
(attribute-string (normalize "role") lastlink) "}"))
(make formatting-instruction data: (string-append
"\\ifx\\Label\\@empty"))
(make formatting-instruction data: (string-append
"\\DAGsetendpage{\\Element}"))
(make formatting-instruction data: (string-append
"\\else\\DAGsetendpage{\\Label}"))
(make formatting-instruction data: (string-append "\\fi"))
(make formatting-instruction data: (string-append
"\\ifthenelse{\\value{DAGendpage}=\\value{DAGlastpage}}{"))
(make formatting-instruction data: (string-append
"\\DAGshow=0}{\\ifthenelse{\\value{DAGstartpage}=\\value{DAGendpage}}{")
)
(make formatting-instruction data: (string-append
"\\DAGshow=1\\setboolean{DAGlastWasPair}{false}}{\\ifthenelse{\\value{DA
Gstartpage}=\\value{DAGlastpage}}{"))
(make formatting-instruction data: (string-append
"\\ifthenelse{\\boolean{DAGlastWasPair}}{\\DAGshow=2\\setboolean{DAGlast
WasPair}{false}}{"))
(make formatting-instruction data: (string-append
"\\DAGshow=3\\setboolean{DAGlastWasPair}{true}}}{\\DAGshow=2\\setboolean
{DAGlastWasPair}{true}}}}"))
(make formatting-instruction data: (string-append
"\\setcounter{DAGlastpage}{\\value{DAGendpage}}"))
(make formatting-instruction data: (string-append
"\\ifthenelse{\\DAGshow=1}{"))
(literal ", ")
(indexentry-link firstlink)
(make formatting-instruction data: (string-append
"}{}\\ifthenelse{\\DAGshow=2}{"))
(literal ", ")
(indexentry-link firstlink)
(make formatting-instruction data: (string-append "}{}"))
(make formatting-instruction data: (string-append
"\\ifthenelse{\\DAGshow=2}{"))
(literal "-")
(indexentry-link lastlink)
(make formatting-instruction data: (string-append
"}{}\\ifthenelse{\\DAGshow=3}{"))
(literal "-")
(indexentry-link lastlink)
(make formatting-instruction data: (string-append "}{}"))
)
)
)
)
)
(element (secondaryie quote quote)
(let ((links (select-elements (descendants (current-node)) "ulink")))
(let ((firstlink (node-list-first links)))
(let ((lastlink (node-list-first (node-list-rest links))))
(make sequence
(make formatting-instruction data: (string-append "\\def\\Label{"
(attribute-string (normalize "role") firstlink) "}"))
(make formatting-instruction data: (string-append
"\\makeatletter\\ifx\\Label\\@empty"))
(make formatting-instruction data: (string-append
"\\DAGsetstartpage{\\Element}"))
(make formatting-instruction data: (string-append
"\\else\\DAGsetstartpage{\\Label}"))
(make formatting-instruction data: (string-append
"\\fi\\makeatother\\DAGshow=1"))
(make formatting-instruction data: (string-append "\\def\\Label{"
(attribute-string (normalize "role") lastlink) "}"))
(make formatting-instruction data: (string-append
"\\ifx\\Label\\@empty"))
(make formatting-instruction data: (string-append
"\\DAGsetendpage{\\Element}"))
(make formatting-instruction data: (string-append
"\\else\\DAGsetendpage{\\Label}"))
(make formatting-instruction data: (string-append "\\fi"))
(make formatting-instruction data: (string-append
"\\ifthenelse{\\value{DAGendpage}=\\value{DAGlastpage}}{"))
(make formatting-instruction data: (string-append
"\\DAGshow=0}{\\ifthenelse{\\value{DAGstartpage}=\\value{DAGendpage}}{")
)
(make formatting-instruction data: (string-append
"\\DAGshow=1\\setboolean{DAGlastWasPair}{false}}{\\ifthenelse{\\value{DA
Gstartpage}=\\value{DAGlastpage}}{"))
(make formatting-instruction data: (string-append
"\\ifthenelse{\\boolean{DAGlastWasPair}}{\\DAGshow=2\\setboolean{DAGlast
WasPair}{false}}{"))
(make formatting-instruction data: (string-append
"\\DAGshow=3\\setboolean{DAGlastWasPair}{true}}}{\\DAGshow=2\\setboolean
{DAGlastWasPair}{true}}}}"))
(make formatting-instruction data: (string-append
"\\setcounter{DAGlastpage}{\\value{DAGendpage}}"))
(make formatting-instruction data: (string-append
"\\ifthenelse{\\DAGshow=1}{"))
(literal ", ")
(indexentry-link firstlink)
(make formatting-instruction data: (string-append
"}{}\\ifthenelse{\\DAGshow=2}{"))
(literal ", ")
(indexentry-link firstlink)
(make formatting-instruction data: (string-append "}{}"))
(make formatting-instruction data: (string-append
"\\ifthenelse{\\DAGshow=2}{"))
(literal "-")
(indexentry-link lastlink)
(make formatting-instruction data: (string-append
"}{}\\ifthenelse{\\DAGshow=3}{"))
(literal "-")
(indexentry-link lastlink)
(make formatting-instruction data: (string-append "}{}"))
)
)
)
)
)
(element (tertiaryie quote quote)
(let ((links (select-elements (descendants (current-node)) "ulink")))
(let ((firstlink (node-list-first links)))
(let ((lastlink (node-list-first (node-list-rest links))))
(make sequence
(make formatting-instruction data: (string-append "\\def\\Label{"
(attribute-string (normalize "role") firstlink) "}"))
(make formatting-instruction data: (string-append
"\\makeatletter\\ifx\\Label\\@empty"))
(make formatting-instruction data: (string-append
"\\DAGsetstartpage{\\Element}"))
(make formatting-instruction data: (string-append
"\\else\\DAGsetstartpage{\\Label}"))
(make formatting-instruction data: (string-append
"\\fi\\makeatother\\DAGshow=1"))
(make formatting-instruction data: (string-append "\\def\\Label{"
(attribute-string (normalize "role") lastlink) "}"))
(make formatting-instruction data: (string-append
"\\ifx\\Label\\@empty"))
(make formatting-instruction data: (string-append
"\\DAGsetendpage{\\Element}"))
(make formatting-instruction data: (string-append
"\\else\\DAGsetendpage{\\Label}"))
(make formatting-instruction data: (string-append "\\fi"))
(make formatting-instruction data: (string-append
"\\ifthenelse{\\value{DAGendpage}=\\value{DAGlastpage}}{"))
(make formatting-instruction data: (string-append
"\\DAGshow=0}{\\ifthenelse{\\value{DAGstartpage}=\\value{DAGendpage}}{")
)
(make formatting-instruction data: (string-append
"\\DAGshow=1\\setboolean{DAGlastWasPair}{false}}{\\ifthenelse{\\value{DA
Gstartpage}=\\value{DAGlastpage}}{"))
(make formatting-instruction data: (string-append
"\\ifthenelse{\\boolean{DAGlastWasPair}}{\\DAGshow=2\\setboolean{DAGlast
WasPair}{false}}{"))
(make formatting-instruction data: (string-append
"\\DAGshow=3\\setboolean{DAGlastWasPair}{true}}}{\\DAGshow=2\\setboolean
{DAGlastWasPair}{true}}}}"))
(make formatting-instruction data: (string-append
"\\setcounter{DAGlastpage}{\\value{DAGendpage}}"))
(make formatting-instruction data: (string-append
"\\ifthenelse{\\DAGshow=1}{"))
(literal ", ")
(indexentry-link firstlink)
(make formatting-instruction data: (string-append
"}{}\\ifthenelse{\\DAGshow=2}{"))
(literal ", ")
(indexentry-link firstlink)
(make formatting-instruction data: (string-append "}{}"))
(make formatting-instruction data: (string-append
"\\ifthenelse{\\DAGshow=2}{"))
(literal "-")
(indexentry-link lastlink)
(make formatting-instruction data: (string-append
"}{}\\ifthenelse{\\DAGshow=3}{"))
(literal "-")
(indexentry-link lastlink)
(make formatting-instruction data: (string-append "}{}"))
)
)
)
)
)
---------------------------------------------------------------------
David A. Gatwood
Kernel Doc Geek
Apple