Inline, nested tabs extension?

314 views
Skip to first unread message

Antaeus Feldspar

unread,
Apr 10, 2012, 8:53:32 PM4/10/12
to tiddl...@googlegroups.com
Is there (or would someone like to program) an extension that produces output similar to the "tabs" macro, but produces it from content in the same tiddler, instead of pulling the content from other tiddlers or tiddler-section references?

I know it's possible to do something *similar* by using the standard tabs macro and giving it references to sections of the current tiddler, but among other problems, you can't really nest content that way. I'd like to be able to do something like this:

<<i-tabs major-choice "Choice A">>
Choice A, blah blah!
<<i-tabs major-choice "Choice B">>
Choice B, unlike Choice A, comes in two variants:
<<i-tabs minor-choice "Choice B-1">>
There's Choice B-1...
<<i-tabs minor-choice "Choice B-2">>
... and the imaginatively named B-2!!
<<i-tabs minor-choice end>>
<<i-tabs major-choice end>>

The output would be a pane with two tab buttons, marked "Choice A" and "Choice B"; if "Choice A" was selected, the pane would contain only the text "Choice A, blah blah!" If the other tab button, "Choice B", was selected, the pane would contain the text "Choice B, unlike Choice A, comes in two variants:" followed by a nested pane with two tab buttons, marked "Choice B-1" and "Choice B-2"... the nested pane would contain the text "There's Choice B-1..." or "... and the imaginatively named B-2!!" depending on which tab button was selected.

I've been trying to write this one myself but reluctantly coming to the conclusion that I have just too many projects on my plate and can't bring this one to fruition any time soon. Anyone else interested?

wolfgang

unread,
Apr 13, 2012, 8:01:09 AM4/13/12
to tiddl...@googlegroups.com

I know it's possible to do something *similar* by using the standard tabs macro and giving it references to sections of the current tiddler, but among other problems, you can't really nest content that way.

Are you're looking for an easier syntax? Because you seem aware that nested tabs are possible today already.

whatever

unread,
Apr 13, 2012, 3:24:54 PM4/13/12
to TiddlyWiki
Well, you can do it with MatchTagsPlugin (1), NestedSlidersPlugin (2)
and DOMTweaksPlugin (3). And I think there are some other options as
well.
Here are a couple of examples:

Example 1 with (1) and (3): Get all tiddlers taged tag1 and ta2 but
not tag3 and display them on panels:
<<matchTags {{"+++*[%0]#panelName:...<<tiddler [[%0]]>\>==="}} "|"
tag1 AND tag2 AND NOT tag3>>
<<matchTags {{"<<DOM move panelName>\>"}} " "tag1 AND tag2 AND NOT
tag3>>

The panelName is a code word defining the name of the DOM object,
which is manipulated. The tags at the end can be a single tag or
multiple, and you can use Boolean operators, like in the example. So
you could have tiddlers titled Choice1, Choice2... ChoiceN, which
would contain similar code for subchoice tiddlers, say, Choice2a,
Choice2b... Choice2n.

Example 2 with (2) and (3): Basically your example; they're not proper
tab, but I'm sure that with some CSS magic, you could make them look
like tags.
+++*[Choice A]#ChoiceA:
Choice A, blah blah!
=== | +++*[Choice B]#ChoiceB:
Choice B, unlike Choice A, comes in two variants:
+++*[Choice B1]#ChoiceB1:
Choice B1, blah blah!
=== | +++*[Choice B2]#ChoiceB2:
Choice B2, blah blah!
===
<<DOM move ChoiceB1>><<DOM move ChoiceB2>>
=== | +++*[Choice C]#ChoiceC:
Choice C, blah blah!
===
<<DOM move ChoiceA>><<DOM move ChoiceB>><<DOM move ChoiceC>>

The only issue here is that for some reason, panels ChoiceB1 and
ChoiceB2 aren't transient and you can have them both open at the same
time, which is not what you want, I'm guessing. I tested this without
the DOM panels and the behavior of the level 2 panels was the same,
they were not transient. Does anyone know why this is so?

Hope it helps.

w

(1) http://www.TiddlyTools.com/#MatchTagsPlugin
(2) http://www.TiddlyTools.com/#NestedSlidersPlugin
(3) http://www.TiddlyTools.com/#DOMTweaksPlugin

whatever

unread,
Apr 13, 2012, 3:26:40 PM4/13/12
to TiddlyWiki
Oops, spotted some typos.

