Skip to content

Commit

Permalink
Add support for time code literals
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanhogg committed Feb 9, 2025
1 parent dba087f commit 805a9a7
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 0 deletions.
4 changes: 4 additions & 0 deletions atom/language-flitter/grammars/flitter.cson
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ patterns: [
match: '--.*$'
name: 'comment.single.flitter'
}
{
match: '\\b([0-9]+:)?[0-5]?[0-9]:[0-5]?[0-9](\\.[0-9]+)?\\b'
name: 'constant.timecode.flitter'
}
{
match: '\\b[-+]?([0-9][_0-9]*(\\.[0-9][_0-9]*)?|\\.[0-9][_0-9]*)([eE][-+]?[0-9][_0-9]*)?[pnuµmkMGT]?\\b'
name: 'constant.numeric.flitter'
Expand Down
17 changes: 17 additions & 0 deletions docs/language.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,23 @@ symbol, then that symbol must be used to retrieve the state value. If a string
has been used, then a symbol *cannot* be used to retrieve the value.
:::

### Time codes

In addition to normal literal numbers, as described above, **Flitter** supports
literal *time codes*, which are given as a sequence of hours, minutes and
seconds separated with colon characters (`:`), with the hours being optional
and the seconds having an optional decimal fraction. For example:

```flitter
!video filename='test.mp4' position=02:05.3
```

Time codes are converted by the parser into a single-item numeric vector
representing the total number of seconds (*125.3* in the example above).
The hours component may be an arbitrarily large integer value, the minutes
and seconds must be in the range *[0,60)*. Time codes may not be combined with
exponents or SI prefixes, and do not support `_` separators.

### Nodes

The purpose of any **Flitter** program is to construct a render tree.
Expand Down
2 changes: 2 additions & 0 deletions src/flitter/language/grammar.lark
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ NODE : /![_\p{alpha}][_\p{alnum}]*'*/i
TAG : /#[_\p{alpha}][_\p{alnum}]*'*/i
SYMBOL : /:[_\p{alpha}][_\p{alnum}]*'*/i
NUMBER : /([0-9][_0-9]*(\.[0-9][_0-9]*)?|\.[0-9][_0-9]*)([eE][-+]?[0-9][_0-9]*)?[pnuµmkMGT]?/
TIMECODE.2 : /([0-9]+:)?[0-5]?[0-9]:[0-5]?[0-9](\.[0-9]+)?/
STRING : /('''([^'\\]|\\.|'{1,2}(?!'))*'''|'([^'\n\\]|\\.)*'|"""([^"\\]|\\.|"{1,2}(?!"))*"""|"([^"\n\\]|\\.)*")/
_HASHBANG : /#!.*\r?\n/
_LPAREN : "("
Expand Down Expand Up @@ -133,6 +134,7 @@ named_arg : NAME "=" node -> binding
| _LPAREN node _RPAREN

literal : NUMBER
| TIMECODE
| STRING
| SYMBOL
| NODE
7 changes: 7 additions & 0 deletions src/flitter/language/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ def NUMBER(self, token):
token = token[:-1]
return model.Vector.coerce(float(token) * multiplier)

def TIMECODE(self, token):
parts = token.split(':')
seconds = 60*int(parts[-2]) + float(parts[-1])
if len(parts) == 3:
seconds += 3600*int(parts[-3])
return model.Vector.coerce(seconds)

def TAG(self, token):
return intern(str(token)[1:])

Expand Down

0 comments on commit 805a9a7

Please sign in to comment.