Skip to content

Commit

Permalink
Added README
Browse files Browse the repository at this point in the history
  • Loading branch information
sergeche committed Aug 20, 2019
1 parent 0b3290f commit 35a9100
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 52 deletions.
24 changes: 0 additions & 24 deletions .eslintrc.json

This file was deleted.

89 changes: 89 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Emmet — the essential toolkit for web-developers

Emmet is a web-developer’s toolkit for boosting HTML & CSS code writing.

With Emmet, you can type expressions (_abbreviations_) similar to CSS selectors and convert them into code fragment with a single keystroke. For example, this abbreviation:

```
ul#nav>li.item$*4>a{Item $}
```

...can be expanded into:

```html
<ul id="nav">
<li class="item1"><a href="">Item 1</a></li>
<li class="item2"><a href="">Item 2</a></li>
<li class="item3"><a href="">Item 3</a></li>
<li class="item4"><a href="">Item 4</a></li>
</ul>
```

## Features

* **Familiar syntax**: as a web-developer, you already know how to use Emmet. Abbreviation syntax is similar to CSS Selectors with shortcuts for id, class, custom attributes, element nesting and so on.
* **Dynamic snippets**: unlike default editor snippets, Emmet abbreviations are dynamic and parsed as-you-type. No need to predefine them for each project, just type `MyComponent>custom-element` to convert any word into a tag.
* **CSS properties shortcuts**: Emmet provides special syntax for CSS properties with embedded values. For example, `bd1-s#f.5` will be exampled to `border: 1px solid rgba(255, 255, 255, 0.5)`.
* **Available for most popular syntaxes**: use single abbreviation to produce code for most popular syntaxes like HAML, Pug, JSX, SCSS, SASS etc.

