On 1/13/2017 6:10 PM, MF wrote:
Hello list, please see this: ---------------------------------------- \startbuffer[test] <text> <div> <p>In this page there is a <name idref="id1">cat</name>, a <name idref="id2">dog</name> and a <name idref="id3">horse</name>.</p> </div> <div> <p>In this page there's only a <name idref="id2">fox terrier</name>.</p> </div> <div> <p>In this page you find a <name idref="id1">persian cat</name> and a <name idref="id3">horse</name>.</p> </div> <index> <entry id="id1" data-sort="cat">Cat</entry> <entry id="id2" data-sort="dog">Dog</entry> <entry id="id3" data-sort="horse">Horse</entry> </index> </text> \stopbuffer
\defineregister[Animal][Animals]
\startxmlsetups xml:mysetup \xmlsetsetup{#1}{text|div|p|name|i|index|entry}{xml:*} \stopxmlsetups
\xmlregistersetup{xml:mysetup}
\startxmlsetups xml:text \xmlflush{#1} \stopxmlsetups
\startxmlsetups xml:div \xmlflush{#1}\page \stopxmlsetups
\startxmlsetups xml:p \xmlflush{#1}\par \stopxmlsetups
\startxmlsetups xml:name
\Animal[\xmlfunction{#1}{sortKeyOfAnimal}]{\xmlfunction{#1}{indexEntryF orAnimal}}{\bf\xmlflush{#1}} \stopxmlsetups
\startxmlsetups xml:i \dontleavehmode{\em\xmlflush{#1}} \stopxmlsetups
\startxmlsetups xml:index \placeregister[Animal] \stopxmlsetups
\startxmlsetups xml:entry \xmlflush{#1} \stopxmlsetups
\startluacode userdata = userdata or {} userdata.animals = {}
function userdata.findAnimal(t) local idref = xml.attribute(t, "", "idref") local animal = userdata.animals[idref] if not animal then local entry = xml.first(t, "ancestor::text//index/entry[@id = '" .. idref .. "']") local sortkey = xml.attribute(entry, "", "data-sort") animal = {} if sortkey and entry then animal.id = idref animal.sortkey = sortkey animal.entry = entry userdata.animals[idref] = animal end end return animal end
function xml.functions.sortKeyOfAnimal(t) local animal = userdata.findAnimal(t) if animal.sortkey then context(animal.sortkey) else context("zzz") end end
function xml.functions.indexEntryForAnimal(t) local animal = userdata.findAnimal(t) if animal.entry then lxml.flush(animal.entry) end end \stopluacode
\starttext \xmlprocessbuffer{main}{test}{} \stoptext ----------------------------------------
It's a simplified version of the documents I'm working on: - it's XML - the index entries are already defined - the entries of the index have an "id" attribute and they are referred in the main text with an "idref" attribute - \Animal[sortkey]{entry} is used to index the terms in the text - "sortkey" and "entry" are calculated by the Lua code, that reads the idref and finds the right entry inside the <index> element (it also caches the entries)
Context has no problems with that code, but the index I get (page 4) is something like this:
c Cat 1 Cat 3
d Dog 1 Dog 2
h Horse 1 Horse 3
What I'd expect is instead:
c Cat 1,3
d Dog 1,2
h Horse 1,3
Could you explain me why everytime I get a distinct entry in the index, even when the sort key and the entry are the same? (or I only think they are, but they are not really)
Take a look at the tuc file ... ["list"]={ { "\\xmlfunction {main::6}{indexEntryForAnimal}", "dog" }, }, ["list"]={ { "\\xmlfunction {main::10}{indexEntryForAnimal}", "dog" }, }, so although the key is the same the entry isn't and we can't know which one to choose so we consider them variants (one can for instance have bold and slanted keys at the same time) you can wrap the entry in \expanded or nicer is: \setupregister[expansion=yes] but if your entries contain markup you might like this more: \startbuffer[test] <text> <div> <p>In this page there is a <name idref="id1">cat</name>, a <name idref="id2">dog</name> and a <name idref="id3">horse</name>.</p> </div> <div> <p>In this page there's only a <name idref="id2">fox terrier</name>.</p> </div> <div> <p>In this page you find a <name idref="id1">persian cat</name> and a <name idref="id3">horse</name>.</p> </div> <index> <entry id="id1" data-sort="cat">Cat</entry> <entry id="id2" data-sort="dog"><bf>Dog</bf></entry> <entry id="id3" data-sort="horse">Horse</entry> </index> </text> \stopbuffer \defineregister[Animal][Animals] \startxmlsetups xml:mysetup \xmlsetsetup{#1}{*}{xml:*} \stopxmlsetups \xmlregistersetup{xml:mysetup} \startxmlsetups xml:text \xmlfunction{#1}{collectIndex} \xmlflush{#1} \stopxmlsetups \startxmlsetups xml:bf \dontleavehmode {\xmlflush{#1}} \stopxmlsetups \startxmlsetups xml:div \xmlflush{#1} \page \stopxmlsetups \startxmlsetups xml:p \ignorespaces \xmlflush{#1} \removeunwantedspaces \par \stopxmlsetups \startxmlsetups xml:name \dontleavehmode \xmlfunction{#1}{indexEntry} {\bf\xmlflush{#1}} \stopxmlsetups \startxmlsetups xml:i \dontleavehmode {\em\xmlflush{#1}} \stopxmlsetups \startxmlsetups xml:index \placeregister[Animal] \stopxmlsetups \startxmlsetups xml:entry \xmlflush{#1} \stopxmlsetups \startluacode local animals = { } function xml.functions.collectIndex(e) for entry in xml.collected(e,"/index/entry") do local key = entry.at["data-sort"] local id = entry.at["id"] if key and id then animals[id] = { key = key, entry = entry, } end end end function xml.functions.indexEntry(e) local animal = animals[e.at.idref] if animal then context.Animal ( { animal.key }, "\\xmlflush{main::" .. animal.entry.ix .. "}" ) end end \stopluacode \starttext \xmlprocessbuffer{main}{test}{} \stoptext These #1 are pointers to nodes, so this way (via ix) you access the entry itself. Also watch how we collect all entries at the start. Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------