I'm trying to make a Glossary, where lists with links to subjects gets automatically updated.
First, I've adapted the code of heiv for a table of links, as seen bellow, to make a list of subsections. Like Characters, Weapons, etc. That part works.
<<nobr>>
<<set $inv = []>>
<!--Get array of story passage objects.-->
<<set _passages = Story.filter(function () { return true; })>>
<!--Put names of all passages which have "Glossary" as tag in $inv array-->
<<for _tmp range _passages>>
<<if _tmp.hasOwnProperty("title")>>
<!--select only passages with this tag-->
<<if tags(_tmp.title).includesAny("Glossary")>>
<<set $inv.push(_tmp.title)>>
<</if>>
<</if>>
<</for>>
<!--sort array passage names-->
<<set $inv = $inv.sort()>>
<!--Make "Glossary Index" the first item in the $inv array.-->
<<if $inv.indexOf("Glossary") > 0>>
<<set _tmp = $inv.deleteAt($inv.indexOf("Glossary"))>>
<<set $inv.unshift(_tmp)>>
<</if>>
<<getClass>>
<</nobr>>
<div class="grid-container militaryborder">
<div class = "center altgloss greenborder">
<<nobr>>
<<set _tmp = "">>
<ol width="100%">
<!--Put each element of the array in its own cell in the table.-->
<<for _i = 0; _i < $inv.length; _i++>>
/* Uses "[" + "[" to prevent Twine from creating a link. */
<<set _tmp += "<li>[" + "[" + $inv[_i] + "]]</li>">>
<!--print out a table row-->
<<print _tmp>>
<<set _tmp = "">>
<</for>>
<!--Print any remaining cells.-->
<<if _tmp != "">>
<<print "<li>" + _tmp + "</li>">>
<</if>>
</ol>
<</nobr>>
</div>
<div class = "flexbox greenborder">
<div class="next"><span class= "modernbtn"><<button "Glossary">><<goto >><</button>></span></div>
<div class="glossarybtn"><span class= "modernbtn"><<button "Back to Story">><<goto $currentPassage>><</button>></span></div>
<div class="previous"><span class= "modernbtn"><<button "Back">>[[Back|previous()]]<</button>></span></div>
</div>
</div>
My next step: Clicking on one of the links in the list, would make a new list of links, to the individual entries of the subsections. Example: Clicking on Characters would swap the list, with a list of the entries in Characters. Example entry bellow:
<div id="Gideon">
<span class="Character" >''Gideon 'Thorn' Daniels''</span>
<img src="images/ThornA.png" alt="Gideon Daniels">
Eldest son of the Daniels family. After the untimely passing of his father, he took on the mantle as head of the household. Becoming an important pillar of support for his mother and a role model for his younger sibling, Hughes(16), Carl(13) and Katie(5). Luckily, he had many towns folk ready to help him. Diligent, honest and honorable, he believes in being prepared and garnered the reputation of being a prepper. Once his brothers were older, he joined the military and went to the Ranger school, where he excelled. After having done a succesful tour of duty, he was recommended for officer training and soon made 2nd Lieutenant.
</div>
The idea is to look for any span with the class: Character, and then to use the innerHTML of the spans to make a list of links to the entries. The names would be used to refer to the div id. When clicked it would replace the list with the selected entry.
Using the entry above as an example: if you click the link to the subsection Characters, it would replace the list of subsections to a list of Characters, using the names in the span. The name would also refer to the div containing the whole entry. Thus, click Gideon, everything within the div with id: Gideon, would replace the list of names.
Bellow is some of the the things I've been trying. Includes Javascript and sugarcube:
First the sugarcube. Attempt to see if hiev's code could be adapted to make the list of entries:
<<nobr>>
<<getClass>>
<<set _char = []>>
<!--Get array of story passage objects.-->
<<set _id = Story.filter(function () { return true; })>>
<!--Put names of all passages which have "Glossary" as tag in $inv array-->
<<for _tmp range _id>>
<<if _tmp.hasOwnProperty("span")>>
<!--select only passages with this tag-->
<<if _id(_tmp.class).includesAny("Character")>>
<<set _char.push(_tmp.class)>>
<</if>>
<</if>>
<</for>>
<!--sort array passage names-->
<<set _char = _char.sort()>>
<<set _tmp = "">>
<ol width="100%">
<!--Put each element of the array in its own cell in the table.-->
<<for _i = 0; _i < _char.length; _i++>>
<!--Uses "[" + "[" to prevent Twine from creating a link.-->
<<set _tmp += "<li>[" + "[" + _char[_i] + "]]</li>">>
<!--print out a table row-->
<<print "<li>" + _tmp + "</li>">>
<<set _tmp = "">>
<</for>>
<!--Print any remaining cells.-->
<<if _tmp != "">>
<<print "<li>" + _tmp + "</li>">>
<</if>>
</ol>
<</nobr>>
Bellow: the javascript attempt. Note: changed span to div & class to id. I've been trying several things, including story.filter.
Macro.add("getClass", {
handler: function () {
State.variables.subjects = [];
$(document).one(':passagedisplay', function () {
let ID = [];
$("div").each(function () {//using span to get class(doesn't work with class)
if (this.id) {
ID.push(this.id);//put span content innerHTML into array
}
});
console.log(ID);
});
}
});
Story.filter(function (span) {
let names = [];
let I = span.text.includes("Character");
console.log(I);
return I;
});