tweaking ForEachTiddler title displays to ignore initial articles?

15 views
Skip to first unread message

Mark

unread,
Jan 9, 2008, 4:32:20 PM1/9/08
to TiddlyWiki
I'm a beginner in learning JavaScript and am in need of some advanced
expertise.

I'm using the ForEachTiddler plugin to generate a list book titles.

The book titles are entered as the titles of the tiddlers.

The current display of a large volume of initial articles is annoying:
to many A's, An's and The's.

Searching around I found a bit of Javascript someone cooked up to
address this issue within the context of an online library catalog:

"I have updated the script to ignore initial articles. I updated the
sort_alpha function thusly:

sort_alpha: function(a,b) {
if (a[0].substring(0,2) == "A ") {
a[0] = a[0].substring(2,a[0].length);
}
if (b[0].substring(0,2) == "A ") {
b[0] = b[0].substring(2,b[0].length);
}
if (a[0].substring(0,3) == "An ") {
a[0] = a[0].substring(3,a[0].length);
}
if (b[0].substring(0,3) == "An ") {
b[0] = b[0].substring(3,b[0].length);
}
if (a[0].substring(0,4) == "The ") {
a[0] = a[0].substring(4,a[0].length);
}
if (b[0].substring(0,4) == "The ") {
b[0] = b[0].substring(4,b[0].length);
}
if (a[0].toUpperCase()==b[0].toUpperCase()) return 0;
if (a[0].toUpperCase()<b[0].toUpperCase()) return -1;
return 1;
},

They state: "There are probably more elegant ways to do this but I'm a
real hack when it comes to javascript! ;)"

From: http://www.innopacusers.org/list/archives/2007/msg07085.html

Is there an elegant way to include such a script with a FET macro
call?

Thanks in advance,

Mark

Eric Shulman

unread,
Jan 10, 2008, 1:12:18 AM1/10/08
to TiddlyWiki
Try this:

sort_alpha: function(a,b) {
a[0]=a[0].replace(/^(A|An|The) /,"");
b[0]=b[0].replace(/^(A|An|The) /,"");
if (a[0].toUpperCase()==b[0].toUpperCase()) return 0;
if (a[0].toUpperCase()<b[0].toUpperCase()) return -1;
return 1;
}

-e
Eric Shulman
TiddlyTools / ELS Design Studios

Mark

unread,
Jan 10, 2008, 4:02:12 AM1/10/08
to TiddlyWiki
Thanks Eric!

Now, please excuse my ignorance but how exactly would I embed this
script to ignore initial articles into a FET macro call like the
following one?

<tab B>
<<forEachTiddler
where
'tiddler.title.startsWith("B") && tiddler.tags.contains("book")'
>>
</tab>

The example provided in my initial post was from a different context
that I do not need to replicate. It was some Javascript that I thought
might illustrate in a general way what I was trying to do.

Thanks again for your assistance.

Your fluency inspires me to dive deeper into these mysteries.

mck

Eric Shulman

unread,
Jan 10, 2008, 4:55:20 AM1/10/08
to TiddlyWiki
> Now, please excuse my ignorance but how exactly would I embed this
> script to ignore initial articles into a FET macro call like the
> following one?

OK... try this:

<tab B>
<<forEachTiddler
where
'tiddler.title.replace(/^(A|An|The) /,"").startsWith("B") &&
tiddler.tags.contains("book")'>>
</tab>


enjoy,
-e

Mark

unread,
Jan 10, 2008, 6:14:10 AM1/10/08
to TiddlyWiki
Almost there!

It now works for: The Book of Job (upper case)

but the following titles get dropped where the second word contains a
lowercase b:

The butcher, the baker, the candlestick maker
The broken chalice

Also, all the titles beginning with ( The ) are currently displaying
at the end of the list rather than within proper alphabetic sequence.

For instance, they now sort like this:

# Creativity and its role in healing
# Crucial work
# Curia anima
# The Cartesian ghost in transference and projective identification
# The Cassandra complex
# The Celtic landscape

rather than:

# The Cartesian ghost in transference and projective identification
# The Cassandra complex
# The Celtic landscape
# Creativity and its role in healing
# Crucial work
# Curia anima

It's 3 am so perhaps if I sleep on this one ....

Thanks again!

Mark

Eric Shulman

unread,
Jan 10, 2008, 8:49:24 AM1/10/08
to TiddlyWiki
> It now works for: The Book of Job (upper case)
> but the following titles get dropped where the second word contains a
> lowercase b:


The startsWith() function (defined by ForEachTiddlerPlugin) does a
case-sensitive comparison... Thus,
tiddler.title.replace(/^(A|An|The) /,"").startsWith("B")
only checks for *upper case* B

For case-insensitive single-letter comparisons, you should skip this
function and use:
tiddler.title.replace(/^(A|An|
The) /,"").substr(0,1).toUpperCase()=="B"

> Also, all the titles beginning with ( The ) are currently displaying
> at the end of the list rather than within proper alphabetic sequence.

The "where" clause filters the title (to remove the A/An/The prefix)
for comparison purposes ONLY. It does not actually alter the titles
in the resulting list, and doesn't change the *sort order* of the
list. You will need to add a custom "sortBy" clause to your
<<ForEachTiddler>> usage so that it also filters out the prefix (if
any) for sorting purposes (without altering the actual titles in the
list)

Putting it together:

<tab B>
<<forEachTiddler
where
'tiddler.title.replace(/^(A|An|
The) /,"").substr(0,1).toUpperCase()=="B" &&
tiddler.tags.contains("book")'
sortBy
tiddler.title.replace(/^(A|An|The) /,"")>>
</tab>


enjoy,
-e

Mark

unread,
Jan 10, 2008, 12:47:47 PM1/10/08
to TiddlyWiki
That's it!

The last part did not work until I wrapped it in ' '.

Now, it works like a charm.

<tab B>
<<forEachTiddler
where
'tiddler.title.replace(/^(A|An|
The) /,"").substr(0,1).toUpperCase()=="A" &&
tiddler.tags.contains("book")'
sortBy
'tiddler.title.replace(/^(A|An|The) /,"")'>>
</tab>

For a 1200 item bibliography, this little bit of Javascript will save
me hours of work and results and a much more professional display.

Thanks, Eric!

Mark

Mark

unread,
Jan 10, 2008, 3:08:11 PM1/10/08
to TiddlyWiki

Oops.

I spoke to soon.

The sortBy clause is not quite right.

It works well where the second word is upper case:

* Caring for the vulnerable child in the critical hours
* The Cartesian ghost in transference and projective identification
* The Cassandra complex
* Cat's eye

but then at the end of the list appear all the instances where the
second word is lower case.

* Creativity its role in healing
* Curia anima
* The case of the murdered ox: the Athenian Bouphonia: a contribution
to ecopsychology
* A chance to say goodbye
* The consulting room as a theater for the Greek tragedy play

What do I need to add to the sort clause so that the case of the first
word after the initial articles (A, An, The) makes no difference to
the alphabetic sort order?

Thus, in the end, the titles should sort as follows:

* Caring for the vulnerable child in the critical hours
* The Cartesian ghost in transference and projective identification
* The Cassandra complex
* Cat's eye
* A chance to say goodbye
* The consulting room as a theater for the Greek tragedy play
* Creativity its role in healing
* Curia anima

I'm sure what would take me days is actually a very quick and simple
fix.

Thanks in advance!

Mark

Eric Shulman

unread,
Jan 10, 2008, 3:13:23 PM1/10/08
to TiddlyWiki
> The sortBy clause is not quite right.
> It works well where the second word is upper case:
> but then at the end of the list appear all the instances where the
> second word is lower case.
> What do I need to add to the sort clause so that the case of the first
> word after the initial articles (A, An, The) makes no difference to
> the alphabetic sort order?

add ".toUpperCase()" to the sortBy expression, like this:

sortBy 'tiddler.title.replace(/^(A|An|The) /,"").toUpperCase()'>>

enjoy,
-e

Mark

unread,
Jan 10, 2008, 4:23:02 PM1/10/08
to TiddlyWiki
Perfect!

Your javascript juju does indeed bring joy!

Many thanks!

Mark

<<forEachTiddler
where
'tiddler.title.replace(/^(A|An|
The) /,"").substr(0,1).toUpperCase()=="A" &&
tiddler.tags.contains("book")'
sortBy
'tiddler.title.replace(/^(A|An|The) /,"").toUpperCase()'>>

Reply all
Reply to author
Forward
0 new messages