A decent CSS parser.

Related tags

CSS Parsers mensch
Overview

mensch Node.js CI

A decent CSS parser.

usage

npm install mensch
var mensch = require('mensch');

var ast = mensch.parse('p { color: black; }');
var css = mensch.stringify(ast);

console.log(css);
// => p { color: black; }

api

parse(css, [options={}])

Convert a CSS string or an array of lexical tokens into a stringify-able AST.

  • css {String|Array} CSS string or array of lexical tokens
  • [options] {Object}
  • [options.comments=false] {Boolean} Allow comment nodes in the AST.
  • [options.position=false] {Boolean} Allow line/column position in the AST.

When {position: true}, AST node will have a position property:

{
  type: 'comment',
  text: ' Hello World! ',
  position: {
    start: { line: 1, col: 1 },
    end: { line 1, col: 18 }
  }
}

stringify(ast, [options={}])

Convert a stringify-able AST into a CSS string.

  • ast {Object} A stringify-able AST
  • [options] {Object}
  • [options.comments=false] {Boolean} Allow comments in the stringified CSS.
  • [options.indentation=''] {String} E.g., indentation: ' ' will indent by two spaces.

lex(css)

Convert a CSS string to an array of lexical tokens for use with .parse().

  • css {String} CSS

non-validating

Mensch is a non-validating CSS parser. While it can handle the major language constructs just fine, and it can recover from gaffes like mis-matched braces and missing or extraneous semi-colons, mensch can't tell you when it finds invalid CSS like a misspelled property name or a misplaced @import.

comments

Unlike most CSS parsers, mensch allows comments to be represented in the AST and subsequently stringified with the {comments: true} option.

var options = { comments: true };
var ast = mensch.parse('.red { color: red; /* Natch. */ }', options);
var css = mensch.stringify(ast, options);

console.log(css);
//=> .red { color: red; /* Natch. */ }

However, comments within the context of a selector, property, etc., will be ignored. These comments are difficult to represent in the AST.

var ast = mench.parse('.red /*1*/ { color /*2*/: /*3*/ red /*4*/; }', options);
var css = mesch.stringify(ast, options);

console.log(css);
//=> .red { color: red; }

ast

The structure of mensch's AST riffs on several existing CSS parsers, but it might not be 100% compatible with other CSS parsers. Here it is in a nutshell:

{
  type: 'stylesheet'
  stylesheet: {
    rules: [{
      type: 'rule',
      selectors: ['.foo'],
      declarations: [{
        type: 'property',
        name: 'color',
        value: 'black'
      }]
    }]
  }
}

credits

Mensch is based on several existing CSS parsers, but nzakas/parser-lib and visionmedia/css are notable influences.

known users

voidlabs/mosaico uses Mensch parser to parse custom-flavored CSS rules in email templates and make the template editable: positions, comment parsing, multiple declarations for the same property have been keys to the choice of Mensch!

Automattic/juice moved to Mensch CSS parser since 3.0 release in order to fix dozen of issues with the previous parser, expecially with support for "multiple properties declarations" in the same ruleset and with invalid values.

Please let us know if you use Mensch in your library!

