Code Monkey home page Code Monkey logo

douceur's Introduction

douceur Build Status

A simple CSS parser and inliner in Golang.

Douceur Logo

Parser is vaguely inspired by CSS Syntax Module Level 3 and corresponding JS parser.

Inliner only parses CSS defined in HTML document, it DOES NOT fetch external stylesheets (for now).

Inliner inserts additional attributes when possible, for example:

<html>
  <head>
  <style type="text/css">
    body {
      background-color: #f2f2f2;
    }
  </style>
  </head>
  <body>
    <p>Inline me !</p>
  </body>
</html>`

Becomes:

<html>
  <head>
  </head>
  <body style="background-color: #f2f2f2;" bgcolor="#f2f2f2">
    <p>Inline me !</p>
  </body>
</html>`

The bgcolor attribute is inserted, in addition to the inlined background-color style.

Tool usage

Install tool:

$ go install github.com/aymerick/douceur

Parse a CSS file and display result:

$ douceur parse inputfile.css

Inline CSS in an HTML document and display result:

$ douceur inline inputfile.html

Library usage

Fetch package:

$ go get github.com/aymerick/douceur

Parse CSS

package main

import (
    "fmt"

    "github.com/aymerick/douceur/parser"
)

func main() {
    input := `body {
    /* D4rK s1T3 */
    background-color: black;
        }

  p     {
    /* Try to read that ! HAHA! */
    color: red; /* L O L */
 }
`

    stylesheet, err := parser.Parse(input)
    if err != nil {
        panic("Please fill a bug :)")
    }

    fmt.Print(stylesheet.String())
}

Displays:

body {
  background-color: black;
}
p {
  color: red;
}

Inline HTML

package main

import (
    "fmt"

    "github.com/aymerick/douceur/inliner"
)

func main() {
    input := `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<style type="text/css">
  p {
    font-family: 'Helvetica Neue', Verdana, sans-serif;
    color: #eee;
  }
</style>
  </head>
  <body>
    <p>
      Inline me please!
    </p>
</body>
</html>`

    html, err := inliner.Inline(input)
    if err != nil {
        panic("Please fill a bug :)")
    }

    fmt.Print(html)
}

Displays:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

  </head>
  <body>
    <p style="color: #eee; font-family: &#39;Helvetica Neue&#39;, Verdana, sans-serif;">
      Inline me please!
    </p>

</body></html>

Test

go test ./... -v

Dependencies

Similar projects

douceur's People

Contributors

aymerick avatar jsgv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

douceur's Issues

Repository activity

I use this code for my mail service, but would like to know if there is any activity. I did a lot of refactoring and added Renovate to my fork.

If interested we could integrate the changes into this repo.

Is there any activity on this repo anyway? I noticed old PR's and issues that are not being replied to/merged or resolved in any way

Infinite loop parsing CSS

The following code loops forever in the latest version:

package css

import (
    "testing"

    "github.com/aymerick/douceur/parser"
)

func TestInfiniteLoop(t *testing.T) {
    parser.Parse(`
@media ( __desktop ) {
  background-color: red;
}
`)
}

Problem with parsing prefixed keyframes

With this CSS

@-webkit-keyframes segment-spin {
  from {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg)
  }
  to {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg)
  }
}

I get:

Unexpected } character: CHAR (line: 11, column: 1): "}"

I think it's because it's not a recognized "AtRule". This works just fine to parse:

@keyframes segment-spin{
from{-webkit-transform:rotate(0deg);transform:rotate(0deg)}
  to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}
}

Vendor prefixes makes me cry at night, but a possible solution would be to extend
this line.

But pardon me, why maintain a list like that? What other strings that starts with a @ can't all be considered "at rules"? E.g this function could be something like:

func (rule *Rule) EmbedsRules() bool {
    return strings.HasPrefix(rule.Name, "@")
}

No?

Preserve Golang template structure

I'm seeing some oddities for this trivial example

package main

import (
	"fmt"
	"github.com/aymerick/douceur/inliner"
)

func main() {
	tmpl := `
<html>
<head>
</head>
<body>
<div>
<table>
{{- range .Trash -}}<tr><td>{{.SomeId}}</td></tr>{{- end -}}
</table>
</div>
</body>
</html>`

	compiled, _ := inliner.Inline(tmpl)

	fmt.Println(compiled)
}
$ go run example.go
<html><head>
</head>
<body>
<div>

{{- range .Trash -}}{{- end -}}
<table><tbody><tr><td>{{.SomeId}}</td></tr></tbody></table>
</div>

</body></html>

It seems like there are a couple strange things happening here.

  1. A tbody tag is automatically introduced for some reason
  2. The Go template tags are re-arranged so that the compiled output cannot be re-used for templating

nbsp is replaced with space

The inliner library replaces &nbsp; is replaced with a space character. In my opinion, inliner should leave &nbsp; as it is. Here is a short test.

html := `
<html>
  <head>
  <style type="text/css">
    body {
      background-color: #f2f2f2;
    }
  </style>
  </head>
  <body>
    <p>&nbsp;</p>
  </body>
</html>`
inline, _ := inliner.Inline(html)
fmt.Println(inline)

This prints:

<html><head>

  </head>
  <body style="background-color: #f2f2f2;" bgcolor="#f2f2f2">
    <p> </p>

</body></html>

Any quick fix for this?

Preserve css style header after inlining.

This is more question/feature-request.

I want to preserve the existing CSS selectors after running through the inliner, eg;

Before

<html>
<head>
<style>
.my-class {
  color: red;
}
</style>
</head>
<body>
<p class="my-class">Test</p>
</body>
</html>

After

<html>
<head>
<style>
.my-class {
  color: red;
}
</style>
</head>
<body>
<p class="my-class" style="color: red;">Test</p>
</body>
</html>

So the my-class class is both inlined in the p element as well as preserved in the <style> header.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.