Skip to content
This repository has been archived by the owner on Aug 23, 2019. It is now read-only.

Commit

Permalink
🔥 Working implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
sergeche committed Jan 10, 2017
1 parent 09b0e78 commit 322de27
Show file tree
Hide file tree
Showing 9 changed files with 252 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"plugins": ["transform-es2015-modules-commonjs"]
}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@ jspm_packages

# Optional REPL history
.node_repl_history
/dist
.DS_Store
8 changes: 8 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
npm-debug.log*
node_modules
jspm_packages
.npm
/.*
/*.*
/test
/lib
149 changes: 149 additions & 0 deletions html.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
'use strict';

import parse from '@emmetio/abbreviation';
import snippets from '@emmetio/snippets';
import createRegistry from '@emmetio/snippets-registry';
import resolveSnippets from '@emmetio/html-snippets-resolver';
import Profile from '@emmetio/output-profile';
import transform from '@emmetio/html-transform';
import resolveVariables from '@emmetio/variable-resolver';
import format from '@emmetio/markup-formatters';

const defaultOptions = {
/**
* Abbreviation output syntax
* @type {String}
*/
syntax: 'html',

/**
* Field/tabstop generator for editor. Most editors support TextMate-style
* fields: ${0} or ${1:item}. So for TextMate-style fields this function
* will look like this:
* @example
* (index, placeholder) => `\${${index}{placeholder ? ':' + placeholder : ''}}`
*
* @param {Number} index Placeholder index. Fields with the same indices
* should be linked
* @param {String} [placeholder] Field placeholder
* @return {String}
*/
field: (index, placeholder) => placeholder || '',

/**
* Predefined snippets registry
* @type {SnippetsRegistry}
*/
registry: null,

/**
* Insert given text string(s) into expanded abbreviation
* If array of strings is given, the implicitly repeated element (e.g. `li*`)
* will be repeated by the amount of items in array
* @type {String|String[]}
*/
insertText: null,

/**
* Either predefined output profile or options for output profile. Used for
* abbreviation output
* @type {Profile|Object}
*/
profile: null,

/**
* Custom variables for variable resolver
* @see @emmetio/variable-resolver
* @type {Object}
*/
variables: {},

/**
* Custom predefined snippets for abbreviation. The expanded abbreviation
* will try to match given snippets that may contain custom elements,
* predefined attributes etc.
* May also contain array of items: either snippets (Object) or references
* to default syntax snippets (String; the key in default snippets hash)
* @see @emmetio/snippets
* @type {Object}
*/
snippets: {},

/**
* Hash of additional transformations that should be applied to expanded
* abbreviation, like BEM or JSX. Since these transformations introduce
* side-effect, they are disabled by default and should be enabled by
* providing a transform name as a key and transform options as value:
* @example
* {
* bem: {element: '--'},
* jsx: true // no options, just enable transform
* }
* @see @emmetio/html-transform/lib/addons
* @type {Object}
*/
addons: null,

/**
* Additional options for syntax formatter
* @see @emmetio/markup-formatters
* @type {Object}
*/
format: null
};

const defaultVariables = {
lang: 'en',
locale: 'en-US',
charset: 'UTF-8'
};

export default function expand(abbr, options) {
options = Object.assign({}, defaultOptions, options);
options.variables = Object.assign({}, defaultVariables, options.variables);

const registry = createSnippetsRegistry(options);

const tree = parse(abbr)
.use(transform, options.insertText, options.addons)
.use(resolveSnippets, registry)
.use(resolveVariables, options.variables);

return format(tree, createProfile(options), options.syntax, options.format);
}

/**
* Creates snippets registry and fills it with data
* @param {Object} options
* @return {SnippetsRegistry}
*/
function createSnippetsRegistry(options) {
if (options.registry) {
return options.registry;
}

const registrySnippets = [snippets[options.syntax]];

if (Array.isArray(options.snippets)) {
options.snippets.forEach(item => {
// if array item is a string, treat it as a reference to globally
// defined snippets
registrySnippets.push(typeof item === 'string' ? snippets[item] : item)
});
} else if (typeof options.snippets === 'object') {
registrySnippets.push(options.snippets);
}

return createRegistry(registrySnippets.filter(Boolean));
}

/**
* Creates output profile from given options
* @param {Object} options
* @return {Profile}
*/
function createProfile(options) {
return options.profile instanceof Profile
? options.profile
: new Profile(options.profile);
}
9 changes: 9 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use strict';

import html from './html';

// XXX will add CSS support later

export default function(abbr, options) {
return html(abbr, options);
}
47 changes: 47 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "@emmetio/expand-abbreviation",
"version": "0.0.1",
"description": "Reference implementation of Emmet abbreviation expander",
"main": "dist/expand.cjs.js",
"jsnext:main": "dist/expand.es.js",
"dependencies": {
"@emmetio/abbreviation": "^0.4.6",
"@emmetio/html-snippets-resolver": "^0.1.0",
"@emmetio/html-transform": "^0.2.0",
"@emmetio/markup-formatters": "^0.2.1",
"@emmetio/output-profile": "^0.1.4",
"@emmetio/snippets": "^0.1.0",
"@emmetio/snippets-registry": "^0.1.1",
"@emmetio/variable-resolver": "^0.1.1"
},
"devDependencies": {
"babel-plugin-transform-es2015-modules-commonjs": "^6.18.0",
"babel-register": "^6.18.0",
"mocha": "^3.2.0",
"rollup": "^0.41.1",
"rollup-plugin-node-resolve": "^2.0.0"
},
"scripts": {
"test": "mocha",
"build": "npm run build:cjs && npm run build:es && npm run build:es:full",
"build:cjs": "rollup -c -o dist/expand.cjs.js -f cjs ./index.js",
"build:es": "rollup -c -o dist/expand.es.js -f es ./index.js",
"build:es:full": "rollup -c ./rollup-full.config.js -o dist/expand-full.es.js ./index.js",
"prepublish": "npm run test && npm run build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/emmetio/expand-abbreviation.git"
},
"keywords": [
"emmet",
"abbreviation",
"expand"
],
"author": "Sergey Chikuyonok <[email protected]>",
"license": "MIT",
"bugs": {
"url": "https://github.com/emmetio/expand-abbreviation/issues"
},
"homepage": "https://github.com/emmetio/expand-abbreviation#readme"
}
9 changes: 9 additions & 0 deletions rollup-full.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import nodeResolve from 'rollup-plugin-node-resolve';

export default {
entry: './index.js',
format: 'es',
plugins: [nodeResolve({
jsnext: true
})]
};
14 changes: 14 additions & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default {
entry: './index.js',
format: 'es',
external: [
'@emmetio/abbreviation',
'@emmetio/snippets',
'@emmetio/snippets-registry',
'@emmetio/html-snippets-resolver',
'@emmetio/output-profile',
'@emmetio/html-transform',
'@emmetio/variable-resolver',
'@emmetio/markup-formatters'
]
};
11 changes: 11 additions & 0 deletions test/expand.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
'use strict';

const assert = require('assert');
require('babel-register');
const expand = require('../html').default;

describe('HTML expand', () => {
it('basic', () => {
console.log(expand('ul>.item$*2'));
});
});

0 comments on commit 322de27

Please sign in to comment.