[Read more about Emmet features](https://docs.emmet.io)

This repo contains only core module for parsing and expanding Emmet abbreviations. Editor plugins are available as [separate repos](https://github.com/emmetio).

This is a *monorepo*: top-level project contains all the code required for converting abbreviation into code fragment while [`./packages`](/packages) folder contains modules for parsing abbreviations into AST and can be used independently (for example, as lexer for syntax highlighting).

### Installation

You can install Emmet as a regular npm module:

```bash
npm i emmet@rc
```

Note that current version is still in *release candidate* version so it should be installed with `@rc` tag. After release, it will be available as version 2.x.

## Usage

To expand abbreviation, pass it to default function of `emmet` module:

```js
import expand from 'emmet';

console.log(expand('p>a')); // <p><a href=""></a></p>
```

By default, Emmet expands *markup* abbreviation, e.g. abbreviation used for producing nested elements with attributes (like HTML, XML, HAML etc.). If you want to expand *stylesheet* abbreviation, you should pass it as a `type` property of second argument:

```js
import expand from 'emmet';

console.log(expand('p10', { type: 'stylesheet' })); // padding: 10px;
```

A stylesheet abbreviation has slightly different syntax compared to markup one: it doesn’t support nesting and attributes but allows embedded values in element name.

Alternatively, Emmet supports *syntaxes* with predefined snippets and options:

```js
import expand from 'emmet';

console.log(expand('p10', { syntax: 'css' })); // padding: 10px;
console.log(expand('p10', { syntax: 'stylus' })); // padding 10px
```

Predefined syntaxes already have `type` attribute which describes whether given abbreviation is markup or stylesheet, but if you wnt to use it with your custom syntax name, you should provide `type` config option as well (default it `markup`):

```js
import expand from 'emmet';

console.log(expand('p10', {
syntax: 'my-custom-syntax',
type: 'stylesheet',
options: {
'stylesheet.between': '__',
'stylesheet.after': '',
}
})); // padding__10px
```

You can pass `options` property as well to shape-up final output or enable/disable various features. See [`src/config`](src/config) for more info and available options.
47 changes: 21 additions & 26 deletions packages/abbreviation/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
# Emmet abbreviation parser [![Build Status](https://travis-ci.org/emmetio/abbreviation.svg?branch=master)](https://travis-ci.org/emmetio/abbreviation)
# Emmet markup abbreviation parser

Reference parser implementation for [Emmet](http://emmet.io) project. Parser takes an abbreviation string and produces a tree. This tree can then be analyzed, updated etc., similar to DOM tree. Use it to produce a string output afterwards.
Parses given Emmet *markup* abbreviation into AST. Parsing is performed in two steps: first it tokenizes given abbreviation (useful for syntax highlighting in editors) and then tokens are analyzed and converted into AST nodes as plain, JSON-serializable objects.

Note that this module *does not* produce a tree that can be used for final HTML output: the tree might miss tag names, predefined attributes, resolved snippets and so on. The goal of this parser is to be a basic embeddable building block for projects that wish to utilize Emmet abbreviations syntax.

If you need a complete HTML or CSS abbreviation expander, you should transform parsed abbreviation tree via [`@emmetio/html-transform`](https://github.com/emmetio/html-transform) or `@emmetio/css-tansform` as well.
Note that AST tree in most cases cannot be used directly for output: for example, AST node produced from `.foo.bar` element misses element name and contains two `class` attributes with `foo` and `bar` values (not a single `class` with `foo bar` value).

## Usage

Expand All @@ -17,40 +15,37 @@ npm install @emmetio/abbreviation
Then add it into your project:

```js
'use strict';
import parseAbbreviation from '@emmetio/abbreviation';

const tree = parseAbbreviation('div#foo>span.bar*3');
tree.walk((node, level) => {
let pad = '';
while (level--) {
pad += ' ';
}
console.log('%s%s', level, node.name);
});
```

After abbreviation is expanded, use returned tree to read and update via [DOM-like API](/lib/node.js).
import parse from '@emmetio/abbreviation';

const tree = parse('div#foo>span.bar*3');
/* {
type: 'Abbreviation',
children: [{
type: 'AbbreviationNode',
name: 'div',
attributes: [...],
children: [...]
}]
} */

There are two types of nodes in returned tree:

* *Element node* is a basic node with name, attributes and/or text content. E.g. an element that can be represented somehow.
* *Grouping node* is used to group sub-nodes and doesn’t has its own representation. It it mostly used to repeat a set of elements, for example `a>(b+c)*3`. Such nodes has `node.isGroup` set to `true`.
```
The returned tree contains `AbbreviationNode` items: a node with name, attributes and/or text content. E.g. an element that can be represented somehow. Repeated and grouped nodes like `a>(b+c)*3` are automatically converted and duplicated as distinct `AbbreviationNode` with distinct `.repeat` property which identifies node in repeating sequence.

## Abbreviation syntax

Emmet abbreviation has the following basic parts:
Emmet abbreviation element has the following basic parts:

```
name.class#id[attributes?, ...]{text value}*repeater/
```

* `name` — element name, like `div`, `span` etc. Stored as `node.name` property.
* `[attributes]` — list of attributes. Each attribute is stored as [`Attribute`](/lib/attribute.js) instance and can be accessed by `node.getAttribute(name)`. Each attribute can be written in different formats:
* `[attributes]` — list of attributes. Each attribute is stored as [`AbbreviationAttribute`](/src/types.ts) instance and can be accessed by `node.getAttribute(name)`. Each attribute can be written in different formats:
* `attr` — attribute with empty value.
* `attr=value` — attribute with value. The `value` may contain any character except space or `]`.
* `attr="value"` or `attr='value'` — attribute with value in quotes. Quotes are automatically removed.
* `attr="value"` or `attr='value'` — attribute with value in quotes. Quotes are automatically removed. Expression values like `attr={value}` are supported and can be identified by `valueType: "expression"` property.
* `attr.` — boolean attribute, e.g. attribute without value, like `required` in `<input>`.
* `!attr` – implicit attribute, will be outputted if its value is not empty. Used as a placeholder to preserve attribute order in output.
* `./non/attr/value` — value for default attribute. In other words, anything that doesn’t match a attribute name characters. Can be a single- or double-quotted as well. Default attribute is stored with `null` as name and should be used later, for example, to resolve predefined attributes.
* `.class` — shorthand for `class` attribute. Note that an element can have multiple classes, like `.class1.class2.class3`.
* `#id` — shorthand for `id` attribute.
Expand Down
41 changes: 39 additions & 2 deletions packages/css-abbreviation/README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,39 @@
# css-transform
Prepares Emmet abbreviation for CSS output
# Emmet stylesheet abbreviation parser

Parses given Emmet *stylesheet* abbreviation into AST. Parsing is performed in two steps: first it tokenizes given abbreviation (useful for syntax highlighting in editors) and then tokens are analyzed and converted into AST nodes as plain, JSON-serializable objects.

Unlike in [markup abbreviations](/packages/abbreviation), elements in stylesheet abbreviations cannot be nested and contain attributes, but allow embedded values in element names.

## Usage

You can install it via npm:

```bash
npm install @emmetio/css-abbreviation
```

Then add it into your project:

```js
import parse from '@emmetio/css-abbreviation';

const props = parse('p10+poa');
/* [{
name: 'p',
value: [{ type: 'CSSValue', value: [...] }],
important: false
}, {
name: 'poa',
value: [],
important: false
}] */
```
The returned result is an array of `CSSProperty` items: a node with name and values.

## Abbreviation syntax

Emmet stylesheet abbreviation element may start with name and followed by values, optionally chained with `-` delimiter. In most cases, actual CSS properties doesn’t have numbers in their names (or at least they are not used in abbreviation shortcuts) so a number right after alpha characters is considered as *embedded value*, as well as colors starting with `#` character: `p10`, `bg#fc0` etc. If implicit name/value boundary can’t be identified, you should use `-` as value separator: `m-a`, `p10-20` etc.

### Operators

Since CSS properties can’t be nested, the only available operator is `+`.
4 changes: 4 additions & 0 deletions test/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "../tsconfig",
"include": ["./*.ts"]
}

0 comments on commit 35a9100

Please sign in to comment.