calibre User Manual, Release 2.57.1
DEVICE_METADATA_FIELDS).union(
CALIBRE_METADATA_FIELDS)
# All fields except custom fields
STANDARD_METADATA_FIELDS = SOCIAL_METADATA_FIELDS.union(
PUBLICATION_METADATA_FIELDS).union(
BOOK_STRUCTURE_FIELDS).union(
DEVICE_METADATA_FIELDS).union(
CALIBRE_METADATA_FIELDS)
# Metadata fields that smart update must do special processing to copy.
SC_FIELDS_NOT_COPIED =
frozenset(['title''title_sort''authors',
'author_sort', 'author_sort_map',
'cover_data', 'tags', 'languages',
'identifiers'])
# Metadata fields that smart update should copy only if the source is not None
SC_FIELDS_COPY_NOT_NULL =
frozenset(['lpath''size''comments''thumbnail'])
# Metadata fields that smart update should copy without special handling
SC_COPYABLE_FIELDS =
SOCIAL_METADATA_FIELDS.union(
PUBLICATION_METADATA_FIELDS).union(
BOOK_STRUCTURE_FIELDS).union(
DEVICE_METADATA_FIELDS).union(
CALIBRE_METADATA_FIELDS) - \
SC_FIELDS_NOT_COPIED.union(
SC_FIELDS_COPY_NOT_NULL)
SERIALIZABLE_FIELDS =
SOCIAL_METADATA_FIELDS.union(
USER_METADATA_FIELDS).union(
PUBLICATION_METADATA_FIELDS).union(
CALIBRE_METADATA_FIELDS).union(
DEVICE_METADATA_FIELDS) - \
frozenset(['device_collections''formats',
'cover_data'])
# these are rebuilt when needed
Using general program mode
For more complicated template programs, it is sometimes easier to avoid template syntax (all the { and } characters),
instead writing a more classical-lookingprogram. Youcan do this in calibre by beginning the template with program:.
In this case, no template processing is done. The special variable $ is not set. It is up to your program to produce the
correct results.
One advantage of program: mode is that the brackets are no longer special. For example, it is not necessary to use [[
and]] when usingthe template()function. Another advantage is thatprogrammode templates are compiled toPython
and can run much faster than templates in the other two modes. Speed improvement depends on the complexity of
the templates; the more complicated the template the more the improvement. Compilation is turned off or on using
the tweak compile_gpm_templates (Compile General Program Mode templates to Python). The main reason to
turn off compilation is if a compiled template does not work,in which case please file a bug report.
The following example is a program: mode implementationof a recipe on the MobileRead forum: “Put series into the
title, using either initials or a shortened form. Strip leading articles from the series name (any).” For example, for the
book The Two Towers in the Lord of the Rings series, the recipe gives LotR [02] The Two Towers. Using standard
templates, the recipe requires three custom columns and a plugboard, as explained in the following:
The solution requires creating three composite columns. The first column is used to remove the leading articles. The
1.9. Tutorials
157
Adding form fields to pdf files - C# PDF Field Edit Library: insert, delete, update pdf form field in C#.net, ASP.NET, MVC, Ajax, WPF
Online C# Tutorial to Insert, Delete and Update Fields in PDF Document
changing font size in pdf form field; add photo to pdf form
Adding form fields to pdf files - VB.NET PDF Field Edit library: insert, delete, update pdf form field in vb.net, ASP.NET, MVC, Ajax, WPF
How to Insert, Delete and Update Fields in PDF Document with VB.NET Demo Code
adding text fields to pdf; changing font in pdf form
calibre User Manual, Release 2.57.1
second is used to compute the ‘shorten’ form. The third is to compute the ‘initials’ form. Once you have these
columns, the plugboard selects between them. You can hide any or all of the three columns on the library view:
First column:
Name: #stripped_series.
Template: {series:re(^(A|The|An)\s+,)||}
Second column (the shortened form):
Name: #shortened.
Template: {#stripped_series:shorten(4,-,4)}
Third column (the initials form):
Name: #initials.
Template: {#stripped_series:re(([^\s])[^\s]+(\s|$),\1)}
Plugboard expression:
Template:{#stripped_series:lookup(.\s,#initials,.,#shortened,series)}{series_index:0>2.0f| [|] ] }{title}
Destination field: title
This set of fields and plugboard produces:
Series: The Lord of the Rings
Series index: 2
Title: The Two Towers
Output: LotR [02] The Two Towers
Series: Dahak
Series index: 1
Title: Mutineers Moon
Output: Dahak [01] Mutineers Moon
Series: Berserkers
Series Index: 4
Title: Berserker Throne
Output: Bers-kers [04] Berserker Throne
Series: Meg Langslow Mysteries
Series Index: 3
Title: Revenge of the Wrought-Iron Flamingos
Output: MLM [03] Revenge of the Wrought-Iron Flamingos
The following program produces the same results as the original recipe, using only one custom column to hold the
results ofa program that computes the special title value:
Custom column:
Name: #special_title
Template: (the following with all leading spaces removed)
program:
#
compute the equivalent of the composite fields and store them in local variables
stripped = re(field('series'), '^(A|The|An)\s+''');
shortened = shorten(stripped, 4'-' ,4);
initials = re(stripped, '[^\w]
*
(\w?)[^\s]+(\s|$)', '\1');
#
Format the series index. Ends up as empty if there is no series index.
#
Note that leading and trailing spaces will be removed by the formatter,
#
so we cannot add them here. We will do that in the strcat below.
#
Also note that because we are in 'program' mode, we can freely use
#
curly brackets in strings, something we cannot do in template mode.
s_index = template('{series_index:0>2.0f}');
158
Chapter 1. Sections
VB.NET PDF Library SDK to view, edit, convert, process PDF file
Capable of adding PDF file navigation features to your VB.NET program. and load PDF from other file formats; merge, append, and split PDF files; insert, delete
android edit pdf forms; add image field to pdf form
C# PDF insert image Library: insert images into PDF in C#.net, ASP
Insert images into PDF form field. To help you solve this technical problem, we provide this C#.NET PDF image adding control, XDoc.PDF for .NET.
add attachment to pdf form; change font pdf form
calibre User Manual, Release 2.57.1
#
print(stripped, shortened, initials, s_index);
#
Now concatenate all the bits together. The switch picks between
#
initials and shortened, depending on whether there is a space
#
in stripped. We then add the brackets around s_index if it is
#
not empty. Finally, add the title. As this is the last function in
#
the program, its value will be returned.
strcat(
switch( stripped,
'.\s', initials,
'.', shortened,
field('series')),
test(s_index, strcat(' [', s_index, '] '), ''),
field('title'));
Plugboard expression:
Template:{#special_title}
Destination field: title
It would be possible to do the above with no custom columns by putting the program into the template box of the
plugboard. However,to do so, all comments must be removedbecause the plugboard text box does not support multi-
line editing. It is debatable whether the gain of not having the custom column is worth the vast increase in difficulty
causedby the program being one giant line.
User-defined Template Functions
You can add your own functions to the template processor. Such functions are written in python, and can be used
in any of the three template programming modes. The functions are added by going to Preferences -> Advanced ->
Template Functions. Instructions are shown in that dialog.
Special notes for save/send templates
Special processing is applied when a template is used in a save to disk or send to device template. The values of the
fields are cleaned,replacing characters that are special tofile systems with underscores,includingslashes. This means
that field text cannot be used to create folders. However, slashes are not changed in prefix or suffix strings, so slashes
in these strings will cause folders to be created. Because ofthis,you can create variable-depth folder structure.
For example, assume we want the folder structure series/series_index - title, with the caveat that if series does not
exist, then the title should be in the top folder. The template to do this is:
{series:||/}{series_index:|| - }{title}
The slash and the hyphen appear only ifseries is not empty.
The lookup function lets us do even fancier processing. For example,assume that ifa book has a series,then we want
the folder structure series/series index - title.fmt. If the book does not have a series, then we want the folder structure
genre/author_sort/title.fmt. If the book has no genre, we want to use ‘Unknown’. We want two completely different
paths, depending on the value of series.
To accomplishthis, we:
1. Create a composite field (call it AA) containing{series}/{series_index} - {title’}. If the
series is not empty,then this template will produce series/series_index - title.
2. Create acompositefield(callitBB)containing {#genre:ifempty(Unknown)}/{author_sort}/{title}.
This template produces genre/author_sort/title, where an empty genre is replaced with Unknown.
1.9. Tutorials
159
C# PDF Page Insert Library: insert pages into PDF file in C#.net
such as how to merge PDF document files by C# code PDF document pages and how to split PDF document in APIs, C# programmers are capable of adding and inserting
pdf fillable form creator; change font pdf fillable form
C# Create PDF Library SDK to convert PDF from other file formats
Create fillable PDF document with fields. you can also protect created PDF file by adding digital signature Create PDF Document from Existing Files Using C#.
pdf form change font size; add text field to pdf acrobat
calibre User Manual, Release 2.57.1
3. Setthe save template to {series:lookup(.,AA,BB)}. This template chooses composite field AA if
series is not empty, and composite field BB ifseries is empty. We therefore have two completely different
save paths, depending on whether ornot series is empty.
Templates and Plugboards
Plugboards are used for changing the metadata written into books during send-to-device and save-to-disk operations.
Aplugboard permits you to specify a template to provide the data to write into the book’s metadata. You can use
plugboards to modifythe following fields: authors, author_sort, language,publisher, tags,title, title_sort. This feature
helps people who want to use different metadata in books on devices to solve sorting or display issues.
When you create a plugboard, you specify the format and device for which the plugboard is to be used. A special
device is provided, save_to_disk, that is used when saving formats (as opposed to sending them to a device). Once
you have chosen the format and device, you choose the metadata fields to change, providing templates to supply the
new values. These templates are connected to their destination fields,hence the name plugboards. You can, of course,
use composite columns in these templates.
When aplugboard might apply(contentserver,saveto disk,orsendtodevice),calibre searches the definedplugboards
tochoose the correctone forthe givenformat and device. Forexample,to findthe appropriate plugboard foran EPUB
book being sent to an ANDROID device, calibre searches the plugboards using the following search order:
• a plugboard with an exact match on format and device,e.g., EPUB and ANDROID
• a plugboardwith an exactmatchonformatandthe special any device choice,e.g.,EPUBandany device
• a plugboard with the special any format choice and an exact match on device, e.g., any format and
ANDROID
• a plugboard with any format and any device
The tags and authors fields have special treatment, because both of these fields can hold more than one item. A book
can have many tags and many authors. When you specify that one ofthese two fields is to be changed, the template’s
resultis examinedto see if more thanone itemis there. For tags,the result is cut apartwherevercalibre finds a comma.
For example, if the template produces the value Thriller, Horror,then the result will be two tags,Thriller
and Horror. There is no way to put a comma in the middle of a tag.
The same thing happens for authors, but using a different character for the cut, a &(ampersand) instead of a comma.
Forexample,ifthetemplate produces the value Blogs, Joe&Posts, Susan, thenthe book will end up withtwo
authors, Blogs, Joe and Posts, Susan. Ifthe template produces the value Blogs, Joe;Posts, Susan,
then the book will have one authorwith a rather strange name.
Plugboards affect the metadata written into the book when it is saved to disk or written to the device. Plugboards
do not affect the metadata used by save to disk and send to device to create the file names. Instead, file
names are constructed usingthe templates entered on the appropriate preferences window.
Helpful Tips
You might find the following tips useful.
• Create a custom composite column to test templates. Once you have the column, you can change its template
simply by double-clicking on the column. Hide the column when you are not testing.
• Templates can use othertemplates by referencing a composite custom column.
• In a plugboard, you can set a field to empty (or whatever is equivalent to empty) by using the special template
{}. This template will always evaluate to an emptystring.
• The technique described above to show numbers even if they have a zero value works with the standard field
series_index.
160
Chapter 1. Sections
C# PDF Library SDK to view, edit, convert, process PDF file for C#
Capable of adding PDF file navigation features to your C# merge, append, and split PDF files; insert, delete to insert, delete and update PDF form fields in C#
add forms to pdf; change font size in pdf form field
VB.NET PDF File & Page Process Library SDK for vb.net, ASP.NET
add it into the original PDF document to form a complete detailed guidance on creating, loading, merge and splitting PDF pages and Files, adding a page
convert word doc to pdf with editable fields; pdf save form data
calibre User Manual, Release 2.57.1
1.9.4 All about using regular expressions in calibre
Regular expressions are features used in many places in calibre to performsophisticatedmanipulationofebookcontent
and metadata. This tutorial is a gentle introduction to getting you started with using regular expressions in calibre.
Contents
• First,awordofwarningandawordofcourage(page 161)
• Whereincalibrecanyouuseregularexpressions?(page 161)
• Whatonearthisaregularexpression?(page 161)
• Caretoexplain?(page 162)
• Thatdoesn’tsoundtoobad.What’snext? (page 162)
• Hey,neat!Thisisstartingtomakesense!(page 162)
• Well,thesespecialcharactersareveryneatandall,butwhatifIwantedtomatchadotoraquestion
mark?(page163)
• So,whatarethemostusefulsets? (page 163)
• ButifIhadafewvaryingstringsIwantedtomatch,thingsgetcomplicated? (page 163)
• Youmissed...(page 164)
• Inthebeginning,yousaidtherewasawaytomakearegularexpressioncaseinsensitive? (page 164)
• IthinkI’mbeginningtounderstandthese regular expressionsnow... . how w doIusethemincalibre?
(page 164)
– Conversions(page 164)
– Addingbooks(page 165)
– Bulkeditingmetadata(page 165)
• Credits(page 166)
First, a word of warning and a word of courage
This is,inevitably,goingtobe somewhattechnical-afterall, regularexpressions area technicaltool fordoingtechnical
stuff. I’m going to have to use some jargon and concepts that may seem complicated or convoluted. I’mgoing to try
to explain those concepts as clearly as I can, but really can’t do without using them at all. That being said, don’t be
discouraged by any jargon, as I’ve tried to explain everything new. And while regular expressions themselves may
seemlikean arcane,blackmagic(or,tobemoreprosaic,a randomstring of mumbo-jumboletters andsigns),Ipromise
that they are not all thatcomplicated. Even those who understand regular expressions really well have trouble reading
the more complex ones, but writing them isn’t as difficult- you construct the expression step by step. So, take a step
and follow me into the rabbit hole.
Where in calibre can you use regular expressions?
There are a few places calibre uses regular expressions. There’s the Search& Replacein conversion options,metadata
detection fromfilenames in the importsettings and Search &Replace when editing the metadata of books in bulk. The
calibre book editor can also use regular expressions in its search and replace feature.
What on earth is a regular expression?
Aregular expression is a way to describe sets of strings. A single regular expression can match a number of different
strings. This is what makes regular expression so powerful – they are a concise way of describing a potentially large
number ofvariations.
Note: I’m using string here in the sense it is used in programming languages: a string of one or more characters,
1.9. Tutorials
161
C# PDF File & Page Process Library SDK for C#.net, ASP.NET, MVC
to PDF; VB.NET Form: extract value from fields; Form Process. Data: Read, Extract Field Data. Data: Auto Fill Provides you with examples for adding an (empty) page
create a fillable pdf form; best pdf form creator
C# PDF insert text Library: insert text into PDF content in C#.net
text character and text string to PDF files using online text to PDF page using .NET XDoc.PDF component in Supports adding text to PDF in preview without adobe
change font in pdf form; pdf form save in reader
calibre User Manual, Release 2.57.1
characters including actual characters, numbers, punctuation and so-called whitespace (linebreaks, tabulators etc.).
Please note that generally,uppercase and lowercase characters are not considered the same, thus “a” being a different
character from “A” and so forth. In calibre, regular expressions are case insensitive in the search bar, but not in the
conversionoptions. There’s awaytomake every regularexpression case insensitive,butwe’lldiscuss thatlater. It gets
complicated because regular expressions allow for variations in the strings it matches, so one expression can match
multiple strings, which is why people bother using them at all. More on that in a bit.
Care to explain?
Well, that’s why we’re here. First, this is the most important concept in regular expressions: A string by itself is a
regular expression that matches itself. That is to say, if I wanted to match the string "Hello, World!" using
aregular expression, the regular expression to use would be Hello, World!. And yes, it really is that simple.
You’ll notice,though, that this only matches the exact string "Hello, World!", not e.g. "Hello, wOrld!" or
"hello, world!" orany other such variation.
That doesn’t sound too bad. What’s next?
Next is the beginning of the really good stuff. Remember where I said that regular expressions can match multiple
strings? This is were it gets a little more complicated. Say, as a somewhat more practical exercise, the ebook you
wanted to convert had a nasty footer counting the pages,like “Page 5 of 423”. Obviously the page numberwould rise
from 1 to 423, thus you’d have to match 423 different strings, right? Wrong, actually: regular expressions allow you
to define sets of characters that are matched: To define a set, you put all the characters you want to be in the set into
square brackets. So, for example, the set [abc] would match either the character “a”, “b” or “c”. Sets will always
only matchone of the characters in the set. They “understand” character ranges, that is,if you wanted to match all the
lower case characters, you’d use the set [a-z] forlower- and uppercase characters you’d use [a-zA-Z] and so on.
Got the idea? So, obviously, using the expression Page [0-9] of 423 you’d be able to match the first 9 pages,
thus reducing the expressions needed to three: The second expression Page [0-9][0-9] of 423 would match
all two-digit page numbers, and I’m sure you can guess what the third expression would look like. Yes, go ahead.
Write it down.
Hey, neat! This is starting to make sense!
Iwas hoping you’d say that. But brace yourself,now it gets even better! We just saw that using sets, we could match
one of several characters at once. But you can even repeat a character or set, reducing the number of expressions
needed to handle the above page number example to one. Yes, ONE! Excited? You should be! It works like this:
Some so-called special characters,“+”, ”?” and “*”,repeat the single element precedingthem. (Element means either
asingle character,a character set,an escape sequence or a group (we’ll learn about those last two later)- in short, any
single entity in a regular expression.) These characters are called wildcards or quantifiers. To be more precise, ”?”
matches 0 or 1 of the preceding element, “*” matches 0 or more of the preceding element and “+” matches 1 or more
of the preceding element. A few examples: The expression a? would match either“” (which is the empty string, not
strictly useful in this case) or “a”, the expression a
*
would match “”, “a”, “aa” or any number of a’s in a row, and,
finally, the expression a+ would match “a”, “aa” or any number of a’s in a row (Note: it wouldn’t match the empty
string!). Same deal forsets: The expression [0-9]+ would match every integer number there is! I know what you’re
thinking, and you’re right: If you usethatin the above caseof matching page numbers,wouldn’t that be the single one
expression to match all the page numbers? Yes, the expression Page [0-9]+ of 423 would match every page
number in that book!
Note: A note on these quantifiers: They generally try to match as much text as possible, so be careful when using
them. This is called “greedy behaviour”- I’msure you get why. It gets problematic when you, say,try to match a tag.
Consider, for example, the string "<p class="calibre2">Title here</p>" and let’s say you’d want to
162
Chapter 1. Sections
C# PDF Digital Signature Library: add, remove, update PDF digital
to PDF; VB.NET Form: extract value from fields; Form Process. Data: Read, Extract Field Data. Data: Auto Fill Security of Your PDF File by Adding Digital Signatures
change font size in pdf form; pdf form maker
C# PDF Password Library: add, remove, edit PDF file password in C#
Following are examples for adding password to a plain PDF passwordSetting.IsAnnot = true; // Allow to fill form. IsAssemble = true; // Add password to PDF file
change font size pdf form; change text size pdf form
calibre User Manual, Release 2.57.1
matchthe openingtag (the part betweenthefirst pair of angle brackets,a littlemore on tags later). You’d think that the
expression<p.
*
>wouldmatchthattag, butactually, it matches thewhole string! (The character ”.” is anotherspecial
character. It matches anything except linebreaks, so,basically,the expression.
*
would matchanysingle line you can
think of.) Instead, try using <p.
*
?> which makes the quantifier"
*
"non-greedy. That expression would only match
the first opening tag, as intended. There’s actually another way to accomplish this: The expression <p[^>]
*
>will
match that same opening tag- you’ll see why after the next section. Just note that there quite frequently is more than
one way towrite a regular expression.
Well, these special charactersare veryneat and all, but what if I wanted to match adotor a question
mark?
You can of course do that: Just put a backslash in front of any special character and it is interpreted as the literal
character, without any special meaning. This pair of a backslash followed by a single character is called an escape
sequence,and the act ofputting a backslash in front ofa special character is called escaping that character. An escape
sequence is interpreted as a single element. There are of course escape sequences that do more than just escaping
special characters, for example "\t" means a tabulator. We’ll get to some of the escape sequences later. Oh, and by
the way, concerning those special characters: Consider any character we discuss in this introduction as having some
function to be special and thus needing to be escaped if you want the literal character.
So, what are the most useful sets?
Knew you’d ask. Some useful sets are [0-9] matching a single number, [a-z] matching a single lowercase letter,
[A-Z] matching a single uppercase letter,[a-zA-Z]matching asingle letterand [a-zA-Z0-9]matching asingle
letter or number. You can also use an escape sequence as shorthand:
\d is equivalent to [0-9]
\w is equivalent to [a-zA-Z0-9_]
\s is equivalent to any whitespace
Note: “Whitespace” is a term for anything thatwon’t be printed. These characters include space, tabulator, line feed,
form feed and carriage return.
As a last note on sets, you can also define a set as any character but those in the set. You do that by including the
character "^" as the very first character in the set. Thus, [^a] would match any character excluding “a”. That’s
called complementing the set. Those escape sequence shorthands we saw earlier can also be complemented: "\D"
means any non-number character, thus being equivalent to [^0-9]. The other shorthands can be complemented by,
you guessed it, using the respective uppercase letter instead of the lowercase one. So, going back to the example
<p[^>]
*
>from the previous section, now you can see that the character set it’s using tries to match any character
except for a closing angle bracket.
But if I had a few varying strings I wanted to match, things get complicated?
Fear not, life still is good and easy. Consider this example: The book you’re converting has “Title” written on every
odd page and “Author” written on every even page. Looks great in print, right? But in ebooks, it’s annoying. You
can group whole expressions in normal parentheses, and the character "|" will let you match either the expression
to its right or the one to its left. Combine those and you’re done. Too fast for you? Okay, first off, we group the
expressions for odd and even pages, thus getting (Title)(Author) as our two needed expressions. Now we
make things simpler by using the vertical bar ("|" is called the vertical bar character): If you use the expression
(Title|Author) you’ll either get a match for “Title” (on the odd pages) or you’d match “Author” (on the even
pages). Well, wasn’t that easy?
1.9. Tutorials
163
calibre User Manual, Release 2.57.1
You can, of course, use the vertical bar without using grouping parentheses, as well. Remember when I said that
quantifiers repeat the element preceding them? Well, the vertical bar works a little differently: The expression “Ti-
tle|Author” will also match either the string “Title” or the string “Author”, just as the above example using grouping.
The vertical bar selects between the entire expression preceding and following it. So, if you wanted to match the
strings “Calibre” and “calibre” and wanted to select only between the upper- and lowercase “c”, you’d have to use
the expression (c|C)alibre, where the grouping ensures that only the “c” will be selected. If you were to use
c|Calibre,you’d get a match on the string “c” or on the string “Calibre”, which isn’t what we wanted. In short: If
in doubt, use grouping together with the vertical bar.
You missed...
... wait just a minute, there’s one last,reallyneatthingyoucan do withgroups. Ifyouhave a group thatyoupreviously
matched, you can use references to that group later in the expression: Groups are numbered starting with 1, and you
reference them by escaping the number of the group you want to reference, thus, the fifth group would be referenced
as \5. So,if you searched for ([^ ]+) \1 in the string “Test Test”,you’d match the whole string!
In the beginning, you said there was a way to make a regular expression case insensitive?
Yes, I did, thanks for paying attention and reminding me. You can tell calibre how you want certain things handled
by using something called flags. You include flags in your expression by using the special construct (?flags go
here) where, obviously, you’d replace “flags go here” with the specific flags you want. For ignoring case, the flag
is i, thus you include (?i) in your expression. Thus, test(?i) would match “Test”, “tEst”, “TEst” and any case
variation you could think of.
Anotheruseful flag lets the dot matchany character at all, including the newline, the flag s. If youwant touse multiple
flags in an expression, just put them in the same statement: (?is) would ignore case and make the dot match all. It
doesn’t matter whichflag you state first,(?si) would beequivalent tothe above. By the way,good places forputting
flags in your expression would be either the very beginning or the very end. That way, they don’t get mixed up with
anything else.
Ithink I’m beginning to understand these regular expressions now... how do I use them in calibre?
Conversions
Let’s begin with the conversion settings, which is really neat. In the Search and Replace part, you can input a regexp
(short for regular expression)that describes the string that will be replaced during the conversion. The neat part is the
wizard. Click on the wizard staff and you get a preview of what calibre “sees” during the conversion process. Scroll
down to the string you want to remove, select and copy it,paste it into the regexp field on top of the window. Ifthere
are variable parts, like page numbers orso, use sets and quantifiers to cover those,and while you’re at it, remember to
escapespecialcharacters,ifthere are some. Hitthe button labeledTest andcalibrehighlights the parts it would replace
were you to use the regexp. Once you’re satisfied, hit OK and convert. Be careful if your conversion source has tags
like this example:
Maybe, but the cops feel like you do, Anita. What's one e more dead d vampire?
New laws don't change that. . </p>
<p class="calibre4"> <b class="calibre2">Generated by y ABC Amber LIT T Conv
<a href="http://www.processtext.com/abclit.html" class="calibre3">erter,
http://www.processtext.com/abclit.html</a></b></p>
<p class="calibre4"It had only y been two o years since Addison n vClark.
The court case gave us a revised version of what life was
164
Chapter 1. Sections
calibre User Manual, Release 2.57.1
(shamelessly ripped out ofthisthread
78
). You’d have to remove some of the tags as well. In this example, I’d
recommend beginning with the tag <b class="calibre2">, now you have to end with the corresponding clos-
ing tag (opening tags are <tag>, closing tags are </tag>), which is simply the next </b> in this case. (Re-
fer to a good HTML manual or ask in the forum if you are unclear on this point.) The opening tag can be de-
scribed using <b.
*
?>, the closing tag using </b>, thus we could remove everything between those tags using
<b.
*
?>.
*
?</b>. But using this expression would be a bad idea, because it removes everything enclosed by <b>-
tags (which, by the way, render the enclosed text in bold print), and it’s a fair bet that we’ll remove portions of
the book in this way. Instead, include the beginning of the enclosed string as well, making the regular expression
<b.
*
?>\s
*
Generated\s+by\s+ABC\s+Amber\s+LIT.
*
?</b> The \s with quantifiers are included here
instead of explicitly using the spaces as seen in the string to catch any variations of the string that might occur. Re-
member to check what calibre will remove to make sure you don’t remove any portions you want to keep if you test
anew expression. If you only check one occurrence, you might miss a mismatch somewhere else in the text. Also
note that should you accidentally remove more or fewer tags than you actually wanted to, calibre tries to repair the
damaged code afterdoing the removal.
Addingbooks
Another thing you can use regular expressions for is to extract metadata from filenames. You can find this feature in
the “Adding books”part ofthe settings. There’s a special feature here: Youcan use field names formetadatafields, for
example (?P<title>) would indicate that calibre uses this part ofthe stringas booktitle. The allowed field names
are listed in the windows, together with another nice test field. An example: Say you want to import a whole bunch
of files named like Classical Texts:
The Divine Comedy by Dante Alighieri.mobi. (Obvi-
ously, this is already in your library, since we all love classical italian poetry) or Science Fiction epics:
The Foundation Trilogy by Isaac Asimov.epub. This is obviously a naming scheme that calibre
won’t extract any meaningful data out of - its standard expression for extracting metadata is (?P<title>.+) -
(?P<author>[^_]+). A regular expression that works here would be [a-zA-Z]+: (?P<title>.+) by
(?P<author>.+). Please note that,inside the group forthe metadata field, you need to use expressions to describe
what the field actually matches. And also note that, when using the test field calibre provides, you need to addthe file
extension to yourtesting filename,otherwise you won’t get any matches at all,despite using a working expression.
Bulk editing metadata
The last part is regular expression search and replace in metadata fields. You can access this by selecting multiple
books in the library and using bulk metadata edit. Be very careful when using this last feature, as it can do Very
Bad Things to your library! Doublecheck that your expressions do what you want them to using the test fields, and
only mark the books you really want to change! In the regular expression search mode, you can search in one field,
replace the text with something and even write the result into another field. A practical example: Say your library
contained the books of Frank Herbert’s Dune series, named after the fashion Dune 1 - Dune,Dune 2 - Dune
Messiah and so on. Now you wantto get Dune intothe series field. Youcan do that by searching for(.
*
?)
\d+
- .
*
in the title field and replacing it with \1 in the series field. See what I did there? That’s a reference to the first
group you’re replacing the series field with. Now that you have the series all set, you only need to do another search
for .
*
?
-in the title field and replace it with "" (an empty string), again in the title field, and your metadata is all
neat and tidy. Isn’t that great? By the way, instead of replacing the entire field, you can also append or prepend to the
field,so, if you wanted the book title to be prepended with series info,youcould do that as well. As you by now have
undoubtedly noticed, there’s a checkbox labeled Case sensitive, so you won’t have to use flags to select behaviour
here.
Well, that just about concludes the very short introduction to regular expressions. Hopefully I’ll have shown you
enough to at least get you started and to enable you to continue learning by yourself- a good starting point would be
thePythondocumentationforregexps
79
.
78
http://www.mobileread.com/forums/showthread.php?t=75594”
79 https://docs.python.org/2/library/re.html
1.9. Tutorials
165
calibre User Manual, Release 2.57.1
One last word of warning, though: Regexps are powerful, but also really easy to get wrong. calibre provides really
great testingpossibilities tosee if yourexpressions behave as you expect themto. Use them. Try not to shootyourself
in the foot. (God, I love that expression...) But should you, despite the warning, injure your foot (or any other body
parts), try to learnfrom it.
Credits
Thanks for helping with tips,corrections and such:
• ldolse
• kovidgoyal
• chaley
• dwanthny
• kacir
• Starson17
For more about regexps seeThePythonUserManual80.
1.9.5 Integrating the calibre content server into other servers
Here, we will show you how to integrate the calibre content server into another server. The most common reason for
this is to make use of SSL or more sophisticated authentication. There are two main techniques: Running the calibre
content server as a standalone process and using a reverse proxy to connect it with your main server or running the
content server in process in your main server with WSGI. The examples below are all for Apache 2.x on linux, but
should be easily adaptable to otherplatforms.
Contents
• Usingareverseproxy(page 166)
• Inprocess (page 167)
Note: This only applies to calibre releases >= 0.7.25
Using a reverse proxy
Areverse proxy is whenyour normal server accepts incomingrequests and passes them onto the calibre server. It then
reads the response fromthe calibre serverand forwards it to the client. This means thatyou can simply runthe calibre
server as normal without trying to integrate it closely with your main server, and you can take advantage of whatever
authentication systems your main server has in place. This is the simplest approach as it allows you to use the binary
calibre install withno externaldependencies/system integration requirements. Below, is an example ofhow to achieve
this with Apache as yourmain server, but it will work with any server that supports Reverse Proxies.
First start the calibre content server as shown below:
calibre-server --url-prefix /calibre --port 8080
80
https://docs.python.org/2/library/re.html
166
Chapter 1. Sections
Documents you may be interested
Documents you may be interested