From AniDB
Jump to navigation Jump to search

Read this first

Author: Arokh
Version: 1 (2009-09-21)

( Note this is the first release of this document so it may contain errors ) Use with AniAdd version 3

Before you go "uh I don't want to read that much -_-", this documentation isn't meant to be completely read but rather for one to jump to sections, one is interested in! And there will be a lot of examples I promise.

If you want a quick tour:
Goto the example section copy paste the code there into the codebox (client) and play with it a bit. If there is something you don't understand, come back here and goto the relevant section for explanations. After understanding it, rewind repeat.

If you find a bug or have a feature request, make a report on the bug tracker. (Please only make a bug report there if you are sure it is a bug. If you are unsure, post your problem and your code in the forum and I will take a quick look)

Syntactical definition

If you don't know how to read CFGs (Context Free Grammar), skip this section. It is for informational purposes only and not important to be able to use the TagSystem.

The following CFG evaluates to all possible syntactical correct "programs" (new & not yet public version):

ASSIGN -> (NAME ':=' )+ EXPRLST | NAME'(' [NAME (, NAME)* ] ')'
STRING -> ('"'<Any string except ">'"') | ("'" <Any string except '> "'")
NAME -> < Any String without the following characters := []'{}(),"%$? >
COMMENT -> #< Any string >
COMMENTBLOCK -> /*< Any string >*/


  • Any string within ' ' is a terminal, all capital words are non-terminals
  • To simplify the CFG, possible (redundant) spaces aren't represented as terminals. (Every unquoted space within the CFG represents any count of spaces)
  • * stands for any count of repetition of the preceding element (including 0 repetitions)
  • + same as * but at least once
  • Anything between [] is optional
  • Empty lines are allowed

Code structure


The Code
Every line you write is independent from the other lines, which means you don't have to worry about the other ones. (Not the complete truth, you'll see why soon)

Every line begins with the Assign construct, which consists of a variable name and an expression list. The expression list is evaluated and then assigned to the new created variable, with the name which was specified.

Those variables can be retrieved on the next lines. This way you can structure & simplify your code. (If you wanted you could write everything in a single line, but it would be very hard to read and error prone)

An expression list is simply a repetition of expressions.

Now the interesting part: There are 6 different expressions:

  1. Condition, it returns different strings based on the condition
  2. Choose: The first string which is not empty is returned
  3. Function: Returns a string based on the function called and parameters passed to it
  4. Variable: Retrieving the value of a variable
  5. String: Literal text
  6. Comment: Explanations for code sections

Those expressions can be nested, appended in any way you see fit.



An assignment, is the beginning of every line. It starts with the variable name followed by ':=' followed by an expression list. To assign the same value to more variables (on the same line) repetition is allowed. If the variable already exists it is overwritten (even predefined ones). To get a list of predefined variables refer to "Predefined variables" section.


 MyVarName := "My Expression list"
 AnotherVar := YetAnother := "Another Expression list"

It is also possible to create functions: To create a function instead of a variable, the variable name is followed by '()'. The parenthesis my contain parameters separated by a comma (same naming conventions as variable name applies). The parameters are only accessible within the function and don't change the 'main' variables in any way.


 MyFuncName() := "My Expression list"
 AnotherFunc(a, b) := %a% %b%

To use the new defined function see Function construct


Based on the result of a given condition (true or false), the true (evaluated) expression list is returned or the false one. The condition is enclosed within {} parenthesis and contains three parts: The condition (valA = valB), true and false expression list, divided by ? and :


 SomeVar := "Bla"
 MyVar := {%SomeVar%="A" ? "SomeVar is A" : "SomeVar is not A"}

If you want to test if something is empty, the second value and the equal sign can be omitted.


 SomeVar := "Bla"
 MyVar := {%SomeVar% ? "SomeVar is not empty" : "SomeVar is empty"}

Other Example:

 SomeVar := "4"
 MyVar := {%SomeVar%="1"?"One": {%SomeVar%="2"?"Two": {%SomeVar%="3"?"Three":"Zero or lower; Four or bigger"} } }


