Ruby CSS parser


#1

Anyone know of a decent ruby CSS parser?

_Kevin


#2

On Feb 5, 2007, at 6:45 PM, _Kevin wrote:

Anyone know of a decent ruby CSS parser?

I’m writing a packrat parser library and this would make a fun
example. I’ve already built a JSON parser with it, so I’m pretty
sure it’s up to the challenge. I’m currently wrapping the core in a
DSL to make it easier to use, but it’s useable. I’ll talk you
through it if you want to work on this.

Of course, I realize that’s not what you asked for. :wink:

James Edward G. II


#3

On 2/5/07, James Edward G. II removed_email_address@domain.invalid wrote:

On Feb 5, 2007, at 6:45 PM, _Kevin wrote:

Anyone know of a decent ruby CSS parser?

I’m writing a packrat parser library and this would make a fun
example. I’ve already built a JSON parser with it, so I’m pretty
sure it’s up to the challenge. I’m currently wrapping the core in a
DSL to make it easier to use,

Oooh, packrat parsing! I assume you’ve seen this stuff:
http://www.lshift.net/blog/2005/08/22/json-for-mzscheme-and-a-portable-packrat-parsing-combinator-library

Keith


#4

On Feb 6, 2007, at 9:55 AM, Keith F. wrote:

Oooh, packrat parsing!
Yeah, I’m having fun playing with it in my spare time. The project
is Ghost Wheel on RubyForge, if you want to take a peek. I’ll make a
release as soon as I get the Ruby DSL wrapper finished.

I assume you’ve seen this stuff:
http://www.lshift.net/blog/2005/08/22/json-for-mzscheme-and-a-
portable-packrat-parsing-combinator-library

Interesting. I hadn’t seen that before now. Thanks for sharing.

James Edward G. II


#5

On Tue, 6 Feb 2007, _Kevin wrote:

Anyone know of a decent ruby CSS parser?

This is the opposite of what you are looking for, but with the upcoming
IOWA 1.0 release I have a Ruby CSS DSL – write CSS with Ruby using a
syntax that’s about as close as I could get it to actual CSS. It
supports
everything Ruby does, so variables work as does nesting of selectors
into
other selectors, and storing a selector into a variable that can be
refered to later. It also provides a smart caching feature so that if,
for instance, one customizes the generated CSS according to a cookie
setting, it can cache that generated CSS and reuse it without having to
execute all of the DSL code for every request.

The goals are to provide much DRYer CSS using Ruby that looks a lot like
CSS, with easy support for dynamic CSS generation, all covered under the
syntax checking of the Ruby parser (which should help one catch simple
errors). And because it’s all Ruby code, it’s easy to write tests to
validate dynamically generated CSS.

Here’s a quick preview:

Media.screen {
body {
font {
color ‘green’
size 12.px
}
}
}

If one wants to refer to something later, one may:

Media.screen {
body {
base_font = font {
color :green
size 12.px
}

 footer {
   font {
     size base_font - 2
     color :black
   }
 }

}
}

All CSS1, CSS2, and CSS3 selectors are supported.

Kirk H.


#6

On Feb 6, 2007, at 10:05 AM, James Edward G. II wrote:

On Feb 6, 2007, at 9:55 AM, Keith F. wrote:

I assume you’ve seen this stuff:
http://www.lshift.net/blog/2005/08/22/json-for-mzscheme-and-a-
portable-packrat-parsing-combinator-library

Interesting. I hadn’t seen that before now. Thanks for sharing.

Looking into this a little further, I find this oddity in the parser:

(define (skip-comment-char results)
(comment-body (parse-results-next results)))

I’m not familiar with scheme, so I don’t know exactly what’s going on
here, but the JSON language does not have comments, so this is a
little odd.

For the curious, the current DSL goal in Ghost Wheel is:

JSON_PARSER = GhostWheel::build_parser do
rule( :keyword,
alt(“true”, “false”, “null”) { |k|
{“true” => true, “false” => false, “null” => nil}[k]
} )

rule( :number,
/-?(?:0|[1-9]\d*)(?:.\d+(?:[eE][±]?\d+)?)?/ ) { |n|
n.include?(".") ? Float(n) : Integer(n)
}

