Create alphabetical ordered index-page from list attribute

Yes, this does work. Note, if you’re writing a book with many chapters, you can create cross-referenced index as well to show what chapter sand sections the keywords show up in. If you’re interested, I could look into pulling a demo of this together for you.

1 Like

Would love to see a small demo of this.

Sounds good. Give me a week or two. I’m heads down on a project that I have to get done.

If the values of $RefWords are “Winken;Blynken;Nod”, we could easily define

Name: Winken agent
AgentQuery: $RefWords.contains("Winken")

And similarly for agents for Blynken and Nod.

This is infeasible if $RefWords has hundreds of values; attribute browser is the answer for that case. But, often, $RefWords has a constrained vocabulary — you can only fit so many characters in a wooden shoe sailing on a river of crystal light, after all. This is actually the common case; attribute browser is for the more difficult, esoteric case.

1 Like

The reason I spoke up is I believe @satikusala has some book-length projects in Tinderbox where he may have addressed this “assemble and export an index” problem.

I’m assuming dozens of agents, one for each entry in a book index to be exported, might be cumbersome and that A/B is good for viewing but not so much for exporting. Am I wrong?

As has been noted, an agent-per-topic approach doesn’t scale well. I’d accord with AB view for quick review: for long-term projects, designing outline/attributes for easy use with AB view (i.e. not needing complex per-view filters) is enlightened self-interest. With large datasets (++notes) a frustrating limitation of AB view is easily being able to see just the categories/counts, i.e. collapsing the per-category listings and showing only the category banners.

Taking another perspective on the assembly of the ‘index’ I like to create notes per category (item, keyword, entity - i.e. a note per thing). Once you have this you can ‘index’ usage a number of ways:

  • Links. Use action code to link the ‘index’ note to any notes using the relevant term in whatever contexts you choose (text, specific attributes, etc.)
  • List/Sets/Dictionaries. Again action code can be used to record a note name (if unique, or $ID/$IDString instead).

If using action code, with size/degree of use a trajectory is to migrate code from rules to edicts to stamps; from long experience, I generally skip the rule stage, but that’s not a requirement. Gong from edict to stamp does require thought.as you’re trading automation (edicts running on their own) for finer control over what code is running and when albeit with you having to be come the ‘automatic’ part. Size/complexity of the TBX is the factor and likely most users won’t reach that problem.

Once populated, an index note can either store the name (identities) of the associated notes, or link to those notes. Neither is ‘better’, it’s partly stylistic choice and partly reflects what the current project involves. Anyway, from this explicit (link) or implicit (attribute value) data it is then possible to construct export-able data for a ‘printed’ index. But, do note that Tinderbox won’t export links to notes transcluded (included) in other exported notes, e.g. exporting everything as a single output file. There are workarounds for that issue but if of interest I’d suggest raising that in a new thread to avoid thread drift.

†. As noted in this forum thread use of note ID-based data is not something most users will need as $Name or $Path should suffice. Once doing large/complex things and with a lot of the work happening abstracted into action code, ID-based work becomes a boon. Plus, it’s really not that hard to migrate from normal Name/Page-based code to using IDs if the need arises. A novice user shouldn’t need to think about ID-based code in their initial work.

1 Like

Has this turned out to be unexpectedly hard to do? Is the approach already covered in a video or somewhere else? If so where, and I can try to hunt it down.

The real need if any for the agents is seeing matches in the UI, though as you mention AB view I’d say the latter is a lot more useful in the same basic role. People still with agents as it’s some of the first automation covered in the basic tutorials (and not everyone pushes on further). Plus in small docs/small scale there’s no real impact. But, making an agent for every one of for one hundred discrete terms or phrases? Perhaps not.

But whilst AB view is great in-doc and can export RTF and textual tables, it is less easily used in formatted (a.k.a. ‘HTML’) export. However, that’s easily got around using ^include()^ and find() to replace exporting an agent either as a separate file (HTML, Markdown, XML, JSON, whatever format) or as part of a large cascading single file export.

So, old scenario, we have an agent with query $Tags.contains("complete") that is exported as a note. Instead we:

  • make a note with $Text:
    • ^include(find($Tags.contains("complete")),"tag-export")^
  • make a template “tag-export” and add whatever HTML, etc., code we need to the export the paths [sic] as returned by the find() query

The export output of the note is now formatted data (list, table, whatever) of info from the same notes that the original found in the agents we no no longer need. I use this model a lot in my large research docs. After a while agents just get in the way and need to be throttled back to allow other automation to run smoothly. No such reporting agents, even better—not that I don’t still use agents for more specific tasks. But, 0s or 00s of agents just listing value occurrence, no.