Comments
  • npm version publish request

    npm version publish request

    Hi @brettstimmerman and @bago,

    I am using the npm package, juice, on a project for work. The Juice package has a dependency on mensch#v0.3.3, but they reference your github repository instead of the npm package itself. It looks like this could be because you haven't published the release to npm (currently 0.3.1 on npm). If it isn't too much of a hassle, would you mind publishing the latest release to npm? Then I can get them to switch the dependency to npm (my deployment setup doesn't allow me to use git on my prod server).

    Thanks for your time. Cheers, Max

    opened by maxasauruswall 7
  • Rules parsed with position=true should have the end curly brace be th…

    Rules parsed with position=true should have the end curly brace be th…

    Rules parsed with position=true should have the end curly brace be the end position, not the end of the selector/at-rule.

    Signed-off-by: Jonathan Horowitz [email protected]

    opened by ghost 5
  • Fixes column/line computation for comments and at-rules, + fix curly braces in strings + fix parsing when property value is missing + keep \n and \t in propery values.

    Fixes column/line computation for comments and at-rules, + fix curly braces in strings + fix parsing when property value is missing + keep \n and \t in propery values.

    My attempt at fixing https://github.com/brettstimmerman/mensch/issues/15 and more. See new test position.js for fixed expectations.

    Moved the col/line computation inside the "skip" method, so to make sure it is always invoked when moving the cursor. NOTE: The method could be optimized and does not support negative movements.

    opened by bago 4
  • Please publish new version

    Please publish new version

    Hi,

    version 0.3.3 has an error with stringify indentation, an error that has already been resolved about two years ago !!! but nobody has published a new version (0.3.4) with that solution

    Can anyone publish that new version to fix that, please?

    opened by jmtt89 2
  • Fix global leak and stringify indentation

    Fix global leak and stringify indentation

    The indent method was leaking into the global scope, so this PR cleans that up by adding a file-scoped _level variable. This variable is also initialized inside the stringify function rather than in the level function so that if stringify were to ever throw an exception, subsequent calls would not use the wrong indentation level.

    Please let me know if you need any information or need me to do anything to help get this merged in!

    opened by tjaneczko 2
  • Is this project still

    Is this project still "mantained"?

    Hi Brett,

    first of all I want to thank you for this great parser!

    In the next weeks I'm going to publish an opensource project (https://github.com/voidlabs/mosaico) depending on my fork for mensch (https://github.com/bago/mensch).

    As you can see (from other open issues and PR) I have applied a few patches to mensch, mainly related to "positions" and a few other improvements.

    Is there any chance to get write access to your repository or to have you accept my PR anytime soon?

    opened by bago 2
  • ie5 hack creating confusion

    ie5 hack creating confusion

    @media tty { 
      i{content:"\";/*" "*/}} a { color: black; } /*";}
    }
    
    a {color: white}
    

    The hack itself is handled ok - two strings in the content property

    The problem is that the next ruleset is considered part of the media block, while it should be outside of it

    Test code:

    var mensch = require('mensch');
    var css = require('fs').readFileSync('./examples/css.css').toString();
    var parsed = mensch.parse(css);
    var res = mensch.stringify(parsed, {indentation: '  '})
    
    console.log(res)
    

    Result:

    @media tty {
      i {
        content: "\";/*" "*/}} a { color: black; } /*";
      }
    
      a {
        color: white;
      }
    }
    
    bug 
    opened by stoyan 2
  • new lines should be treated as spaces

    new lines should be treated as spaces

    body
    div
    {color: red}
    

    gives

    { type: 'rule',
      selectors: [ 'bodydiv' ],
      declarations: [ { type: 'property', name: 'color', value: 'red' } ] }
    

    I think the selector should be body div

    bug 
    opened by stoyan 2
  • correct handling of escaped quotes

    correct handling of escaped quotes

    this confuses the parser:

      .sele {
        content: "he\"lo";
      }
    

    this is ok:

      .sele {
        content: "helo";
      }
    
    { type: 'property', 
      name: 'content', 
      value: '"helo"' }
    
    bug 
    opened by stoyan 2
  • Wrong position computation between first and other lines

    Wrong position computation between first and other lines

    On line 1 the first column is column 1, on the following lines the first column is column 0. I guess the correct positioning is the one when the first char is col:1, line:1 so the right solution is to have following lines to start with 1 too.

    opened by bago 1
  • empty value creating confusion

    empty value creating confusion

    in

    body {background:;}
    #yo {display: block;}
    

    Expected

    body {
    
    }
    #yo {
      display: block;
    }
    

    Actual

    body {
      background: ;#yo display: block;
    }
    

    AST

    {
      "type": "stylesheet",
      "stylesheet": {
        "rules": [
          {
            "type": "rule",
            "selectors": [
              "body"
            ],
            "declarations": [
              {
                "type": "property",
                "name": "background",
                "value": ";#yo display: block"
              }
            ]
          }
        ]
      }
    }
    
    bug 
    opened by stoyan 1
  • [Bug] The stylesheet rules is wrong when css includes :not()

    [Bug] The stylesheet rules is wrong when css includes :not()

    Run this code:

    var mensch = require('mensch');
    var parsed = mensch.parse('.my-class:not(.class1, .class2) {}', {
      position: true,
      comments: true,
    });
    

    The parsed.stylesheet.rules will be an array with two items: ['.my-class:not(.class1', '.class)'], this rules are wrong. It should not be splited by , simply.

    opened by lwenn 0
Releases(v0.3.4)
  • v0.3.4(Nov 9, 2019)

  • v0.3.3(Aug 4, 2016)

  • v0.3.2(Aug 18, 2015)

    • Fixed column/line computation for comments and at-rules (Fix #15)
    • Closing } and ; now takes precedence over declaration value parsing (Fix #14)
    • Ignore curly braces in strings (Fix #13)
    • Keep \n and \t inside values and consider them "whitespace" (Fix #12)
    • Fixed column count in positions for rows after the first line (Fix #18)
    • Enabled running test suite under Windows (CRLF vs LF issues)
    Source code(tar.gz)
    Source code(zip)
Owner
Brett Stimmerman
A human with internet.
Brett Stimmerman
A tool set for CSS including fast detailed parser, walker, generator and lexer based on W3C specs and browser implementations

CSSTree CSSTree is a tool set for CSS: fast detailed parser (CSS → AST), walker (AST traversal), generator (AST → CSS) and lexer (validation and match

CSSTree 1.6k Dec 28, 2022
CSS parser with support of preprocessors

Gonzales PE @dev Gonzales PE is a CSS parser which plays nicely with preprocessors. Currently those are supported: SCSS, Sass, LESS. Try out Gonzales

Tony Ganch 322 Dec 10, 2022
Plugin framework for CSS preprocessing in Node.js

rework CSS manipulations built on css, allowing you to automate vendor prefixing, create your own properties, inline images, anything you can imagine!

rework 2.8k Dec 6, 2022
Modern CSS to all browsers

stylecow: modern CSS for all browser Node library to fix your css code and make it compatible with all browsers. Created by Óscar Otero. License: MIT

stylecow 155 Dec 21, 2022
Json-parser - A parser for json-objects without dependencies

Json Parser This is a experimental tool that I create for educational purposes, it's based in the jq works With this tool you can parse json-like stri

Gabriel Guerra 1 Jan 3, 2022
CSS Object Model implemented in pure JavaScript. It's also a parser!

CSSOM CSSOM.js is a CSS parser written in pure JavaScript. It is also a partial implementation of CSS Object Model. CSSOM.parse("body {color: black}")

Nikita Vasilyev 723 Dec 30, 2022
A tool set for CSS including fast detailed parser, walker, generator and lexer based on W3C specs and browser implementations

CSSTree CSSTree is a tool set for CSS: fast detailed parser (CSS → AST), walker (AST traversal), generator (AST → CSS) and lexer (validation and match

CSSTree 1.6k Dec 28, 2022
CSS parser with support of preprocessors

Gonzales PE @dev Gonzales PE is a CSS parser which plays nicely with preprocessors. Currently those are supported: SCSS, Sass, LESS. Try out Gonzales

Tony Ganch 322 Dec 10, 2022
Javascript Canvas Library, SVG-to-Canvas (& canvas-to-SVG) Parser

Fabric.js Fabric.js is a framework that makes it easy to work with HTML5 canvas element. It is an interactive object model on top of canvas element. I

Fabric.js 23.6k Jan 3, 2023
Fast and powerful CSV (delimited text) parser that gracefully handles large files and malformed input

Parse CSV with JavaScript Papa Parse is the fastest in-browser CSV (or delimited text) parser for JavaScript. It is reliable and correct according to

Matt Holt 11k Jan 6, 2023
Javascript Canvas Library, SVG-to-Canvas (& canvas-to-SVG) Parser

Fabric.js Fabric.js is a framework that makes it easy to work with HTML5 canvas element. It is an interactive object model on top of canvas element. I

Fabric.js 23.6k Jan 3, 2023
:herb: NodeJS PHP Parser - extract AST or tokens (PHP5 and PHP7)

php-parser This javascript library parses PHP code and convert it to AST. Installation This library is distributed with npm : npm install php-parser -

glayzzle 476 Jan 7, 2023
tar-stream is a streaming tar parser and generator.

tar-stream tar-stream is a streaming tar parser and generator and nothing else. It is streams2 and operates purely using streams which means you can e

Mathias Buus 356 Jan 3, 2023
JavaScript parser for FIGlet fonts

_______ _________ _______ _ _______ _________ _________ _______ ( ____ \\__ __/( ____ \( \ ( ____ \\__ __/ \__ _/(

Scott González 114 Oct 15, 2022
Receipt parser webapplication written in javascript and python.

Receipt Manager Webapp You can find pre-compiled releases on the Github release page. All the needed info about how to use the receipt-manager-webapp

null 37 Nov 27, 2022
Live port of Lark's standalone parser to Javascript

Lark.js Generate LALR(1) parsers in Javascript Lark is a popular parsing toolkit for Python. This project is a live port of the Lark standalone parser

Lark - Parsing Library & Toolkit 51 Nov 19, 2022
This is a test parser which can automatically parse the tests in from websites like codeforces, codechef, atcoder etc.

✔ Sublime test parser This is a test parser which can automatically parse the tests in from websites like codeforces, codechef, atcoder etc. See how i

Prakhar Rai 15 Aug 6, 2022
A markdown parser and compiler. Built for speed.

Marked ⚡ built for speed ⬇️ low-level compiler for parsing markdown without caching or blocking for long periods of time ⚖️ light-weight while impleme

Marked 28.9k Jan 7, 2023
A lightweight Adobe Photoshop .psd/.psb file parser in typescript with zero-dependency for WebBrowser and NodeJS

@webtoon/psd A lightweight Adobe Photoshop .psd/.psb file parser in typescript with zero-dependency for WebBrowser and NodeJS Browser Support Chrome F

null 830 Jan 1, 2023