Skip to content

InExcludeMetadataFeature

Jim Miller edited this page Sep 9, 2023 · 5 revisions
## Include/Exclude metadata
##
## You can use the include/exclude metadata features to either limit
## the values of particular metadata lists to specific values or to
## exclude specific values.  Further, you can conditionally apply each
## line depending on other metadata, use exact strings or regular
## expressions(regex) to match values, and negate matches.
##
## The settings are:
## include_metadata_pre
## exclude_metadata_pre
## include_metadata_post
## exclude_metadata_post
##
## The form of each line is:
## metakey[,metakey]==exactvalue
## metakey[,metakey]=~regex
## metakey[,metakey]==exactvalue&&conditionalkey==exactcondvalue
## metakey[,metakey]=~regex&&conditionalkey==exactcondvalue
## metakey[,metakey]==exactvalue&&conditionalkey=~condregex

## When set true, conditionals for both replace_metadata and
## Include/Exclude metadata will check against each list value rather
## than the entire list as a string which was the case prior to this
## change (~Dec 2018).  replace_metadata conditionals (after &&) can
## also now use ==, !=, =~ and !~.  => is the same as =~ .)
## Set false to get the old behavior.  You can also compare the list
## as string by using <entry>_LIST, such as category_LIST
conditionals_use_lists:true

Well, I set out to make a simple way to include or exclude metadata values. But like most of my projects, it quickly spiraled into something considerably more complex than I'd first intended.

Let's start with some simple cases first.

'Include' in this case really means 'include ONLY these.' If a metadata type has lines in include, only those values will be kept, all others are discarded.

(Note that the separator is ==, which is different than in replace_metadata.)

## in stories from site dramione.org, only use these 4 characters, all
## others will be omitted.  Because only characters are listed, only
## characters will be effected.
[dramione.org]
include_metadata_pre:
 characters==Draco Malfoy
 characters==Hermione Granger
 characters==Harry Potter
 characters==Ron Weasley

## in stories from site www.fimfiction.net, only keep these 2
## characters, all others will be omitted.  And only Comedy and
## Adventure genres will be used--all other genres will be omitted.
## All other metadata will be as usual.
[www.fimfiction.net]
include_metadata_pre:
 characters==Twilight Sparkle
 characters==Rainbow Dash
 genre==Comedy
 genre==Adventure

If, on the other hand, you want to keep most values, and want to exclude only certain values you use exclude instead. (The =~ will be explained next.)

## in stories from site thequidditchpitch.org, exclude warnings 'Minor
## Fluff', AU and anything with 'Contains Spoiler' in it; and the genre
## PWP.  All other values will be kept.
[thequidditchpitch.org]
exclude_metadata_pre:
 warnings==Minor Fluff
 warnings==Alternate Universe
 warnings=~Contains Spoiler
 genre==PWP

In both include and exclude, you can use regular expressions(regex) instead of simple strings by using =~ for the separator.

## in stories from site buffynfaith.net, only include ships with Buffy
## in them, even if spelled with a lower case 'b'.
[buffynfaith.net]
include_metadata_pre:
 ships=~[Bb]uffy

## in stories from site www.fimfiction.net, only use these 2
## characters, all others will be omitted.  All other metadata will be
## as usual.
[www.fimfiction.net]
include_metadata_pre:
 characters=~^(Twilight Sparkle|Rainbow Dash)$

## exclude the Mane Six or Main 6 or variation.
exclude_metadata_pre:
 characters=~(Mane|Main) (Six|6)

But what happens when you're using a site that has more than one category of story and you only want to affect one fandom at a time? You can use conditionals similar to replace_metadata. And in include/exclude, conditionals can be either exact string(==) or regex(=~) too.

While an include line for say characters without a conditional means only characters explicitly matched by include lines will be kept, an include line with a conditional only effects stories that meet the conditional.

## in stories from site archiveofourown.org, when category contains
## 'The Hobbit', only include these three characters.  All other
## stories will continue to have full characters.
[archiveofourown.org]
include_metadata_pre:
 characters==Bilbo&&category==The Hobbit
 characters==Samwise&&category==The Hobbit
 characters==Gandalf&&category==The Hobbit

## still on archiveofourown.org, exclude any character with Bucky in
## it, but only for Marvel, Captain America & Avengers
exclude_metadata_pre:
 characters=~Bucky&&category=~(Marvel|Captain America|Avengers)

As of 2019Jan, conditional checks are done against each item in metadata lists. Before that, they checked the string made from the list. So in the example above, &&category==The Hobbit will now match a story with category = The Hobbit, The Lord of the Rings whereas before it would not. If you want to be able to still use the whole string method, you can use <entry>_LIST, eg, category_LIST to get The Hobbit, The Lord of the Rings as a single string in the example above.

You can use conditionals_use_lists:false to get the old behavior.

Note that include is applied first, then exclude.

## in stories from site buffynfaith.net, only include ships with Buffy
## in them, even if spelled with a lower case 'b'.
[buffynfaith.net]
include_metadata_pre:
 ships=~[Bb]uffy

## But exclude any Buffy/Dawn.
exclude_metadata_pre:
 ships=~[Bb]uffy/Dawn

You may have noticed that all the examples so far ended in _pre. That's because all of these were applied before replace_metadata is applied. You can also use include_metadata_post and exclude_metadata_post to filter after replace_metadata is applied.

[default]
replace_metadata:
 ... tons of code to tweak metadata to your exacting standards
 ... and normalize all the character names juuuust right

## Now make sure that only characters that start with your corrected
## formatting are included.
include_metadata_post:
 characters=~^(Books|Anime|Movies)\.

Now one more twist. In addition to == and =~ to match exact strings and regex, you can also use != and !~ to negate the match. Much of what you can do with negated matches can be done by include/exclude, but some things can't. Don't go crazy with negated matches--Figuring out which to use when and why can be quite complicated.

[www.fimfiction.net]
## These two on their own are functionally equivalent: exclude
## 'Twilight Sparkle' in characters
include_metadata_pre:
 characters!=Twilight Sparkle

exclude_metadata_pre:
 characters==Twilight Sparkle

## But these two are *not*:

## excludes these two as expected.
exclude_metadata_pre:
 characters==Twilight Sparkle
 characters==Rainbow Dash

## includes all characters because Rainbow Dash matches != Twilight
## Sparkle and Twilight Sparkle matches != Rainbow Dash.  So both
## match an include line and are kept.
include_metadata_pre:
 characters!=Twilight Sparkle
 characters!=Rainbow Dash

Realistically, I expect negated matches to be more useful in the conditionals.

[fanfiction.net]
## Exclude Harry Porter, Harry Pearson, etc from other fandoms.
exclude_metadata_pre:
 characters==Harry P.&&category!=Harry Potter

And finally, if you need a trailing space in a string or regex, you can use \s and FanFicFare will convert it to a space.

List Entries Note

The way it works is that include/exclude_metadata_pre then replace_metadata then include/exclude_metadata_post are applied to each metadata entry as it's used, not all metadata as a whole.

So for characters, for example, write each line to match one character entry, not the whole list. "Harry P." not "Harry P., Sirius B."

Conditionals Note:

When using conditional clauses (&&entry==value) with replace_metadata (see ReplaceMetadata) or include/exclude_metadata_pre/post be aware that include/exclude_metadata_pre, replace_metadata, and include/exclude_metadata_post will all already be applied to the metadata entries you are using in the conditional.

If you want to use a conditional with the 'raw' value of an entry, for conditionals, you can make a copy without replacements. Example for rating:

add_to_extra_valid_entries:rating_raw
include_in_rating_raw:rating.NOREPL