View Single Post
Old 10-07-2014, 05:01 AM   #608
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: 12,486
Karma: 8025704
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by MiniMouse View Post
I'm trying to organize my fanfiction columns, more specific my relationsship column (I think tags-like, I'm not home at the moment, so I can't look). I want the pairings look the same what ever site taken from and I thought that might be easier over the custom column than the personal.ini of FFDL.

...

So how do I do that for a whole list of pairings?

Mini
What you want to do is very hard with regular expressions. Basically you would need to apply a separate regexp for each possible pairing, because there is no way to express A->B, C->D in a regular expression.

If your relationship names all have the form ("some characters" space "desired name") (all of your examples do have this form) then you can easily do what you want by stripping all the leading characters from the name to leave the last word. This GPM template shows how to do that.
Code:
program:
	sample = 'S. Holmes/J. Watson, S. Moran/J. Moriarty';
	list_re(sample, ',',  '^.* ([^ ]*)/.* ([^ ]*$)', '\1/\2')
"Sample" would become "field('#relationship')"

This scheme will not work if the last word must change based on the original. For example, it won't work if you want 'S. Holmes/J. Watson' to become 'Holmes/Whatnot" because whether or not to change from Watson to Whatnot depends on the seeing "Watson" and not "Moran". It also will not work if last names can be two words, such as von Trapp.

If in fact you really want a series of expressions of the form A becomes B then you would need to write each of them as a separate regular expression. If there are more than a few of them, the performance would be terrible.

An alternate approach would be to write a custom template function that uses python dictionaries to make the changes. This would have acceptable performance (I think) but requires you to know how to code in python. The maintenance would also be problematic because all changes would need to be made in python.

Yet another alternate approach would be to write a calibre python script that processes the relationship column to create another tags-like column containing the values you want. This would have great performance and be somewhat easier to maintain, but still suffers from having to do it in python. An example of what this might look like is under the spoiler.
Spoiler:
Code:
def init_cache(library_path):
	from calibre.db.backend import DB
	from calibre.db.cache import Cache
	backend = DB(library_path)
	cache = Cache(backend)
	cache.init()
	return cache

from collections import defaultdict
	
cache = init_cache(library_path = sys.argv[1])

transformation_dict = {
	'Sherlock Holmes': 'Holmes',
	'S. Holmes': 'Holmes',
	'John Watson': 'Watson',
	'J. Watson': 'Watson',
	'Sebastian Moran': 'Moran',
	'S. Moran': 'Moran',
	'Jim Moriarty': 'Moriarty',
	'J. Moriarty': 'Moriarty'
	}

values_to_write = {}
for id_ in cache.all_book_ids():
	relationships = cache.field_for('#mytextmult', id_)
	new_relationships = []
	if relationships:
		for relationship in relationships:
			pair = relationship.split('/')
			if len(pair) == 2:
				left, right = pair
				newleft = transformation_dict.get(left, left)
				newright = transformation_dict.get(right, right)
				new_relationships.append(newleft + '/' + newright)
			else:
				new_relationships.append(relationship)
		values_to_write[id_] = new_relationships
print values_to_write

cache.set_field('#mytextmult', values_to_write)
chaley is offline   Reply With Quote