rule( :string_content,
alt(
lit(%r{\["\/]}) { |e| e[-1, 1] },
lit(/\[bfnrt]/) { |e|
Hash[*%W[b \n f \f n \n r \r t \t]][e[-1, 1]]
},
lit(/\u[0-9a-fA-F]{4}/) { |e| [Integer(“0x#{e
[2…-1]}”)].pack(“U”) },
/[^\"]+/
) )
rule( :string,
seq(
skip(’"’),
zplus(:string_content),
skip(’"’)
) { |s| s.flatten.join } )

rule( :array,
seq(
skip(/[\s*/),
alt(
seq(
oplus(seq(:value, skip(/\s*,\s*/))),
:value
) { |a| a[0].inject([]) { |vs, v| vs.push(v) } + a
[-1…-1] },
seq(opt(:value))
),
skip(/\s
]/)
) { |a| a.first } )

rule(:object_pair, seq(:string, /\s*:\s*/, :value) { |kv| {kv[0]
=> kv[-1]} })
rule( :object,
seq(
skip(/{\s*/),
alt(
seq(
oplus(seq(:object_pair, skip(/\s*;\s*/))),
:object_pair
) { |ps| ps[0][0] + ps[-1…-1] },
seq(opt(:object_pair))
),
skip(/}\s*/)
) { |ps| ps[0].inject({}) { |h, p| h.merge§ } } )

rule(:value_space, opt(skip(/\s+/)))
rule( :value,
seq(
:value_space,
alt(:object, :array, :string, :number, :keyword),
:value_space
) { |v| v[0] } )

parser(:json, seq(:value, eof) { |j| j[0] })
end

This is a good bit more compact than the Scheme equivalent at the
above link.

James Edward G. II


#7

From: removed_email_address@domain.invalid [mailto:removed_email_address@domain.invalid] :

IOWA 1.0 release I have a Ruby CSS DSL – write CSS with Ruby using a

syntax that’s about as close as I could get it to actual CSS.

this is uver cool. is it possible to plug it in to other non*-iowa
frameworks like nitro and rails?
waiting for ruby css…
kind regards -botp


#8

On 2/6/07, Peña, Botp removed_email_address@domain.invalid wrote:

From: removed_email_address@domain.invalid [mailto:removed_email_address@domain.invalid] :

IOWA 1.0 release I have a Ruby CSS DSL – write CSS with Ruby using a

syntax that’s about as close as I could get it to actual CSS.

this is uver cool. is it possible to plug it in to other non*-iowa frameworks like nitro and rails?
waiting for ruby css…

+1, I’d like to see something like this for camping.


#9

On Wed, 7 Feb 2007, [iso-8859-1] Peña, Botp wrote:

From: removed_email_address@domain.invalid [mailto:removed_email_address@domain.invalid] :

IOWA 1.0 release I have a Ruby CSS DSL – write CSS with Ruby using a

syntax that’s about as close as I could get it to actual CSS.

this is uver cool. is it possible to plug it in to other non*-iowa frameworks like nitro and rails?
waiting for ruby css…

Yes. It should be possible to use it in Nitro or Rails with no
problems.

Kirk H.


#10

cache that generated CSS and reuse it without having to execute all
of the DSL code for every request.

The goals are to provide much DRYer CSS using Ruby that looks a lot
like CSS, with easy support for dynamic CSS generation, all covered
under the syntax checking of the Ruby parser (which should help one
catch simple errors). And because it’s all Ruby code, it’s easy to
write tests to validate dynamically generated CSS.

This sounds similar to my css_dryer plugin for Rails which allows one
to nest selectors and use variables:

http://blog.airbladesoftware.com/2006/12/11/cssdryer-dry-up-your-css

In the code I have to parse DRY CSS stylesheets as input. At the
time I thought I could either build a proper, robust parser or get by
with regular expressions and a home-made state machine. Not having
any experience building parsers, I went with the latter approach. It
works well but would I think be tricky to extend!

Regards,
Andy S.


AirBlade Software Ltd
http://airbladesoftware.com

“Software that doesn’t make you cry…”