I’m on deadlines right now so no demo, but it ought to be easy for an experienced user to make a working model from the instructions above.

It is a bit more mis-en-place to make a single exportable listing note but a much more powerful export affordance when done. The normal argument against this is being familiar with agents and unwilling to learn new methods, but I see that as self-defeating.

Sorry there’s no demo file but HTH. :slight_smile:

1 Like

I think I get the general idea. But need more specifics on how to implement it. This is the part I am interested in.

Yes, I know…I just submitted the next major draft of my dissertation (let’s hope this is the near-final draft…fingers crossed). Now that this is done, I can turn to this. I’l schedule some time to try to pull something together for you by next week. Sorry for the delay, but I really needed to get the dissertation out

2 Likes

Hi @sumnerg just finished an indexing demo, check it out: Tinderbox Meetup Saturday 10 February 24: ExportFileName, Highlighting, Creating an Index. Let me know what you think and if you have any questions.

1 Like

Thanks for this! The holidays are upon us over here. But working through the tbx and the video. There’s a lot to digest!

1 Like

Taking @satikusala impressive example a step at a time I think I’ve got bare bones indexes working for me. One set attribute and, as I have often found with Tinderbox, just a few bits of shockingly compact code - here all in functions called by ^value() in the text of an index note.

Index-table-test.tbx (236.0 KB)

Questions:

If I wanted, how could I get case insensitive sort? (Here all uppercase sorts together to the top.)

When trying to rely on what I think of as the “built-in” markup with <p> etc to create a “text format” index rather than “table format” index why do I get the desired export markup and preview when calling the functions from a stamp, but not when calling the same functions by ^value() in the text of the note (which I’d rather do)?

Illustration of my problem here:

Index-text-test.tbx (232.8 KB)

See .isort().

Also useful to know: Lexical vs. numeric sorting.

1 Like

.isort() an easy add to the function when needed. Thanks!

1 Like

My main question is the second one, about the markup differences in the second tbx attached even though it is the same functions being called.

When using the stamp, you call your function to place a list of entries into the text of the note. Each entry is separated with a carriage return:

	return result.format("\n");

When you export (or preview) the page, each paragraph receives markup, transforming “TermA, Chapter 1, Chapter 6\n” to

<p>TermA, Chapter 1, Chapter 6</p>

That second step isn’t done in ^value(), which inserts the literal result.

One solution would be to insert HTML markup in the function:

	return result.format("<br> \n");

This is poor HTML style, but it gets the job done. Better would be to export a proper list:

         <li> entry 1 </li> 
         ...
</ul> 

That’s easy enough as well.

You could also write a function that takes the result of termToLoc and wraps each line in paragraph markup:

function asList(theIndex:string) {
    var:string result;
   theIndex.eachLine(entry) {
      result += "<p>" + entry + "</p>";
      }
   return result;
}
2 Likes

This makes me very happy. :smiling_face_with_three_hearts::smiling_face_with_three_hearts::smiling_face_with_three_hearts:

[sorry about the seeming partial answer—I was half out the door to fix storm damage at out allotment (garden) when I saw the post. I answered the bit it I knew.]

If I understand correctly, the difference lies in understanding $Text in Text vs. Preview mode. Looking at Index-text-test.tbx, and “Index - ^value(function)” vs. “Index - stamp me” in Export pane shows this use. I feel like an angry prophet, but if you click from Text to Preview and it looks wrong, look at the Export tab before trying to fix anything.

That said, this seemingly ‘simple’ problem, which 50 minutes later turns out to be a limitation of what can be done inside ^value()^. I won’t go into gory detail here as it ins more helpful to look at this in a version of your test doc:

Index-text-test copy.tbx (246.9 KB)

In this, I’ve copied your original “Index - ^value(function)” as “Index - ^value(function) original”. I also changed the note to turns off ‘smart quotes’ as the fix needs code in the note.

My first thought was to write something like this:

^value(locToTerm($Path(parent)).replace("\n","").format("","<p>","</p>","")^

but that failed. But this works:

^action(
var:list vListOne = termToLoc($Path(parent)).replace("\n",";");
$Text(/log) = vListOne;
var:string vStringOne = vListOne.format("","<p>","</p>\n","");
var:list vListTwo = locToTerm($Path(parent)).replace("\n",";");
$Text(/log) = vListTwo;
var:string vStringTwo = vListTwo.format("","<p>","</p>\n","");

)^
<h3>Term to Location</h3>
...etc.

As the previous reply in-thread shows, there’s no one ‘right’ answer. However, the above hopefully sticks close to what you thought you were trying to do.

HTH

2 Likes

The explanations and the many examples approaching the problem from different angles are most helpful. Thank you!

3 Likes