Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avisynth lang definition. #3071

Merged
merged 14 commits into from Sep 15, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion components.js

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions components.json
Expand Up @@ -160,6 +160,11 @@
"title": "AutoIt",
"owner": "Golmote"
},
"avisynth": {
"title": "AviSynth",
"alias": "avs",
"owner": "Zinfidel"
},
"avro-idl": {
"title":"Avro IDL",
"alias": "avdl",
Expand Down
169 changes: 169 additions & 0 deletions components/prism-avisynth.js
@@ -0,0 +1,169 @@
// http://avisynth.nl/index.php/The_full_AviSynth_grammar
(function (Prism) {

function toAlternation(words) {
return words.reduce(function (acc, cur) {
return cat(acc, cur.trim().replace(/ /g, '|'));
}, '');
}

function cat(left, right) {
return left + (left == '' ? '' : '|') + right;
}

function replace(pattern, replacements) {
return pattern.replace(/<<(\d+)>>/g, function (m, index) {
return replacements[+index];
});
}

function re(pattern, replacements, flags) {
return RegExp(replace(pattern, replacements), flags || '');
}

var wordLists = {
types: 'clip int float string bool val',
keywords: 'function global return try catch if else while for __END__', // includes avs+ native gscript constructs
predefined: 'DEFAULT_MT_MODE (?:SCRIPT|MAINSCRIPT|PROGRAM)DIR (?:USER|MACHINE)_(?:PLUS|CLASSIC)_PLUGINS',
Zinfidel marked this conversation as resolved.
Show resolved Hide resolved
constants: 'MT_(?:NICE_FILTER|MULTI_INSTANCE|SERIALIZED|SPECIAL_MT)',
internals: {
bools: 'is(?:bool|clip|float|int|string) defined (?:var|(?:internal)?function)?exists?',
control: 'apply assert default eval import select nop undefined',
global: 'set(?:memorymax|cachemode|maxcpu|workingdir|planarlegacyalignment) opt_(?:allowfloataudio|usewaveextensible|dwchannelmask|avipadscanlines|vdubplanarhack|enable_(?:v210|y3_10_10|y3_10_16|b64a|planartopackedrgb))',
conv: 'hex(?:value)? value',
numeric: 'max min muldiv floor ceil round fmod pi exp log(?:10)? pow sqrt abs sign frac rand spline continued(?:numerator|denominator)?',
trig: 'a?sinh? a?cosh? a?tan[2h]?',
bit: '(?:bit(?:and|not|x?or|[lr]?shift[aslu]?|sh[lr]|sa[lr]|[lr]rotatel?|ro[rl]|te?st|set(?:count)?|cl(?:ea)?r|ch(?:an)?ge?))',
runtime: 'average(?:luma|chroma[uv]|[bgr]) (?:luma|chroma[uv]|rgb|[rgb]|[yuv](?=difference(?:fromprevious|tonext)))difference(?:fromprevious|tonext)? [yuvrgb]plane(?:median|min|max|minmaxdifference)',
script: 'script(?:name(?:utf8)?|file(?:utf8)?|dir(?:utf8)?) setlogparams logmsg getprocessinfo',
string: '[lu]case str(?:toutf8|fromutf8|len|cmpi?) (?:rev|left|right|mid|find|replace|fill)str format trim(?:left|right|all) chr ord time',
version: 'version(?:number|string) isversionorgreater',
helper: 'buildpixeltype colorspacenametopixeltype',
avsplus: 'setfiltermtmode prefetch addautoloaddir on(?:cpu|cuda)'
},
properties: {
content: 'has(?:audio|video)',
resolution: 'width height',
framerate: 'frame(?:count|rate) framerate(?:numerator|denominator)',
interlacing: 'is(?:field|frame)based getparity',
colorformat: 'pixeltype is(?:planar(?:rgba?)?|interleaved|rgb(?:24|32|48|64)?|y(?:8|u(?:y2|va?))?|yv(?:12|16|24|411)|420|422|444|packedrgb) hasalpha componentsize numcomponents bitspercomponent',
audio: 'audio(?:rate|duration|length(?:[fs]|lo|hi)?|channels|bits) isaudio(?:float|int)'
},
filters: {
source: 'avi(?:file)?source opendmlsource directshowsource image(?:reader|source|sourceanim) segmented(?:avisource|directshowsource) wavsource',
color: 'coloryuv convertto(?:RGB(?:24|32|48|64)|(?:planar)?RGBA?|Y8?|YV(?:12|16|24|411)|YUVA?(?:444|422|420|411)|YUY2) convertbacktoyuy2 fixluminance gr[ae]yscale invert levels limiter mergea?rgb merge(?:luma|chroma) rgbadjust show(?:red|green|blue|alpha) swapuv tweak [uv]toy8? ytouv',
overlay: '(?:colorkey|reset)mask mask(?:hs)? layer merge overlay subtract',
geometry: 'addborders crop(?:bottom)? flip(?:horizontal|vertical) letterbox (?:horizontal|vertical)?reduceby2 (?:bicubic|bilinear|blackman|gauss|lanczos|lanczos4|point|sinc|spline(?:16|36|64))resize skewrows turn(?:left|right|180)',
pixel: 'blur sharpen generalconvolution (?:spatial|temporal)soften fixbrokenchromaupsampling',
timeline: 'trim (?:un)?alignedsplice (?:assume|assumescaled|change|convert)FPS (?:delete|duplicate)frame dissolve fade(?:in|out|io)[02]? freezeframe interleave loop reverse select(?:even|odd|(?:range)?every)',
interlace: 'assume(?:frame|field)based assume[bt]ff bob complementparity doubleweave peculiarblend pulldown separate(?:columns|rows|fields) swapfields weave(?:columns|rows)?',
audio: 'amplify(?:db)? assumesamplerate audiodub(?:ex)? audiotrim convertaudioto(?:(?:8|16|24|32)bit|float) converttomono delayaudio ensurevbrmp3sync get(?:left|right)?channel kill(?:audio|video) mergechannels mixaudio monotostereo normalize resampleaudio supereq ssrc timestretch',
conditional: 'conditional(?:filter|select|reader) frameevaluate scriptclip writefile(?:if|start|end)? animate applyrange tcp(?:server|source)',
export: 'imagewriter',
debug: 'subtitle blankclip blackness colorbars(?:hd)? compare dumpfiltergraph setgraphanalysis echo histogram info messageclip preroll showfiveversions show(?:framenumber|smpte|time) stack(?:horizontal|vertical) tone version'
}
};

var types = toAlternation([wordLists.types]);
Zinfidel marked this conversation as resolved.
Show resolved Hide resolved
var keywords = toAlternation([wordLists.keywords]);
var predefined = toAlternation([wordLists.predefined]);
var constants = toAlternation([wordLists.constants]);
var properties = toAlternation(Object.values(wordLists.properties));
Zinfidel marked this conversation as resolved.
Show resolved Hide resolved
var intfuncs = toAlternation(Object.values(wordLists.internals));
var intfilters = toAlternation(Object.values(wordLists.filters));
var internals = cat(intfuncs, cat(properties, intfilters));
Zinfidel marked this conversation as resolved.
Show resolved Hide resolved

Prism.languages.avisynth = {

'comment': [
{ // Matches [* *] nestable block comments, but can not handle nested comments correctly (recursion)
pattern: /(^|[^\\])\[\*[\s\S]*?(?:\*\]|$)/,
lookbehind: true,
greedy: true
},
{ // Matches /* */ block comments
pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
lookbehind: true,
greedy: true
},
{ // Matches # comments
pattern: /(^|[^\\$])#.*/,
lookbehind: true,
greedy: true
}
],

// Handle before strings because optional arguments are surrounded by double quotes.
'argument': {
pattern: re(/\b(?:<<0>>)\s+("?)\w+\1/.source, [types], 'i'),
inside: {
'keyword': {
pattern: re(/\b(?:<<0>>)\b/.source, [types], 'i')
}
Zinfidel marked this conversation as resolved.
Show resolved Hide resolved
}
},

'string': [
{ // triple double-quoted
pattern: /"""[\s\S]*?"""/i,
Zinfidel marked this conversation as resolved.
Show resolved Hide resolved
greedy: true,
},
{ // single double-quoted
pattern: /"(?:\\(?:\r\n|[\s\S])|(?!")[^\\\r\n])*"/,
Zinfidel marked this conversation as resolved.
Show resolved Hide resolved
greedy: true,
inside: {
'constant': {
pattern: re(/<<0>>/.source, [predefined]) // These *are* case-sensitive!
Zinfidel marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
],

// The special "last" variable that takes the value of the last implicitly returned clip.
'variable': /\b(last)\b/i,
Zinfidel marked this conversation as resolved.
Show resolved Hide resolved

'boolean': /\b(?:true|false|yes|no)\b/i,

'keyword': {
pattern: re(/((?:^|[\\{])\s*)(?:<<0>>)(?=\s+)/.source, [keywords], 'im'),
lookbehind: true
},

'constant': re(/\b<<0>>\b/.source, [constants]),
Zinfidel marked this conversation as resolved.
Show resolved Hide resolved

'builtin': [
{ // AviSynth's internal clip properties.
pattern: re(/(\b\.)(?:<<0>>)\b(?=[^\.])/.source, [properties], 'i'),
lookbehind: true
},
{ // AviSynth's internal functions and filters, including properties used as functions.
pattern: re(/\b(?:<<0>>)(?=\s*\()/.source, [internals], 'i')
}
],

// External filters, and user-defined filters.
'function': {
pattern: /\b[a-z_]\w*(?=\s*\()/i,
inside: {
'keyword': { // type casts
pattern: re(/\b(?:<<0>>)\b/.source, [types], 'i')
RunDevelopment marked this conversation as resolved.
Show resolved Hide resolved
}
}
},

// Matches a \ as the first or last character on a line
'line-continuation': {
pattern: /(^\s*)\\|\\(?=\s*$)/m,
Zinfidel marked this conversation as resolved.
Show resolved Hide resolved
lookbehind: true,
alias: 'punctuation'
},

'operator': /\+\+?|!=?|<=?|>=?|==?|&&|\|\||\?|\*|\/|%|:/,

'number': /\B\$(?:[\da-f]{6}|[\da-f]{8})\b|(?:(?:\b|\B-)\d+(?:\.\d*)?\b|\B\.\d+\b)/i,
Zinfidel marked this conversation as resolved.
Show resolved Hide resolved

'punctuation': /[{};(),.]/
Zinfidel marked this conversation as resolved.
Show resolved Hide resolved
}
}(Prism));

Prism.languages.avs = Prism.languages.avisynth
1 change: 1 addition & 0 deletions components/prism-avisynth.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions examples/prism-avisynth.html
@@ -0,0 +1,24 @@
<h2>Full Example</h2>
<pre><code>/*
* Example AviSynth script for PrismJS demonstration.
* By Zinfidel
*/

SetFilterMTMode("DEFAULT_MT_MODE", MT_MULTI_INSTANCE)
AddAutoloadDir("MAINSCRIPTDIR/programs/plugins")

# Multiplies clip size and changes aspect ratio to 4:3
function CorrectAspectRatio(clip c, int scaleFactor, bool "useNearestNeighbor") {
useNearestNeighbor = default(useNearestNeighbor, false)
stretchFactor = (c.Height * (4 / 3)) / c.Width

return useNearestNeighbor \
? c.PointResize(c.Width * scaleFactor * stretchFactor, c.Height * scaleFactor) \
: c.Lanczos4Resize(c.Width * scaleFactor * stretchFactor, c.Height * scaleFactor)
}

AviSource("myclip.avi")
last.CorrectAspectRatio(3, yes)


Prefetch(4)</code></pre>
1 change: 1 addition & 0 deletions plugins/autoloader/prism-autoloader.js
Expand Up @@ -172,6 +172,7 @@
"js": "javascript",
"g4": "antlr4",
"adoc": "asciidoc",
"avs": "avisynth",
"avdl": "avro-idl",
"shell": "bash",
"shortcode": "bbcode",
Expand Down