The first string which is not empty is returned. The choose construct is enclosed within [] parenthesis and contains expression lists divided by commas. If every expression list evaluates to an empty string, an empty string is returned.


 EnglishTitle := ""
 RomajiTitle := "TheRomajiTitle"
 KanjiTitle := "TheKanjiTitle"
 PreferedTitle := [%EnglishTitle%, %RomajiTitle%, %KanjiTitle%]


Returns a value based on the function called and parameters passed. To call a function, prefix the function name with $ and append its parameters with () parenthesis, separated by commas. To get a list of predefined functions refer to "Predefined functions" section.


 valA := "15"
 valB := "4"
 valMax := $max(%valA%, %valB%)

Not yet public Note: User created functions are only evaluated when called, so even if the code within it is wrong, an error is only thrown after it was called! Predefined functions cannot be overwritten. Any form of recursion is not allowed/possible


 Max4(a,b,c,d) := $max($max(a,b), $max(c,d))
 HighestNum := $Max4("0","3","6","20")


Returns the value of a previously defined variable or a predefined variable. To retrieve the variable simply enclose the variable name with %%. If the variable is undefined an empty string is returned.


 valA := "Hello"
 valB := "World"
 valC := %valA% " " %valB%


Returns the literal value enclosed within or "".


 quote1 := "Quote single quote ' "
 quote2 := 'Quote double quote " '
 quote3 := "'" '"'


Anything after a # is ignored and may be used to comment code sections.


 #Get prefered language
 PreferedTitle := [%E%, %R%, %K%] #English, Romaji, Kanji

Predefined Variables


  • ATr, ATe, ATk, ATs, ATo - Anime title, r: romaji, e: english, k: kanji, s: synonym, o: other
  • ETr, ETe, ETk - Episode title, languages as above
  • GTs, GTl - Group title, s: short, l: long

Anime information

  • EpHiNo - Highest (subbed) episode number
  • EpCount - Anime Episode count
  • AYearBegin, AYearEnd - The beginning & ending year of the anime
  • ACatList - The Categories associated with the anime.

Episode information

  • EpNo - File's Episode number

File information

  • Type - Anime type, Value: 'Movie', 'TV', 'OVA', 'Web'
  • Depr - File is deprecated if the value is '1'
  • Cen - File is censored if the value is '1'
  • Ver - File version
  • Source - Where the file came from (HDTV, DTV, WWW, etc)
  • Quality - How good the quality of the file is (Very Good, Good, Eye Cancer)
  • AniDBFN - Default AniDB filename
  • CurrentFN - Current Filename
  • FCrc - The file's crc
  • FVideoRes - Video Resolution (e.g. 1920x1080)
  • FALng - List of available audio languages (japanese, english'japanese'german)
  • FSLng - List of available subtitle languages (japanese, english'japanese'german)
  • FACodec - Codecs used for the Audiostreams
  • FVCodec - Codecs used for the Videostreams
  • Watched - File is watched if the value is '1' otherwise unwatched and ""

More predefined variables will be added on request.

Predefined Functions

  • NUM $min/max(NUM, NUM) - Both NUMs need to be numerical string. Returns the smaller/greater NUM
  • NUM $len(STR) - Returns a numerical string represinting the character count of STR
  • STR $pad(STR, NUM, CHAR) - STR: String to be padded; NUM min string length; CHAR: The character used to pad the string
  • STR $repl(SRC, REGEX, REPL) - SRC: Source; REGEX: Regex used to match; REPL: replaces every match with REPL
  • STR $match(STR, REGEX) STR: Source; REGEX: Match; Returns "1" if STR has a match for REGEX, otherwise unwatched and ""
  • STR $uc/lc(STR) Convert string to uppercase/lowercase
  • NUM $add/sub/mul/div(NUM, NUM) Add/Substract/Multiply/Divide two numerical strings
  • STR $substr(STR, NUM[, NUM]) Returns the substring beginning from seconds param index to end or optionally to the third param index
  • NUM $[l]indexof(STR, STR) Returns the first/last index of the substring specified in the second param in the first param string, -1 if there are no occurrences.