The above sentence:
Example 2 with (2) and (3): Basically your example; they're not proper
tab, but I'm sure that with some CSS magic, you could make them look
like tags.

should be:
Example 2 with (2) and (3): Basically your example; they're not proper
tabs, but I'm sure that with some CSS magic, you could make them look
like tabs.

w
> (3)http://www.TiddlyTools.com/#DOMTweaksPlugin

Antaeus Feldspar

unread,
Apr 13, 2012, 8:29:04 PM4/13/12
to tiddl...@googlegroups.com
Wolfgang, Whatever - thank you so much for your answers so far! Let me describe how I use TiddlyWiki and hopefully it will clarify what I'm looking for in an "inline tabs" extension.

I actually use TiddlyWiki for composing long prose works - short stories, novels, screenplays, stage plays, etc. TW is very good for the way I write, where I may get a very clear idea for individual scenes before I know how to put them all together into a whole. With TW, I can open up a new tiddler, pour everything I know about the current scene into that tiddler, and then put tags on the tiddler and create references to it in other tiddlers to help me find it later, in the "weaving it all together" phase of the writing.

Sometimes, while I'm writing, I can see two (or more) ways to approach the current writing. To give an example, if I'm bringing "on stage" a new character and an important object they're carrying, I may be unsure whether it works better to describe the character first and then the object, or the other way around. What I would really like is an extension where, without breaking the flow of my writing, I can write quick rough versions of *both* approaches, and then when I put that tiddler in view mode, have those two passages appear as two tabs on one pane. So, something like the following:

(syntax line indicating the start of the inline-tabs section, and the start of the first tab)
The book was clearly ancient, bound in leather that rotted and gave up dust at every careless jostle. The cover bore no words, merely a sigil that made the viewer uneasy...

The man who carried the book out of the crypt seemed scarcely less ancient. It was impossible for those who watched him to tell whether his filmy eyes still saw, or whether he navigated his way over the uneven stone flooring by feel alone...
(syntax line indicating the start of the second tab)
The man who carried the book out of the crypt was ancient, so ancient that, while living, he seemed a walking symbol of mortality. It was impossible for those who watched him to tell whether his filmy eyes still saw, or whether he navigated his way over the uneven stone flooring by feel alone...

The book itself was clearly even more ancient, bound in leather that rotted and gave up dust at every careless jostle. The cover bore no words, merely a sigil that made the viewer uneasy...
(syntax line indicating the end of the tabs-section)

Now, what I *could* do is to put each of those two alternate versions into an individual tiddler, and then write a tabs macro in the tiddler that refers to those two individual tiddlers. The reason that's not an optimal solution is that I'm trying not to break the flow of my writing, and having to stop to create two individual tiddlers and then the tabs macro invoking them in the original tiddler is *very* flow-breaking. I know; I've tried it.

I can avoid the distraction of creating new individual tiddlers if I create sections in the current tiddler, mark them so that they don't show up in normal view mode but their content can still be transcluded, and then construct the macro invocation referring to those tiddler sections. But this is also very flow-breaking, and it has the additional disadvantage that if I have another choice I want to study both versions of, and that choice appears in one of the two tab-sections, I have to establish those two sub-choices as top-level tiddler sections, since sections can't nest, and then create the tabs macro. It's like doing Reverse Polish Notation with my wiki syntax, and while I know how to do RPN, I'd rather be giving my brain power to the *writing* rather than the syntax.

While writing this, I've thought of a way I *might* be able to get the effect I'm looking for with Nested Sliders. I don't know how well it will work, so I'll try it out and report in a few days. Thank you for all your help!

wolfgang

unread,
Apr 13, 2012, 9:41:58 PM4/13/12
to tiddl...@googlegroups.com
Saq once wrote the InlineTabsPlugin, don't know if it still works with the latest TW version:

DEMO

Note: you can space out the tabs to make editing easier, the linebreaks between tabs will be ignored:
{{{
<tabs mytabs>

<tab tab1>
This is my first tab
</tab>

<tab tab2>
This is my second tab
</tab>

<tab tab3>
This is my third tab
with more than one line
</tab>

<tab tab4>
</tab>

</tabs>
}}}

InlineTabsPlugin

