Skip to content

Instantly share code, notes, and snippets.

@satabin
Last active June 4, 2016 15:30
Show Gist options
  • Save satabin/2da704a4ff80c20ff013 to your computer and use it in GitHub Desktop.
Save satabin/2da704a4ff80c20ff013 to your computer and use it in GitHub Desktop.
class SyncTeXLexer
constructor: (@input) ->
@pointer = 0
current: =>
if @eos()
undefined
else
@input.slice @pointer
eos: =>
@pointer >= @input.length
next: =>
if @eos()
undefined
else if float = /^(-?\d+\.\d+)/.exec(@current())
@pointer += float[0].length
{
token: 'float',
value: parseFloat(float[1])
}
else if int = /^(-?\d+)/.exec(@current())
@pointer += int[0].length
{
token: 'int',
value: parseInt(int[0])
}
else if path = /^([a-zA-Z0-9/_.-]+)/.exec(@current())
@pointer += path[0].length
{
token: 'path',
value: path[1]
}
else if eol = /\n|\r\n/.exec(@current())
@pointer += eol[0].length
{
token: 'eol'
}
else if symbol = /^([{}:! ])/.exec(@current())
@pointer += 1
{
token: symbol
}
else
name = /^([^\s]+)/.exec(@current())
@pointer += path[0].length
{
token: 'name',
value: path[1]
}
class SyncTeXParser
constructor: (@lexer) ->
@lookahead = undefined
token: =>
if not @lookahead?
@lookahead = @lexer.next()
@lookahead
consume: =>
@lookahead = undefined
check: (expected) =>
{ expected_token, expected_value } = expected
{ token, value } = @token()
token is expected_token and value is expected_value
accept: (expected) =>
if @check(expected)
@consume()
else
throw new Error("#{expected.value} of type #{expected.token} expected")
acceptName: (name) =>
@accept {token: 'name', value: name}
acceptSymbol: (sym) =>
@accept {token: sym}
acceptInt: =>
{ token, value } = @token()
if token is 'int'
@consume()
value
else
throw new Error("Integer expected")
acceptFloat: =>
{ token, value } = @token()
if token is 'float'
@consume()
value
else
throw new Error("Float expected")
acceptEol: =>
@accept {token: 'eol'}
parse: =>
file = {}
@preamble(file)
@content(file)
@postamble(file)
@postscriptum(file)
preamble: (file) =>
@acceptName "SyncTeX"
@acceptSymbol " "
@acceptName "Version"
@acceptSymbol ":"
file.version = @acceptInt()
@acceptEol()
file.inputs = @inputLines()
@acceptName "Output"
@acceptSymbol ":"
file.format = @acceptName()
@acceptName "Magnification"
@acceptSymbol ":"
file.magnification = @acceptInt()
@acceptEol()
@acceptName "Unit"
@acceptSymbol ":"
file.unit = @acceptInt()
@acceptEol()
file.offset = {}
@acceptName "XOffset"
@acceptSymbol ":"
file.offset.x = @acceptInt()
@acceptEol()
@acceptName "YOffset"
@acceptSymbol ":"
file.offset.y = @acceptInt()
@acceptEol()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment