[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]
Subject: Re: [docbook-apps] Spurious matches of CaseB/CaseF in select.olink.key.in.lang
On Wednesday, August 28, 2013 03:27:24 PM Bob Stayton wrote:
> Hi Alexey,
> Yes, there is some value in $prefer.internal.olinks for some people. In
> this section of my book:
> there is this description of the $prefer.internal.olink parameter:
> "Another feature to support modular source files is the
> prefer.internal.olink stylesheet parameter. This is useful when you reuse a
> content module in more than one document. If you cross reference to such a
> module, you do not want to open another document if the content exists in
> the current document. Setting prefer.internal.olink to 1 causes the
> stylesheet to first test the current document's olink data to see if it has
> the id or xml:id value of the targetptr. If it does not, then the stylesheet
> falls back to the requested targetdoc data set."
I read your book - and, by the way, thank you very much for it!
And this paragraph was exactly why I first configured $prefer.internal.olink to 1: I read the sentence "if the content exists in the current document" as "the content identified by @targetdoc/@targetptr is in the current document". I assumed the stylesheets would only optimize the <olink>s to internal links in PDF output if this parameter is set to 1 - which, as I found out, is not the case - they are optimized to internal links even if this parameter is set to 0.
> So if $prefer.internal.olink = 1, then the olink's targetdoc attribute may
> be overridden by the value of $current.docid, if the target id is in the
> current document. I think that is why it links to itself in your case, even
> when the targetdoc attribute seems to point to another document. If you
> don't want that override behavior because in your case the elements with
> the same id have different content, then set $prefer.internal.olinks = 0.
> In general, the use case for $prefer.internal.olinks=1 is when you are
> reusing source modules that don't otherwise have duplicate id values, and
> you want the olinks to resolve close to home if possible. That's pretty
> specialized, so the param is set to zero by default.
I see the point. I think that purpose is mostly covered by CaseC in the olink.xsl:
<!-- targetdoc.att = blank
targetptr.att = not blank
current.docid = not blank
That is, if you're linking to some content that exists in (is shared among) multiple documents within the same linkage domain, including the current document, you could just omit the @targetdoc attribute from <olink> entirely and each of such documents would resolve to the instance of that content in the linking document itself.
The only corner case not covered by CaseC is when you have, say, three documents. All documents include common source 1.xml, and documents A&B include 2.xml, and 1.xml wants to refer to some material in 2.xml. So that link resolution logic would be "if 2.xml was included in current doc, link locally; otherwise, link to instance of 2.xml included in document A". So, documents A&B would have local links, and document C would link to document A.
> One clarification: the value of targetdoc is independent of the value of @id
> on the root element of the source document. You may make them the same by
> convention if that is convenient, but the olink system does not assume
> that. The targetdoc values are only resolved in the olinkdb.xml file, by
> matching an <olink> element's @targetdoc in the source file to a <document>
> @targetdoc in the olinkdb.xml database file. So when you say:
> > even though the document ID is clearly different
> I cannot tell if you are referring to the id attribute value in <book
> id="doc1">, which is irrelevant. What is important is if there is a
> <document targetdoc="doc1"> in your olink database. I suspect there is, but
> I want to make that distinction.
Yes, I know that - and I am following your book's suggestion of using /*/@id as the document ID. In fact, my target database file is also automatically generated from the documents' XMLs, so the build system enforces that rule.
> Regarding your question 1, Cases A and B (and E and F) may produce different
> results, and so the template keeps them separate so that the debug messages
> can distinguish between the cases.
> Regarding your question 2, "internal" here means internal to the current
> source document being processed, and "external" means in another source
> document processed at a different time. It is a logical distinction at the
> source level. They may not be in the same physical source file: a document
> made up of many Xincluded modules would consider all ids found *after*
> resolution of Xincludes to be internal to the resolved document.
> In FO output, links internal to the PDF file use <fo:basic-link
> internal-destination="id">, while external links use <fo:basic-link
> external-destination="url(...)". Linking among the chunks of a single
> source document would still be considered "internal" by this usage. The
> distinction for an external document is that the baseuri value from the
> olinkdb.xml file for that external document is added to the href value.
And the stylesheets (at least as of 1.78.0) are smart enough to convert <olinks> to <fo:basic-link infernal-destination="..."> even with $prefer.internal.olink=0.
Thanks for the explanation,
> I hope I answered your questions. If not, feel free to ask more.
> Bob Stayton
> Sagehill Enterprises
> From: Alexey Neyman
> Sent: Wednesday, August 28, 2013 1:29 PM
> To: DocBook Apps
> Subject: [docbook-apps] Spurious matches of CaseB/CaseF in
> Hi all,
> I have a couple of documents with some element IDs overlapping. For example,
> both have "ch-overview" ID for the first chapter. I tried using
> $prefer.internal.olink, but it seems to misbehave on such links: it links to
> internal ID even if @targetdoc points to another document. For example:
> <book id="doc1">
> <chapter id="ch-overview">
> <olink targetdoc="doc2" targetptr="ch-overview"/>
> links to itself, even though the document ID is clearly different. The
> reason is that select.olink.key.in.lang template has CaseB/CaseF variables
> that ignore @targetdoc from <olink/> and use $current.docid instead, and
> cases B/F have higher precedence than cases A/E (that use olink/@targetdoc).
> So, what is the purpose of $prefer.internal.olink, given that:
> 1. If a check for $current.docid = $targetdoc.att is added to cases B/F (to
> respect the document ID on the pointer), they become equivalent to cases
> 2. Even with $prefer.internal.olink = 0, links within the current document
> are converted to internal links by olink.as.linkend template in fo/xref.xsl
> (in the PDF output). I haven't experimented with HTML output - but I am not
> sure what would be the notion of "external" vs. "internal" link in, say,
> chunked HTML document.
> Is $prefer.internal.olink some vestige of the past that should've been
> removed, or am I missing some value in it?