Skip to content

Instantly share code, notes, and snippets.

@BrandonBrowning
Last active December 12, 2021 09:01
Show Gist options
  • Save BrandonBrowning/6373772 to your computer and use it in GitHub Desktop.
Save BrandonBrowning/6373772 to your computer and use it in GitHub Desktop.
Simple CSS Parser in F#
// TODO: Fixme
open System
open FParsec
type Css = CssDefinition list
and CssDefinition = CssSelector * CssRule list
and CssSelector = CssSelectorPart list
and CssSelectorPart = CssTag * CssModifier list
and CssModifier =
| CssClass of string
| CssId of string
and CssTag = string
and CssRule = string * string
let identifier = (satisfy isLetter <|> pchar '*' <|> pchar '-') |> many1Chars
let ruleValue = (satisfy <| fun c -> c <> ';') |> many1Chars
let parseCssClass =
(spaces >>. pchar '.') >>. identifier
|>> CssClass
let parseCssId =
(spaces >>. pchar '#') >>. identifier
|>> CssId
let parseCssModifier =
attempt parseCssClass <|> attempt parseCssId
let parseCssSelectorPart =
(spaces >>. identifier) .>>. many parseCssModifier
let parseCssSelector =
many (attempt parseCssSelectorPart)
let parseCssRule =
(identifier .>> spaces) .>>. (pchar ':' >>. spaces >>. ruleValue .>> spaces .>> pchar ';')
let parseCssDefinition =
(parseCssSelector .>> spaces) .>>. (pchar '{' >>. spaces >>. many parseCssRule .>> spaces .>> pchar '}')
let parseCss =
many (attempt parseCssDefinition)
[<EntryPoint>]
let main argv =
let testText = "div .class #id p { margin: 0 auto; } * .btn #foo { background-color: red; }"
testText |> printfn "%s"
run parseCss testText |> printfn "%A"
0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment