Register Guidelines E-Books Today's Posts Search

Go Back   MobileRead Forums > E-Book Software > Calibre > Library Management

Notices

Reply
 
Thread Tools Search this Thread
Old 07-10-2018, 01:34 PM   #1
BookJunkieLI
Evangelist
BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.
 
BookJunkieLI's Avatar
 
Posts: 435
Karma: 572984
Join Date: Jan 2010
Location: Long Island
Device: Kobo Libra 2, Kindle 4, Nook Gl4, Nook STR, REB 1100, Ebookwise 1500,
Need help w/Advanced Column Icon Rule

I'm going to preface this by saying I do have a minor learning disability and without real examples of 'this results in this' and 'this results in this' I can have a hard time comprehending abstract concepts. And I have, or tried to, read through the General Program and Template language tutorials but I'm still pretty lost.

I have figured out how to get multiple icons in a column using individual rules but I can't figure out how to create a single advanced rule that will put multiple icons in a column.

This is the rule I currently have setup with Composed icons w/No Text:

Spoiler:
Code:
program:
 first_non_empty
 ( 
		contains(field('tags'), "tag1", 'letter-a-icon.png', ''), 
		contains(field('tags'), "tag2", 'letter-c-icon.png', ''), 
                contains(field('tags'), "tag3", 'letter-b-icon.png', ''),
                contains(field('tags'), "tag4", 'letter-b-icon.png', ''),
		contains(field('tags'), "tag5", 'letter-d-icon.png', ''), 
		contains(field('tags'), "tag6", 'letter-x-icon.png', ''), 
		contains(field('tags'), "tag7", 'letter-i-icon.png', ''), 
		contains(field('tags'), "tag8", 'letter-c-icon.png', ''), 
		contains(field('tags'), "tag9", 'letter-p-icon.png', ''), 
		contains(field('tags'), "tag10", 'letter-p-icon.png', ''), 
		contains(field('tags'), "tag11", 'letter-r-icon.png', ''), 
		contains(field('tags'), "tag12", 'letter-s-icon.png', ''), 
		contains(field('tags'), "tag13", 'letter-s-icon.png', ''), 
		contains(field('tags'), "tag14", 'letter-x-icon.png', ''), 
		contains(field('tags'), "tag15", 'letter-w-icon.png', '')
 )


It will only return the first icon tag it finds and ignores any others unless I have them setup as a separate rule. I suspect it's because I'm using the 'first_non_empty' qualifier but I'm really not sure which one I should be using. Any help is greatly appreciated.
BookJunkieLI is offline   Reply With Quote
Old 07-10-2018, 02:28 PM   #2
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 11,773
Karma: 7029857
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
I appreciate your trying to solve the problem from the docs.

Try this:
Code:
program:
 t = field('tags');
 strcat
 ( 
		contains(t, "tag1", 'letter-a-icon.png:', ''), 
		contains(t, "tag2", 'letter-c-icon.png:', ''), 
                contains(t, "tag3", 'letter-b-icon.png:', ''),
                contains(t, "tag4", 'letter-b-icon.png:', ''),
		contains(t, "tag5", 'letter-d-icon.png:', ''), 
		contains(t, "tag6", 'letter-x-icon.png:', ''), 
		contains(t, "tag7", 'letter-i-icon.png:', ''), 
		contains(t, "tag8", 'letter-c-icon.png:', ''), 
		contains(t, "tag9", 'letter-p-icon.png:', ''), 
		contains(t, "tag10", 'letter-p-icon.png:', ''), 
		contains(t, "tag11", 'letter-r-icon.png:', ''), 
		contains(t, "tag12", 'letter-s-icon.png:', ''), 
		contains(t, "tag13", 'letter-s-icon.png:', ''), 
		contains(t, "tag14", 'letter-x-icon.png:', ''), 
		contains(t, "tag15", 'letter-w-icon.png:', '')
 )
I added a colon at the end of each icon name and changed "first_non_empty" to "strcat" (string concatenate). Calibre uses a colon to separate icon file names. The template produces a list of image names, so calibre will display each icon in the list. I changed all the "field('tags') to 't' for performance.

For the purists out there, calibre ignores empty icon names. For example, :::foo.png::: will produce only foo.png. This means we don't need to deal with the "second time" or "last time" problem, trying to account for hanging colons.

And just for fun, here is a way to supply a single different icon if two tags are present otherwise supply different icons:
Code:
program:
 t = field('tags');
 has_foo = contains(t, 'foo', '1', '');
 has_bar = contains(t, 'bar', '1', '');
 first_non_empty
 ( 
		test(and(has_foo, has_bar), 'foo_and_bar.png', ''), 
		test(has_foo, 'foo.png', ''), 
		test(has_bar, 'bar.png', '')
 )
chaley is offline   Reply With Quote
Advert
Old 07-11-2018, 11:29 AM   #3
BookJunkieLI
Evangelist
BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.
 
BookJunkieLI's Avatar
 
Posts: 435
Karma: 572984
Join Date: Jan 2010
Location: Long Island
Device: Kobo Libra 2, Kindle 4, Nook Gl4, Nook STR, REB 1100, Ebookwise 1500,
Thanks, chaley!

I think I understand the reasons behind each of the changes you made to the rule. I do have one other question. The new rule does what I was looking for but with one minor glitch, which is my fault.

I have a few sets of tags which are associated with the same icon:
tag2 & tag8 = letter-c-icon.png
tag3 & tag4 = letter-b-icon.png
tag6 & tag14 = letter-x-icon.png
tag9 & tag10 = letter-p-icon.png
tag12 & tag13 = letter-s-icon.png
Which I'm realizing is about half the tags in the rule. Anyway I use them as warnings, for example tag2 and tag8 are cheating and infidelity respectively, so they're essentially the same thing but some stories have one tag and some stories have the other tag. What I didn't take into account are stories which have both tags so I end up with the C icon twice.

So I did a little searching and found this forum thread and I think the Or function is what I want to incorporate but I'm not sure how or if I'm better off setting each pair up as a separate rule.

I tried setting it up this way:

Code:
program:
 t = field('tags');
 strcat
 ( 
		contains(t, "tag1", 'letter-a-icon.png:', ''), 
                contains(t, "tag3", 'letter-b-icon.png:', ''),
                contains(t, "tag4", 'letter-b-icon.png:', ''),
		contains(t, "tag5", 'letter-d-icon.png:', ''), 
		contains(t, "tag6", 'letter-x-icon.png:', ''), 
		contains(t, "tag7", 'letter-i-icon.png:', ''), 
		contains(t, "tag9", 'letter-p-icon.png:', ''), 
		contains(t, "tag10", 'letter-p-icon.png:', ''), 
		contains(t, "tag11", 'letter-r-icon.png:', ''), 
		contains(t, "tag12", 'letter-s-icon.png:', ''), 
		contains(t, "tag13", 'letter-s-icon.png:', ''), 
		contains(t, "tag14", 'letter-x-icon.png:', ''), 
		contains(t, "tag15", 'letter-w-icon.png:', ''),
or(
			contains(t, "tag2", 'y', ''),
			contains(t, "tag8", 'y', ''),

		),
		'letter-c-icon.png:',
		''
 )
Only that added the C icon to every book and not just the ones with tag2 and/or tag8. Switching Strcat to Test gave me an Exception error and I assume switching to First_non-empty will give me the same issue I originally had.

When I set it up as a separate rule
Code:
program:
 t = field('tags');
	test(
		or(
			contains(t, "cheating", 'y', ''),
			contains(t, "infidelity", 'y', ''),

		),
		'letter-c-icon.png',
		''
)
It works perfectly.
So I'm wondering if I should set each one up separately or if I'll have to worry about it bogging down Calibre? Thanks again for the help.
BookJunkieLI is offline   Reply With Quote
Old 07-11-2018, 12:10 PM   #4
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 11,773
Karma: 7029857
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Ok, time to get into some details.

1) Lets first fix your non-working example.
Code:
program:
 t = field('tags');
 strcat
 ( 
		contains(t, "tag1", 'letter-a-icon.png:', ''), 
                contains(t, "tag3", 'letter-b-icon.png:', ''),
                contains(t, "tag4", 'letter-b-icon.png:', ''),
		contains(t, "tag5", 'letter-d-icon.png:', ''), 
		contains(t, "tag6", 'letter-x-icon.png:', ''), 
		contains(t, "tag7", 'letter-i-icon.png:', ''), 
		contains(t, "tag9", 'letter-p-icon.png:', ''), 
		contains(t, "tag10", 'letter-p-icon.png:', ''), 
		contains(t, "tag11", 'letter-r-icon.png:', ''), 
		contains(t, "tag12", 'letter-s-icon.png:', ''), 
		contains(t, "tag13", 'letter-s-icon.png:', ''), 
		contains(t, "tag14", 'letter-x-icon.png:', ''), 
		contains(t, "tag15", 'letter-w-icon.png:', ''),
		test(or(
				contains(t, "tag2", 'y', ''),
				contains(t, "tag8", 'y', ''),
			), 'letter-c-icon.png:', '')
 )
The problem with your example is that the value of the "or" was thrown away, making the strcat always add letter-c-icon.png to the result. Using "test" takes care of that problem, adding letter-c-icon.png only if the "or" returns a non-empty value.

2) Efficient "or": the "contains" function actually searches using a regular expression, not a basic string. This means that using the "or" capability built into regexps ('val1|val2') you can do "or" tests without changing very much. For example, the following replaces your first example, with the added benefit of better performance. I didn't bother to copy the tag1 through tag12 lines.

Code:
program:
 t = field('tags');
 strcat
 ( 
		contains(t, "tag13", 'letter-s-icon.png:', ''), 
		contains(t, "tag14", 'letter-x-icon.png:', ''), 
		contains(t, "tag15", 'letter-w-icon.png:', ''),
		contains(t, "tag2|tag8", 'letter-c-icon.png:', '')
 )
3) There is a gotcha: substrings in tags. Consider an example where you want an icon for fidelity instead of infidelity. This template would do it:
Code:
program:
 t = field('tags');
 strcat
 ( 
		contains(t, "fidelity|monogamy", 'letter-m-icon.png:', '')
 )
Unfortunately it would also match the tag "infidelity" because it contains the substring "fidelity". There is an easy way to avoid this as long as your tags contain only alphanumeric or underscores: use the regexp boundary test \b which matches if the previous/next character is not alphanumeric or underscore. For example:
Code:
program:
 t = field('tags');
 strcat
 ( 
		contains(t, "\bfidelity\b|monogamy", 'letter-m-icon.png:', '')
 )
would not match "infidelity" because the 'n' in front of 'fidelity' does not satisfy the boundary test.
chaley is offline   Reply With Quote
Old 07-11-2018, 02:00 PM   #5
BookJunkieLI
Evangelist
BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.BookJunkieLI ought to be getting tired of karma fortunes by now.
 
BookJunkieLI's Avatar
 
Posts: 435
Karma: 572984
Join Date: Jan 2010
Location: Long Island
Device: Kobo Libra 2, Kindle 4, Nook Gl4, Nook STR, REB 1100, Ebookwise 1500,
Awesome! Thanks again for all your help, chaley.
BookJunkieLI is offline   Reply With Quote
Advert
Reply


Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Advanced Icon Rule with Exception Tanjamuse Library Management 21 05-01-2018 01:26 AM
Help with Icon Rule Tanjamuse Library Management 17 10-13-2016 03:30 PM
Does anyone know of a way to create a column coloring rule for a condition like this? readin Library Management 2 07-27-2016 12:48 AM
Advanced Custom Icon with two requirements One4Tanner Library Management 3 03-11-2015 02:14 AM
Display more than one column icon blaubach Calibre 3 09-21-2013 01:36 PM


All times are GMT -4. The time now is 12:24 PM.


MobileRead.com is a privately owned, operated and funded community.