Grammar

From Avisynth wiki
(Difference between revisions)
Jump to: navigation, search
(formatting, links, phrasing)
m (formatting, links, phrasing continued)
Line 8: Line 8:
 
(Two higher-level constructs also exist - the [[User_defined_script_functions|function declaration]] and the [[Control_structures#The_try..catch_statement|try..catch statement]].)
 
(Two higher-level constructs also exist - the [[User_defined_script_functions|function declaration]] and the [[Control_structures#The_try..catch_statement|try..catch statement]].)
  
*In the first case, {{FuncArg|expression}} is evaluated and the result is assigned to {{FuncArg|variable_name}}.  
+
*In the first form, {{FuncArg|expression}} is evaluated and the result is assigned to {{FuncArg|variable_name}}.  
*In the second case, {{FuncArg|expression}} is evaluated and the result, if a ''clip'', is assigned to the special variable '''Last'''.  
+
*In the second form, {{FuncArg|expression}} is evaluated and the result, if a ''clip'', is assigned to the special variable '''Last'''.  
*In the third case, {{FuncArg|expression}} is evaluated and is used as the '''return value''' of the active ''script block'' (function), or the entire script.  
+
*In the third form, {{FuncArg|expression}} is evaluated and is used as the '''return value''' of the active ''script block'' (function), or the entire script.  
 
As a shorthand, if '''return''' is not present in the final executable statement of a script (or script block), it is ''implied'' – the statement is treated as if '''return''' was present.
 
As a shorthand, if '''return''' is not present in the final executable statement of a script (or script block), it is ''implied'' – the statement is treated as if '''return''' was present.
  
Line 16: Line 16:
  
 
If the return value of the script is a ''clip'', which is the normal case, it can be "played" as a video by a [[Frameserver|frameserving]] client.
 
If the return value of the script is a ''clip'', which is the normal case, it can be "played" as a video by a [[Frameserver|frameserving]] client.
 +
  
 
An '''Expression''' can have one of these forms:  
 
An '''Expression''' can have one of these forms:  
Line 26: Line 27:
 
# ''boolean_expression'' <b>?</b> ''expression'' <b>:</b> ''expression''
 
# ''boolean_expression'' <b>?</b> ''expression'' <b>:</b> ''expression''
  
*In the first case, the value of the expression is the value of the {{FuncArg|constant}}. <br>(syntactically, a ''constant'' is indistinguishable from a ''variable''; by convention, you set the value of a ''constant'' once and once only)
+
*In the first form, the value of the expression is the value of the {{FuncArg|constant}}. <br>(syntactically, a ''constant'' is indistinguishable from a ''variable''; by convention, you set the value of a ''constant'' once and once only)
*In the second case, the value equals the value of the specified [[Script_variables|{{FuncArg|variable}}]] or [[Clip_properties|{{FuncArg|clip property}}]] (possibly [[Internal_functions/Defined#Defined|undefined]]).   
+
*In the second form, the value equals the value of the specified [[Script_variables|{{FuncArg|variable}}]] or [[Clip_properties|{{FuncArg|clip property}}]] (possibly [[Internal_functions/Defined#Defined|undefined]]).   
*In the third case, the value is the return value of a {{FuncArg|function}} (see below).   
+
*In the third form, the value is the return value of a {{FuncArg|function}} (see below).   
*The fourth case is an alternate syntax called "''OOP notation''" in AviSynth:
+
*The fourth form is an alternate syntax called "''OOP notation''" in AviSynth:
 
::''expression'' <b>.</b> ''function_name'' '''(''' ''argument_list'' ''')''' is equivalent to
 
::''expression'' <b>.</b> ''function_name'' '''(''' ''argument_list'' ''')''' is equivalent to
 
::''function_name'' '''(''' ''expression'' ''',''' ''argument_list'' ''')'''   
 
::''function_name'' '''(''' ''expression'' ''',''' ''argument_list'' ''')'''   
*The fifth case contains an arithmetic or logical {{FuncArg|operator}}; AviSynth operators are discussed [[Operators|here]]; for example,  
+
*The fifth form has an {{FuncArg|operator}}; AviSynth operators are discussed [[Operators|here]]; for example,  
 
:*'''strings''' can be ''concatenated'' (joined together) with '+', and ''compared'' with relational operators.
 
:*'''strings''' can be ''concatenated'' (joined together) with '+', and ''compared'' with relational operators.
 
:*'''video clips''' can be ''spliced'' (joined together) with '+':
 
:*'''video clips''' can be ''spliced'' (joined together) with '+':
 
::''a'' '''+''' ''b'' is equivalent to [[Splice|UnalignedSplice]](''a'', ''b'')
 
::''a'' '''+''' ''b'' is equivalent to [[Splice|UnalignedSplice]](''a'', ''b'')
 
::''a'' '''++''' ''b'' is equivalent to [[Splice|AlignedSplice]](''a'', ''b'').  
 
::''a'' '''++''' ''b'' is equivalent to [[Splice|AlignedSplice]](''a'', ''b'').  
*The sixth case supports conditional execution with the {{FuncArg|ternary operator}}.   
+
*The sixth form supports conditional execution with the {{FuncArg|ternary operator}}.   
  
 
Avisynth '''ignores case''': ''avisource'' or ''aViSouRCe'' is just as good as ''AVISource''.
 
Avisynth '''ignores case''': ''avisource'' or ''aViSouRCe'' is just as good as ''AVISource''.
 +
  
 
==== Functions, Filters and Arguments ====
 
==== Functions, Filters and Arguments ====
Line 51: Line 53:
  
 
To see the usage syntax of the function call for each built-in filter, see the [[Internal_filters|internal filters]] page. There are also many useful non-clip-returning [[Internal_functions|internal functions]].
 
To see the usage syntax of the function call for each built-in filter, see the [[Internal_filters|internal filters]] page. There are also many useful non-clip-returning [[Internal_functions|internal functions]].
 +
  
 
'''argument_list''' (see '''Expression''', forms 3 and 4) is a list of function arguments separated by commas. The list can be empty. Each argument must be an expression whose ''type'' matches the one expected by the function. If the function expects a video clip as its first argument, and that argument is not supplied, then the clip in the special variable '''Last''' will be used.  
 
'''argument_list''' (see '''Expression''', forms 3 and 4) is a list of function arguments separated by commas. The list can be empty. Each argument must be an expression whose ''type'' matches the one expected by the function. If the function expects a video clip as its first argument, and that argument is not supplied, then the clip in the special variable '''Last''' will be used.  
Line 58: Line 61:
 
Any ''variable_name'' which has never been assigned a value is an '''undefined''' variable. Undefined variables may be passed to functions, which in turn can determine their status with the [[Internal_functions/Defined#Defined|Defined]] function.
 
Any ''variable_name'' which has never been assigned a value is an '''undefined''' variable. Undefined variables may be passed to functions, which in turn can determine their status with the [[Internal_functions/Defined#Defined|Defined]] function.
  
Functions can take '''named arguments'''. Named arguments can be specified in any order, and the filter will choose default values for any that you leave off (they will be ''undefined'' within the function body). This makes certain filters much easier to use. For example, you can now write <tt>[[Subtitle]]("Hello, World!", text_color=$00FF00, x=100, y=200)</tt> instead of <tt>[[Subtitle]]("Hello, World!", 100, 200, 0, 999999, "Arial", 24, $00FF00)</tt>.
 
  
By the way, '''[[Colors]]''' can be specified in hexadecimal as in the example above, or in decimal. They may be specified as an [[RGB]] value, even if the clip itself is [[YUV]]. They may also be specified by name using one of the [[Preset_colors]].
+
Functions can take '''named arguments'''. Named arguments can be specified in any order, and the filter will choose default values for any that you leave off (they will be ''undefined'' within the function body). This makes certain filters much easier to use. For example, you can now write
 +
<div {{BoxWidthIndent|48|1}} >
 +
[[Subtitle]]("Hello, World!", text_color=$00FF00, x=100, y=200)
 +
</div>
 +
instead of
 +
<div {{BoxWidthIndent|48|1}} >
 +
Subtitle("Hello, World!", 100, 200, 0, 999999, "Arial", 24, $00FF00)
 +
</div>
 +
 
 +
By the way, '''[[Colors]]''' can be specified in hexadecimal as in the example above, or in decimal. They may be specified as an [[RGB]] value, even if the clip itself is [[YUV]]. They may also be specified by name using one of the [[Preset_colors|preset colors]].
 +
 
  
 
If no arguments are passed to the function, you can omit the '''parentheses''':
 
If no arguments are passed to the function, you can omit the '''parentheses''':
Line 70: Line 82:
 
  [[AviSource]]("my.avi").[[AssumeFieldBased]].[[AssumeTFF]].[[SeparateFields]]
 
  [[AviSource]]("my.avi").[[AssumeFieldBased]].[[AssumeTFF]].[[SeparateFields]]
 
</div>
 
</div>
 +
  
 
==== Comments ====
 
==== Comments ====
Line 94: Line 107:
 
  */
 
  */
 
</div>
 
</div>
 +
  
 
Avisynth ignores anything from the <tt><nowiki>__END__</nowiki></tt> keyword (with double underscores) to the end of the script file.   
 
Avisynth ignores anything from the <tt><nowiki>__END__</nowiki></tt> keyword (with double underscores) to the end of the script file.   
Line 102: Line 116:
 
  Result is not reduced and we can write any text here
 
  Result is not reduced and we can write any text here
 
</div>
 
</div>
 +
  
 
==== Line breaks and continuation ====
 
==== Line breaks and continuation ====
'''Multiple statements on a single line''' can be made with [[Wikipedia:Object-oriented_programming|''OOP''-style]] (dot) notation, or by embedding filters as parameters of another function:
+
'''Multiple statements on a single line''' can be made with OOP-style (dot) notation, or by embedding filters as arguments to another function:
 
<div {{BoxWidthIndent|48|1}} >
 
<div {{BoxWidthIndent|48|1}} >
 
  [[AviSource]]("c:\video.avi").[[Trim]](0, 499)
 
  [[AviSource]]("c:\video.avi").[[Trim]](0, 499)
Line 111: Line 126:
 
</div>
 
</div>
  
The [[Wikipedia:Parsing|parser]] recognises it has reached the end of a ''statement'' when the next symbol is not a valid continuation of what it already has. Although it is conventional to use '''newlines''' to separate statements (and good practice for readability), the syntax is such that it is only strictly necessary if the following statement starts with a unary minus (or plus) operator. See [http://forum.doom9.org/showthread.php?p=1621382#post1621382 Multiple statements on a single line] @ doom9.org
+
The [[Wikipedia:Parsing|parser]] recognises it has reached the end of a ''statement'' when the next symbol is not a valid continuation of what it parsed so far; the next symbol it encounters begins a new statement. Although it is conventional to use '''newlines''' to separate statements (and good practice for readability), the grammar is such that it is only strictly necessary if the following statement starts with a unary minus (or plus) operator. See [http://forum.doom9.org/showthread.php?p=1621382#post1621382 Multiple statements on a single line] @ doom9.org
  
 
For example:
 
For example:
Line 117: Line 132:
 
  x = 1  y = 2  z = 3  
 
  x = 1  y = 2  z = 3  
 
</div>
 
</div>
 +
  
 
Statements can be '''split across multiple lines''' by placing a backslash ('<tt>\</tt>') either as the last non-space character of the line being extended, or as the first non-space character on the next line.
 
Statements can be '''split across multiple lines''' by placing a backslash ('<tt>\</tt>') either as the last non-space character of the line being extended, or as the first non-space character on the next line.
Line 131: Line 147:
 
</div>
 
</div>
  
When splitting across multiple lines you may place comments ''only at the end of the last line''. Mixing comments with backslashes at an intermediate line of the line-split will either produce an error message or result at hard to trace bugs.
 
  
Example of a not-signaled bug by improper mixing of comments and line separation:
+
When splitting across multiple lines you may place '#'-style '''comments''' ''only at the end of the last line''. Mixing comments with backslashes at an intermediate line of the line-split will either produce an error message or result in hard-to-trace bugs.
 +
 
 +
Example of a silent bug (no error is raised) by improper mixing of comments and line separation:
 
<div {{BoxWidthIndent|48|1}} >
 
<div {{BoxWidthIndent|48|1}} >
 
  [[ColorBars]]
 
  [[ColorBars]]
Line 142: Line 159:
  
 
The above example does not return frames [0..9, 20..29] as intended because the '<tt>\</tt>' is masked by the '<tt>#</tt>' character before it; thus the line continuation never happens.
 
The above example does not return frames [0..9, 20..29] as intended because the '<tt>\</tt>' is masked by the '<tt>#</tt>' character before it; thus the line continuation never happens.
 +
 +
However you may use the '<tt>[*</tt> ... <tt>*]</tt>' style nested block comment in this situation:
 +
<div {{BoxWidthIndent|48|1}} >
 +
[[ColorBars]]
 +
[[ShowFrameNumber]]
 +
Trim(0,9) '''[*''' select some frames '''*] \'''
 +
  + Trim(20,29)
 +
</div>
  
 
----
 
----

Revision as of 18:48, 24 January 2016

Contents

 [hide

Statements, Expressions, Types and Operators

All basic AviSynth scripting statements have one of these forms:

  1. variable_name = expression
  2. expression
  3. return expression

(Two higher-level constructs also exist - the function declaration and the try..catch statement.)

  • In the first form, expression is evaluated and the result is assigned to variable_name.
  • In the second form, expression is evaluated and the result, if a clip, is assigned to the special variable Last.
  • In the third form, expression is evaluated and is used as the return value of the active script block (function), or the entire script.

As a shorthand, if return is not present in the final executable statement of a script (or script block), it is implied – the statement is treated as if return was present.

Most of the time the result of an expression will be a video clip; however an expression's result can be any Avisynth Type (clip, int, float, bool, string) – these are sometimes called utility functions. A list of built-in utility functions can be found here.

If the return value of the script is a clip, which is the normal case, it can be "played" as a video by a frameserving client.


An Expression can have one of these forms:

  1. numeric_constant or string_constant or boolean_constant
  2. variable_name or clip_property_name
  3. function_name ( argument_list )
  4. expression . function_name ( argument_list )
  5. expression operator expression
  6. boolean_expression ? expression : expression
  • In the first form, the value of the expression is the value of the constant.
    (syntactically, a constant is indistinguishable from a variable; by convention, you set the value of a constant once and once only)
  • In the second form, the value equals the value of the specified variable or clip property (possibly undefined).
  • In the third form, the value is the return value of a function (see below).
  • The fourth form is an alternate syntax called "OOP notation" in AviSynth:
expression . function_name ( argument_list ) is equivalent to
function_name ( expression , argument_list )
  • The fifth form has an operator; AviSynth operators are discussed here; for example,
  • strings can be concatenated (joined together) with '+', and compared with relational operators.
  • video clips can be spliced (joined together) with '+':
a + b is equivalent to UnalignedSplice(a, b)
a ++ b is equivalent to AlignedSplice(a, b).
  • The sixth form supports conditional execution with the ternary operator.

Avisynth ignores case: avisource or aViSouRCe is just as good as AVISource.


Functions, Filters and Arguments

Functions in AviSynth are usually also Filters (functions that return a clip). Although a function can return any type it chooses, functions which do not return a clip are only used for intermediate processing. The script should always return a clip as its final value. After all, AviSynth is a video processing application.

Functions can take up to sixty arguments (hope that's enough), and the return value can be of any Avisynth type (clip, int, float, bool, string).

The term parameter is often used interchangeably with the term argument; while this usage is not strictly correct, it happens—even on this Wiki.

Functions always produce a new value and never modify an existing one. What that means is that all arguments to a function are passed by value and not by reference; in order to alter a variable's value in AviSynth, you must assign it a new value.

To see the usage syntax of the function call for each built-in filter, see the internal filters page. There are also many useful non-clip-returning internal functions.


argument_list (see Expression, forms 3 and 4) is a list of function arguments separated by commas. The list can be empty. Each argument must be an expression whose type matches the one expected by the function. If the function expects a video clip as its first argument, and that argument is not supplied, then the clip in the special variable Last will be used.

Function definitions may specify an additional argument "type": var, which accepts any of the AviSynth types.

Any variable_name which has never been assigned a value is an undefined variable. Undefined variables may be passed to functions, which in turn can determine their status with the Defined function.


Functions can take named arguments. Named arguments can be specified in any order, and the filter will choose default values for any that you leave off (they will be undefined within the function body). This makes certain filters much easier to use. For example, you can now write

Subtitle("Hello, World!", text_color=$00FF00, x=100, y=200)

instead of

Subtitle("Hello, World!", 100, 200, 0, 999999, "Arial", 24, $00FF00)

By the way, Colors can be specified in hexadecimal as in the example above, or in decimal. They may be specified as an RGB value, even if the clip itself is YUV. They may also be specified by name using one of the preset colors.


If no arguments are passed to the function, you can omit the parentheses:

versus


Comments

Avisynth ignores anything from a '#' character to the end of that line. This can be used to add comments to a script.

# this is a comment

It is possible to add block and nested block comments in the following way:

/* 
this is a
block comment
*/
/* this is a
    block comment
  [* this is
     a nested comment
     [* and another one *]
  *] 
*/


Avisynth ignores anything from the __END__ keyword (with double underscores) to the end of the script file.

Version()
__END__
ReduceBy2()
Result is not reduced and we can write any text here


Line breaks and continuation

Multiple statements on a single line can be made with OOP-style (dot) notation, or by embedding filters as arguments to another function:

AviSource("c:\video.avi").Trim(0, 499)
-or-
AudioDub(AviSource("c:\video.avi"), WavSource("c:\audio.wav"))

The parser recognises it has reached the end of a statement when the next symbol is not a valid continuation of what it parsed so far; the next symbol it encounters begins a new statement. Although it is conventional to use newlines to separate statements (and good practice for readability), the grammar is such that it is only strictly necessary if the following statement starts with a unary minus (or plus) operator. See Multiple statements on a single line @ doom9.org

For example:

x = 1  y = 2  z = 3 


Statements can be split across multiple lines by placing a backslash ('\') either as the last non-space character of the line being extended, or as the first non-space character on the next line.

Line splitting examples (both valid and equal):

Subtitle("Hello, World!", 100, 200, 0, \
  999999, "Arial", 24, $00FF00)

-or-

Subtitle("Hello, World!", 100, 200, 0,
  \ 999999, "Arial", 24, $00FF00)


When splitting across multiple lines you may place '#'-style comments only at the end of the last line. Mixing comments with backslashes at an intermediate line of the line-split will either produce an error message or result in hard-to-trace bugs.

Example of a silent bug (no error is raised) by improper mixing of comments and line separation:

ColorBars
ShowFrameNumber
Trim(0,9) # select some frames  \
  + Trim(20,29)

The above example does not return frames [0..9, 20..29] as intended because the '\' is masked by the '#' character before it; thus the line continuation never happens.

However you may use the '[* ... *]' style nested block comment in this situation:

ColorBars
ShowFrameNumber
Trim(0,9) [* select some frames *] \
  + Trim(20,29)

Back to AviSynth_Syntax.

Personal tools