//{{{
config.formatters.unshift( {
    name: "inlinetabs",
    match: "\\<tabs",
        lookaheadRegExp: /(?:<tabs (.*)>\n)((?:.|\n)*?)(?:\n<\/tabs>)/mg,
    handler: function(w)
    {
        this.lookaheadRegExp.lastIndex = w.matchStart;
        var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
        if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
            {
             var cookie = lookaheadMatch[1];
               var wrapper = createTiddlyElement(null,"div",null,cookie);
             var tabset = createTiddlyElement(wrapper,"div",null,"tabset");
             tabset.setAttribute("cookie",cookie);
             var validTab = false;
             var firstTab = '';
             var tabregexp = /(?:<tab (.*)>)(?:(?:\n)?)((?:.|\n)*?)(?:<\/tab>)/mg;
             while((m = tabregexp.exec(lookaheadMatch[2])) != null)
                 {
                 if (firstTab == '') firstTab = m[1];
                 var tab = createTiddlyButton(tabset,m[1],m[1],story.onClickInlineTab,"tab tabUnselected");
                 tab.setAttribute("tab",m[1]);
                 tab.setAttribute("content",m[2]);
                 tab.title = m[1];
                 if(config.options[cookie] == m[1])
                     validTab = true;
                 }
             if(!validTab)
                 config.options[cookie] = firstTab;
             w.output.appendChild(wrapper);
             story.switchInlineTab(tabset,config.options[cookie]);
             w.nextMatch = this.lookaheadRegExp.lastIndex;
            }
    }
})

Story.prototype.switchInlineTab = function(tabset,tab)
{
    var cookie = tabset.getAttribute("cookie");
    var theTab = null
    var nodes = tabset.childNodes;
    for(var t=0; t<nodes.length; t++)
    if(nodes[t].getAttribute && nodes[t].getAttribute("tab") == tab)
        {
        theTab = nodes[t];
        theTab.className = "tab tabSelected";
        }
    else
        nodes[t].className = "tab tabUnselected"
    if(theTab)
        {
        if(tabset.nextSibling && tabset.nextSibling.className == "tabContents")
            tabset.parentNode.removeChild(tabset.nextSibling);
        var tabContent = createTiddlyElement(null,"div",null,"tabContents");
        tabset.parentNode.insertBefore(tabContent,tabset.nextSibling);
        wikify(theTab.getAttribute("content"),tabContent);
        if(cookie)
            {
            config.options[cookie] = tab;
            saveOptionCookie(cookie);
            }
        }
}
   
Story.prototype.onClickInlineTab = function(e)
{
    story.switchInlineTab(this.parentNode,this.getAttribute("tab"));
    return false;
}
//}}}

Antaeus Feldspar

unread,
Apr 13, 2012, 10:28:55 PM4/13/12
to tiddl...@googlegroups.com
Wolfgang, thank you!! That is at least 95% if not 100% what I've been looking for, and I don't know how I never found any trace of it before, not even searching for "inline tabs TiddlyWiki"! Thank you so much!! I'll start using this right away!

wolfgang

unread,
Apr 19, 2012, 5:18:28 PM4/19/12
to tiddl...@googlegroups.com

That is at least 95% if not ..

Actually it doesn't seems that much less awkward than using the regular tabs macro which uses the hidden sections of a tiddler, if used with lots of tidders. Think this could be made much more easier with a inline script, or a ForEachTiddlers, but didn't found anything for example on abegoExtensions on how to use it for sections.

Anyone got an idea?

Tobias Beer

unread,
Apr 19, 2012, 5:56:27 PM4/19/12
to tiddl...@googlegroups.com
Hi Antaeus,

Can you expand on the reason(s) why you would say that - for writing storylines - tabs make your life easier?

What's better about tabs than sections in your context? I mean, if you don't want to interrupt your flow when writing, why do you want to interrupt your flow when reading?

Is there some hidden idea behind that? At least to me, tabs do not seem an intuitive thing to come accros when reading a kind of manuscript.

Can it be that your ultimate goal is to be able to construct your preferred storyline from individual choices that you want to toggle but ultimately actually mark the ones that you like best?

So maybe it's really not about tabs but about being able to have alternative parts of a tiddler that you want to hide / display / flick through and here you ultimately select one... and perhaps depending on your first choice a secondary subchoice.

If that's the idea behind it... what would be the markup that you would need inside these tabs... would simple text suffice or would you also need to be able to put lists or headings etc?

Tobias.

Antaeus Feldspar

unread,
Apr 19, 2012, 7:19:40 PM4/19/12
to tiddl...@googlegroups.com
>Hi Antaeus,

>Can you expand on the reason(s) why you would say that - for writing storylines - tabs make your life easier?

