Skip to content

Instantly share code, notes, and snippets.

@frostney
Created February 7, 2013 23:39
Show Gist options
  • Save frostney/4735272 to your computer and use it in GitHub Desktop.
Save frostney/4735272 to your computer and use it in GitHub Desktop.
Rudimentary CSS parser written in about 100 lines of CoffeeScript
class StringReader
buffer = ""
constructor: (@input) ->
@reset()
readUntil: (character, omitCharacter = false, notFoundFn) ->
loop
if @end()
notFoundFn(buffer) if notFoundFn
break
if character.length is 1
break if @input[@currentIndex] is character
else
skip = true
counter = 0
for c in character
unless @input[@currentIndex + counter] is c
skip = false
break
counter++
break if skip
buffer += @input[@currentIndex]
@currentIndex++
@currentIndex += character.length if omitCharacter
buffer
clearBuffer: -> buffer = ""
reset: ->
@currentIndex = 0
@clearBuffer()
end: -> @currentIndex >= @input.length
class CSSParser
tokenNotFound = (expectedCharacter) ->
(token) ->
token = if token then "'#{token}'" else "EOL"
console.log "[WARN] Expected #{expectedCharacter}, got #{token}"
constructor: (@input) ->
parse: ->
inputString = new StringReader(@input)
parsedObject = {}
loop
break if inputString.end()
currentToken = inputString.readUntil("{", true, tokenNotFound("{")).trim()
selector = currentToken.trim()
parsedObject[selector] = {}
inputString.clearBuffer()
selectorToken = inputString.readUntil("}", true, tokenNotFound("}")).trim()
propString = new StringReader(selectorToken)
loop
break if propString.end()
propToken = propString.readUntil(";", true, tokenNotFound(";")).trim()
keyString = new StringReader(propToken)
parsedKey = ""
parsedValue = ""
loop
break if keyString.end()
keyToken = keyString.readUntil(":", true).trim()
unless parsedKey
parsedKey = keyToken
else
parsedValue = keyToken
keyString.clearBuffer()
parsedObject[selector][parsedKey] = parsedValue
propString.clearBuffer()
inputString.clearBuffer()
parsedObject
input = "#selector { width: 50px; } .other-selector { height: 60px; width: 100px; background-color: #fff; }"
parser = new CSSParser(input)
console.log parser.parse()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment