yesodweb / css-text

CSS parser and renderer.
MIT License
16 stars 8 forks source link

parse and render is not idempotent for bootstrap.min.css #6

Closed jgm closed 9 years ago

jgm commented 9 years ago

First

wget https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css

Then in GHCI:

GHCI> Data.Text.Lazy.IO.writeFile "converted.css" . Data.Text.Lazy.Builder.toLazyText . Text.CSS.Render.renderNestedBlocks . (\(Right x) -> x) . Text.CSS.Parse.parseNestedBlocks =<< Data.Text.IO.readFile "bootstrap.min.css"

Now observe that bootstrap.min.css is 113K, and converted.css is 14K. Looks like a parsing problem. See jgm/pandoc#2224.

jgm commented 9 years ago

I normalized bootstrap.min.css and converted.css so I could do a diff. The result shows that converted.css is missing everything after this point:

@@ -1510,5535 +1508,3 @@
     font-weight: 300;
     line-height: 1.4;
 }
-
-@media (min-width:768px) {
-    .lead {
-        font-size: 21px;
-    };
-}
-
-.small,small {
-    font-size: 85%;
-}
-
-.mark,mark {
-    padding: .2em;
-    background-color: #fcf8e3;
-}

So, essentially, the parser seems to quit (but without reporting an error) when it hits @media (min-width:768px).

jgm commented 9 years ago

Okay, I think I've localized this bug:

*Text.CSS.Parse> Text.CSS.Parse.parseNestedBlocks "@media print { :after { color: #000!important; } }"
Right [LeafBlock ("@media print",[("","after { color: #000!important")])]

It's the :after selector that is causing the problem.

jgm commented 9 years ago

Culprit is probably line 92 in Parse.hs:

    unknown <- strip <$> takeTill (\c -> c == '{' || c == '}' || c == ':')
creichert commented 9 years ago

I'm catching up with the issues you linked but there does seem to be an issue:

Prelude Text.CSS.Parse> parseNestedBlocks "@media print { :after { color: #000!important; } }"
Right [LeafBlock ("@media print",[("","after { color: #000!important")])]
Prelude Text.CSS.Parse> parseNestedBlocks "@media print { *:after { color: #000!important; } }"
Right [LeafBlock ("@media print",[("*","after { color: #000!important")])]

With or without the * causes the same problem.

jgm commented 9 years ago

I think I have a fix - will push something soon.

jgm commented 9 years ago

PR #8 should fix the problem discussed most recently above. However, the bootstrap.min.css test still fails. The problem now is

@font-face {
    font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg');
}

which chokes the parser.

jgm commented 9 years ago

OK, my mistake. The @font-face problem was introduced by my last change. I had thought that things like

@media {
  property: value; 
}

were invalid CSS, but apparently that's wrong. Will fix.

jgm commented 9 years ago

This issue is no longer urgent for me, as I've decided not to use css-text in pandoc. You may find some useful ideas for improvements in PR #8.

snoyberg commented 9 years ago

Closing in favor of #8