More predefined functions will be added on request.

How AniAdd uses the TagSystem

After AniAdd has finished sending commands for a file and recieved replies for them, it checks if you have the TagSystem enabled.

If it is, it runs the code once and retrieves the variables "PathName" & "FileName" as necessary.

Note: While every invalid character for the filename is removed prior renaming, for the pathname they are not removed! To remove them manually, refer to the examples.


Select your prefered language

 AT := [%ATe%, %ATr%, %ATk%]

This saves your prefered Animetitle language into the variable AT. In this order: English, Romaji, Kanji. If the English title is not available, the romaji title is selected, if that one is also not avaiable the kanji title will be selected. Look up: The Assign, Choose construct & Predefined variables

Other Examples:

 ET := [%ETe%, %ETr%, %ETk%] #Episode title
 GT := [%GTs%, %GTl%] #Group title

Episodenumber Padding

 EpNoPad := $pad(%EpNo%, $max($len(%EpHiNo%), $len(%EpCount%)), "0")

This looks complicated but it is quite logical: What do we need to pad the Episodenumber? Right, the string itself, the target string length and the pad character. The padding is done by the pad function: $pad(%EpNo%, <stringlength>, "0") Here the %EpNo% needs to be padded, <stringlength> explained below, and we want to use the 0 as padding char.

In our example we used $max($len(%EpHiNo%), $len(%EpCount%)) for <stringlength> The max function takes two numerical parameters, the greater one will be returned. Since calculating the maximum of a string doesn't make much sense, we need to get its length first, which is exactly what the len function does.

Why not write write EpNoPad := $pad(%EpNo%, $len(%EpCount%), "0") and be done with it? There are a lot of ongoing anime series where the EpCount variable is not yet available. In that case EpCount would contain the value "0" (Think of Gintama, Conan etc.) and padding would never occur (well it would after its episode count is set). Now EpHiNo comes to the rescue: It contains the highest released episode number. Now we only need to determine which one is longer, and pass it to the pad function, what is exactly what we have done in the example.

Different formats for Movies & TV Series

 TVFormat   := %ATe% " " %EpNo% "v"%Ver% " - " %ETe% " [" %GTs% "]"
 MovieFormat:= %ATe% " - " %ETe% " [" %GTs% "][v"%Ver%"]"
 Format := {%Type% = "Movie"? %MovieFormat% : %TVFormat%}

Simply create a variable for each style and after them, create a variable where you choose the desired one based on the Type variable.

Display version & other information only as needed

There are some you only want to be displayed if it different from the standard value: There are the Ver (Version), Cen (Censored) & Depr (Deprecated) variables. The version variable is most of the time "1" and the other ones ""

 Ver := {%Ver%="1" ? "" : "v"%Ver%}
 Cen := {%Cen% ? "[Cen]" : ""}
 Depr := {%Depr% ? "[Depr]" : ""}

Here the predefined variables are overwritten with formatted ones: Ver is "" when it is version 1 otherwise "v"%Ver%
Cen is "" if it is not censored otherwise "[Cen]"
Depr is "" if it is not deprecated otherwise "[Depr]"

Replacing invalid characters

When you want to set the path via the TagSystem one often wants to include the anime title. The problem with this is that it may contain illegal characters and thus the renaming fails. To prevent that you can replace those characters.

 PathName := "C:\My\Path\Name\" $repl(%ATe%,'[\\":/*|<>?]',"")

Look up the repl function in the Predefined Functions section. If you don't feel like learning a bit regex (the seconds parameter), every character within the [] brackets are replaced by the third parameter.

Piecing everything together

GT:="[" [%GTs%,%GTl%] "]"



Movie := %AT%" - "%ET%" "%GT% %Depr% %Cen% %Src% %Ver%
Other := %AT%" "%EpNoPad% %Ver% " - "%ET%" "%GT% %Depr% %Cen% %Src%

FileName:= {%Type% = "Movie"? %Movie% : %Other%}
PathName:="E:\My\Path\Name\" $repl(%AT%,'[\\":/*|<>?]',"")