>What's better about tabs than sections in your context? I mean, if you don't want to interrupt your flow when writing, why do you want to interrupt your flow when reading?

>Is there some hidden idea behind that? At least to me, tabs do not seem an intuitive thing to come accros when reading a kind of manuscript.

>Can it be that your ultimate goal is to be able to construct your preferred storyline from individual choices that you want to toggle but ultimately actually mark the ones that you like best?

Tobias, that's exactly what my ultimate goal is. Sometimes I'll write several different versions of a scene, or a part of a scene, and I'll have to look back and forth between all the different versions I've written, comparing them, trying to figure out how I can combine the best parts of each attempt to make the final version.

At the *end* of the process, I'll have everything boiled down to one single final draft version, but while I'm trying to get to that final version, being able to toggle between the different versions would be extremely helpful.

>So maybe it's really not about tabs but about being able to have alternative parts of a tiddler that you want to hide / display / flick through and here you ultimately select one... and perhaps depending on your first choice a secondary subchoice.

Exactly! Tabs would be an easy UI element to flip between those alternative parts, but another element that did the same thing would also work.

>If that's the idea behind it... what would be the markup that you would need inside these tabs... would simple text suffice or would you also need to be able to put lists or headings etc?

>Tobias.

Headings, probably not. Lists... perhaps. Italics, strong text, wikilinks: definitely. Nested sliders: I would really like these - I use the "floating" version to make notes to myself.

Thank you!

Tobias Beer

unread,
Apr 20, 2012, 2:50:52 AM4/20/12
to tiddl...@googlegroups.com
My Idea would be this,

I would essentially (want to) define some markup which is recognized as such "tabbed inline choices", which can be displayed as inline or as block level elements. The simple trick behind it would be to start with a new line and then a blank and then a character you normally do not expect, like a dot.

 .1st Choice                                        
Some choice content, describing it. All available choice titles of that level would be displayed as html titles to the entire choice.

By default a choice is rendered inline right behind the text that precedes it, not as a block level element (like a tab).
A choice might even contain a...
!Heading
...although the section content would probably be meaningless when asked for via the <<tiddler>> macro.
 .2nd Choice                                       
This one contains a list...
*The choice titles must be unique
**to later be able to extend with search and replace
**this makes your wikitext more readable
 ..1st Sub Of 2nd Choice                      

Add another little dot and the thing is a subchoice to the second choice.
Note how this starts with a blank line which essentially renders it on a new line instead of inline.
 ..!2nd Sub Of 2nd Choice                    

Of course we would always want at least two choices, don't we?
Notice the exclamation mark before the title which would show this choice initially even though it is listed second!
 .                                                        

And finally just the triggering markup but without anything following but a new line in order to end the sequence.

To me this looks like the least markup you could probably have. Here's an example:


I like fruits, especially 
 .Apples                        
apples! They are so yummy.
 .Bananas                     
bananas! I just love how yellow and mushy they are.
 ..Platanos                    
There even are those south americain platanos which are especially cool when cooked.
 ..Baby Bananas           
Those tiny baby bananas always give me the chills.
 .

As I said above, unlike tabs, I would always render a choice inline, so if you wanted your choice to be rendered on a new line, you would have to prepend a blank line to the choices body.

I would say the markup could not be any simpler.

Obviously, choices need their own css wrapper so you can easily spot them in your storyline.

Once you hover them, they would highlight a little more and a simple click on your choice would toggle the thing.

The little exclamation mark prepended to a choices title could be used to persist choices. So, when you reopen the tiddler, you would see the storyline reflecting the choices you last made.

I guess the ultimate coolness would be a little overlay menu displayed when you hover a choice that allows you to * add another choice (making it default)
* edit the choice you currently see
* delete a choice


So much for brainstorming... to have this all working is quite another feast. Please don't get your hopes up too high, any time soon.

Tobias.

wolfgang

unread,
Apr 20, 2012, 8:24:55 PM4/20/12
to tiddl...@googlegroups.com
Meanwhile..
 
Think this could be made much more easier with a inline script, or a ForEachTiddlers, but didn't found anything for example on abegoExtensions on how to use it for sections.

found this script coming very close in Eric's TestTidder:

