Re: Allow variables to be referenced from @scope="peer" maps


David Hollis
 

Hi Chris, Eliot,

It's obvious that the two products and their documentation share an environment because there is a mapref from one to the other. With that in mind, I'm struggling to understand why you are not keen to use one of the alternatives that you mention.

It might seem like a good idea for each product to manage its own keys and content, but surely that leads to product silos? One of the strengths of DITA is that it breaks silos down.

I'm also a little concerned that the solution Eliot suggests could lead to quite complicated key processing?

Maybe I'm missing something?

David

To implement this you have to do all the preprocessing on all the peer maps referenced so that you know what the key space in each referenced peer map is.

That would be very inefficient in a naïve implementation because every time you ran map A that references peer B you'd also have to process peer B.

An obvious solution is to implement some kind of "key service" that maintains a persistent resolved key space for each map such that a processor can just ask for the resolved value of a given key in a given map. Of course, there are a number of potential issues here, including: how do you know when to update your persistent store? How do you handle runtime conditions, in particular, active filtering settings (DITAVAL)?

You start to see that this is the domain of content management where you have systems that have general knowledge of bodies of DITA content, track their status, versions, etc.

A relatively simplistic key service probably wouldn't be that difficult to implement (and my now-fallow DITA for Small Teams link manager application was working towards being a key service, among other things) but probably way outside the scope of the Open Toolkit project.

I've thought for a while that it would be useful to have a general key access API that defines the minimum features for DITA key stores. Given such an API a tool like Open Toolkit could have general key store requests that are then resolved against whatever key store you happen to have made a available, if any. A REST API could be implemented in any number of common technologies (Java, JavaScript, XQuery, etc.).

Another brute force solution would be to have Open Toolkit write out an easy-to-access representation of a given publication's key space whenever it's processed (or on request as a runtime option). When resolving peer references, could then try to find the key space data file and use it if found. This would leave it up to users to make sure that the key spaces were up to date, basically, processing every publication once and then processing them a second time to ensure they've used up to date key spaces from any peer publications.

Essentially, using peer maps takes you from having a collection of otherwise-independent publications to having a system of interdependent publications. As soon as you have that you have unavoidable management problems inherent in trying to produce deliverables from these interdependent publications, problems that are solvable but require some kind of content management system that maintains knowledge about all the publications, their components, their versions, their relationships to each other, provides processing optimizations (indexes, caches, etc.).

Or you have to create ad-hoc solutions that take advantage of simplifying assumptions you can make about your content or constraints you can impose on your content (and its authors). For example, for your purposes, it might be sufficient to have some kind of script that reads peer maps and generates sets of key definitions to be used in the referencing publications as local-scope key definitions. That's relatively easy to do but you then have to keep these generated key definition sets up to date as the publications are modified.

Cheers,

E.

--
Eliot Kimber
http://contrext.com


On 1/21/21, 5:39 PM, "Chris Papademetrious" <main@dita-users.groups.io on behalf of chrispitude@gmail.com> wrote:

Hi everyone,

This is an FYI for an enhancement request I filed for the DITA-OT, in case anyone else would find it useful too:

Allow variables to be referenced from @scope="peer" maps #3685 <https://github.com/dita-ot/dita-ot/issues/3685>

The text is as follows:
Description
I have two books, bookA and bookB. bookA references bookB as a @scope="peer" map:

<map>
<title>Book A Map</title>
<mapref href="bookB.ditamap" scope="peer" keyscope="bookB" processing-role="resource-only"/>
<!-- ^^^^^^^^^^^^^ ^^^^ ^^^^^
...
</map>


In a topic in bookA, I would like to reference a "Product" variable from bookB:

<p>BookB provides more information on <ph keyref="bookB.Product"/>.</p>
<!-- ^^^^^^^^^^^^^ -->

Unfortunately, @scope="peer" suppresses all bookB content from the bookA transformation - topic content and variable definitions.

This enhancement requests that keyscoped @scope="peer" maps pull their keys (but not topics) from the referenced map into the current map.

To test this, unarchive the following testcase:

#### ditaot_keys_from_peer_books.zip ####

then run

dita -i bookA.ditamap -i bookA.ditamap -f html5 -o out
Possible Solution
I tried implementing a proof-of-concept solution, which you can see in the testcase directory as follows:

diff maprefImpl.xsl.ORIG maprefImpl.xsl.NEW

The attempt was to remember when we're in a @scope="peer-with-keys" context, that would keep all mapref contents except topic references. Unfortunately, even this naive attempt did not work - the variables still did not resolve, and bookB topics still showed up in the bookA output directory. (You will need to change @scope="peer" to @scope="peer-with-keys" to try this proof-of-concept on the provided testcase.)
Potential Alternatives
I am aware of warehouse topics, shared key definition files, etc. However, those are not a good fit for this need. This enhancement is for the case where we're already referencing a peer book and that book already defines the variables we want (for its own use), and we simply want to access them as well.

Join main@dita-users.groups.io to automatically receive all group messages.