+++!!![ListSections]...
<script>
var title=prompt('enter tiddler title','SectionLinksPlugin'); if (!title) return;
var pattern=/(^|\n)!{1,6}([^eE\n][^nN\n][^dD\n])[^\n]*\n/g;
var matches=store.getTiddlerText(title).match(pattern);
var out='<<tabs txtCurrentTab ';
for (var i=0;i<matches.length;i++) {
    var m=matches[i].replace(/!{1,6}|\n/g,'').replace(/"/g,'\\x22').replace(/>>/g,'>\\>').replace(/\}\}\}/g,'}\\}\\}');
    out+= '{{"'+m+'"}} {{"'+m+'"}} {{"'+title+'##'+m+'"}} ';
}
out += '>>';
return out;
</script>
===
 
Now I only would need to know how to change the prompt to using it for the sections of a tiddler with the script?

wolfgang

unread,
Apr 20, 2012, 9:26:31 PM4/20/12
to tiddl...@googlegroups.com
This does it:

<script>
var here = window.story.findContainingTiddler(place); 
var tiddler = store.getTiddler(here.getAttribute("tiddler")); 
var title = tiddler.title; 

wolfgang

unread,
Apr 20, 2012, 9:37:50 PM4/20/12
to tiddl...@googlegroups.com

This does it:


Well, still not perfect. It renders the different levels of headings on one level of tabs only, but not as nested tabs.

Antaeus Feldspar

unread,
Apr 23, 2012, 9:51:12 PM4/23/12
to tiddl...@googlegroups.com
wolfgang, I must admit I'm a bit mystified by the code snippet you posted. I'm intrigued but I don't understand how it would work - where the code would go and how I'd invoke it. Can you clarify it a bit?

wolfgang

unread,
Apr 24, 2012, 3:36:10 AM4/24/12
to tiddl...@googlegroups.com
Sorry for not being more clear. It is an inline script and only works if Eric's InlineJavascriptPlugin (TiddlyTools) is installed.

Next create a tiddler with the script and name it for example:

SectionTabs
No tags are required for this SectionTab tiddler. Then simple add <<tiddler SectionTab>> transclusion at the beginning of a tiddler, and comment the main content of it out. eg.

<<tiddler SectionTab>>/%

! Chapter 1

text

! Chaper 2

some more text

%/


It will create a tab for each chapter of that tidder.

Antaeus Feldspar

unread,
Apr 24, 2012, 9:48:30 PM4/24/12
to tiddl...@googlegroups.com
Ahh! That's awesome! One question, though: could you use more than one of these in a tiddler? I don't mean nested; I mean using the transclusion twice to tab-ify two separate sets of sections. I could be wrong but it looks like each transclusion would tabify *all* the sections in that tiddler.

wolfgang

unread,
Apr 25, 2012, 2:43:43 AM4/25/12
to tiddl...@googlegroups.com
If you're not javascript literate, like me, you can use this script only once in each tiddler and transclude these into one.

Antaeus Feldspar

unread,
Apr 26, 2012, 7:45:00 PM4/26/12
to tiddl...@googlegroups.com
I've been doing some experimenting, and I think I'm concluding that the syntax which I've always found concentration-breaking before about trying to set up tabs for content in the same tiddler isn't in the sections - it's in the tabs macro itself. I mean, just to set up a pane with two tabs takes a minimum of eight words in the macro invocation! I've figured out a way to use transclusion to make it easier, by substituting sensible defaults, but I'm not sure it'll really save that much except with large numbers of tabs.

TonG

unread,
Apr 27, 2012, 3:29:27 AM4/27/12
to TiddlyWiki
Hi Antaeus,

How about using Tiddlytools' QuickEdit package?
http://www.tiddlytools.com/#QuickEditPackage
With that you can make custom insertions with a click of a button,
e.g. inserting the default (2, 3, ..) tabs macro or inline tabs.

Cheers,

Ton

TonyM

unread,
Jun 14, 2012, 3:34:52 AM6/14/12
to tiddl...@googlegroups.com
Bit late I suppose but one thing I do now a lot is use the nested sliders plugin as I am typing

+++[heading]
text
===

Once you have done it a few times it becomes second nature

In the Script story writing example it would go

++++[object first]
The boject comes into the room
===
+++[person first]
The person comes into the room
===

Notice in this case I used the 4 + "++++" to make the object first open be default thus indicating my current preference.

I also use the QuickEdit plugin as suggested before with the following entry in custom
Start Slider Section - place {{{===}}} at end
+++[$1]...
----

Then I highlight the "heading" which is placed at $1 and choose where to place the === to close the slider.

The above works mid paragraph as well. I also think the nested slider section is considered a section for other section handling tools.

Regards
TonyM
Tony
Reply all
Reply to author
Forward
0 new messages