├── .gitattributes ├── .gitignore ├── example ├── index.js ├── examples │ ├── preact.js │ ├── golang.go │ ├── vue.js │ ├── python.py │ └── next.js └── App.vue ├── test └── index.test.js ├── .editorconfig ├── circle.yml ├── LICENSE ├── src └── index.js ├── package.json └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | *.log 4 | 5 | /dist 6 | /dist-example 7 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | new Vue({ 5 | el: '#app', 6 | render: h => h(App) 7 | }) 8 | -------------------------------------------------------------------------------- /test/index.test.js: -------------------------------------------------------------------------------- 1 | import hanabi from '../src' 2 | 3 | test('main', () => { 4 | const out = hanabi(`co`) 5 | expect(out).toBe('co') 6 | }) 7 | -------------------------------------------------------------------------------- /example/examples/preact.js: -------------------------------------------------------------------------------- 1 | import { h, render } from 'preact'; 2 | 3 | render(( 4 |
5 | Hello, world! 6 | 7 |
8 | ), document.body); 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | node: 3 | version: 7 4 | environment: 5 | PATH: "${PATH}:${HOME}/${CIRCLE_PROJECT_REPONAME}/node_modules/.bin" 6 | 7 | dependencies: 8 | override: 9 | - yarn 10 | cache_directories: 11 | - ~/.cache/yarn 12 | 13 | test: 14 | override: 15 | - yarn test 16 | -------------------------------------------------------------------------------- /example/examples/golang.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // fib returns a function that returns 6 | // successive Fibonacci numbers. 7 | func fib() func() int { 8 | a, b := 0, 1 9 | return func() int { 10 | a, b = b, a+b 11 | return a 12 | } 13 | } 14 | 15 | func main() { 16 | f := fib() 17 | // Function calls are evaluated left-to-right. 18 | fmt.Println(f(), f(), f(), f(), f()) 19 | } 20 | -------------------------------------------------------------------------------- /example/examples/vue.js: -------------------------------------------------------------------------------- 1 | 6 | 7 | 25 | 26 | 32 | -------------------------------------------------------------------------------- /example/examples/python.py: -------------------------------------------------------------------------------- 1 | from bottle import route, install, template 2 | from bottle_sqlite import SQLitePlugin 3 | 4 | install(SQLitePlugin(dbfile='/tmp/test.db')) 5 | 6 | @route('/show/') 7 | def show(db, post_id): 8 | c = db.execute('SELECT title, content FROM posts WHERE id = ?', (post_id,)) 9 | row = c.fetchone() 10 | return template('show_post', title=row['title'], text=row['content']) 11 | 12 | @route('/contact') 13 | def contact_page(): 14 | ''' This callback does not need a db connection. Because the 'db' 15 | keyword argument is missing, the sqlite plugin ignores this callback 16 | completely. ''' 17 | return template('contact') 18 | -------------------------------------------------------------------------------- /example/examples/next.js: -------------------------------------------------------------------------------- 1 | const { createServer } = require('http') 2 | const { parse } = require('url') 3 | const next = require('next') 4 | 5 | const dev = process.env.NODE_ENV !== 'production' 6 | const app = next({ dev }) 7 | const handle = app.getRequestHandler() 8 | 9 | app.prepare().then(() => { 10 | createServer((req, res) => { 11 | const parsedUrl = parse(req.url, true) 12 | const { pathname, query } = parsedUrl 13 | 14 | if (pathname === '/a') { 15 | app.render(req, res, '/b', query) 16 | } else if (pathname === '/b') { 17 | app.render(req, res, '/a', query) 18 | } else { 19 | handle(req, res, parsedUrl) 20 | } 21 | }) 22 | .listen(3000, (err) => { 23 | if (err) throw err 24 | console.log('> Ready on http://localhost:3000') 25 | }) 26 | }) 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) egoist <0x142857@gmail.com> (https://egoistian.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import jsCommentRe from 'comment-regex' 2 | 3 | const defaultColors = ['23AC69', '91C132', 'F19726', 'E8552D', '1AAB8E', 'E1147F', '2980C1', '1BA1E6', '9FA0A0', 'F19726', 'E30B20', 'E30B20', 'A3338B'] 4 | 5 | export default function (input, { 6 | colors = defaultColors 7 | } = {}) { 8 | let index = 0 9 | const cache = {} 10 | const wordRe = /[\u4E00-\u9FFF\u3400-\u4dbf\uf900-\ufaff\u3040-\u309f\uac00-\ud7af\u0400-\u04FF]+|\w+/ 11 | const leftAngleRe = / { 16 | if (cm) { 17 | return toComment(cm) 18 | } 19 | 20 | if (word === '<') { 21 | return '<' 22 | } 23 | let color 24 | if (cache[word]) { 25 | color = cache[word] 26 | } else { 27 | color = colors[index] 28 | cache[word] = color 29 | } 30 | 31 | const out = `${word}` 32 | index = ++index % colors.length 33 | return out 34 | }) 35 | } 36 | 37 | function toComment(cm) { 38 | return `${cm}` 39 | } 40 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hanabi", 3 | "productionName": "Hanabi: Highlight any code, in a colorful way", 4 | "version": "0.4.0", 5 | "description": "Highlight any code, in a colorful way.", 6 | "repository": { 7 | "url": "egoist/hanabi", 8 | "type": "git" 9 | }, 10 | "main": "dist/hanabi.js", 11 | "files": [ 12 | "dist" 13 | ], 14 | "scripts": { 15 | "test": "jest && npm run lint && npm run build", 16 | "lint": "xo", 17 | "build": "bili --format umd --module-name hanabi --compress", 18 | "example": "vbuild example/index.js -d", 19 | "build:example": "vbuild example/index.js --dist dist-example", 20 | "deploy": "npm run build:example && gh-pages -d dist-example" 21 | }, 22 | "author": "egoist <0x142857@gmail.com>", 23 | "license": "MIT", 24 | "jest": { 25 | "testEnvironment": "node" 26 | }, 27 | "babel": { 28 | "babelrc": false, 29 | "env": { 30 | "test": { 31 | "presets": [ 32 | "es2015" 33 | ] 34 | } 35 | } 36 | }, 37 | "devDependencies": { 38 | "babel-preset-es2015": "^6.24.0", 39 | "bili": "^0.14.0", 40 | "gh-pages": "^0.12.0", 41 | "jest-cli": "^19.0.2", 42 | "raw-loader": "^0.5.1", 43 | "vbuild": "^6.24.3", 44 | "xo": "^0.17.1" 45 | }, 46 | "xo": { 47 | "space": 2, 48 | "semicolon": false, 49 | "envs": [ 50 | "jest" 51 | ], 52 | "ignores": [ 53 | "example/**" 54 | ] 55 | }, 56 | "dependencies": { 57 | "comment-regex": "^1.0.0" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hanabi 2 | 3 | [![NPM version](https://img.shields.io/npm/v/hanabi.svg?style=flat)](https://npmjs.com/package/hanabi) [![NPM downloads](https://img.shields.io/npm/dm/hanabi.svg?style=flat)](https://npmjs.com/package/hanabi) [![Build Status](https://img.shields.io/circleci/project/egoist/hanabi/master.svg?style=flat)](https://circleci.com/gh/egoist/hanabi) [![donate](https://img.shields.io/badge/$-donate-ff69b4.svg?maxAge=2592000&style=flat)](https://github.com/egoist/donate) 4 | 5 | How does it look like? Hmmm: 6 | 7 | 2017-02-23 6 07 22 8 | 9 | ## Install 10 | 11 | ```bash 12 | yarn add hanabi 13 | ``` 14 | 15 | CDN: https://unpkg.com/hanabi/dist/ 16 | 17 | ## Usage 18 | 19 | ```js 20 | const hanabi = require("hanabi"); 21 | 22 | hanabi(code); 23 | ``` 24 | 25 | Demo: https://hanabi.egoist.dev/ 26 | 27 | ## Contributing 28 | 29 | 1. Fork it! 30 | 2. Create your feature branch: `git checkout -b my-new-feature` 31 | 3. Commit your changes: `git commit -am 'Add some feature'` 32 | 4. Push to the branch: `git push origin my-new-feature` 33 | 5. Submit a pull request :D 34 | 35 | ## Author 36 | 37 | **hanabi** © [egoist](https://github.com/egoist), Released under the [MIT](./LICENSE) License.
38 | Authored and maintained by egoist with help from contributors ([list](https://github.com/egoist/hanabi/contributors)). 39 | 40 | > [egoist.dev](https://egoist.dev) · GitHub [@egoist](https://github.com/egoist) · Twitter [@\localhost_5173](https://twitter.com/localhost_5173) 41 | -------------------------------------------------------------------------------- /example/App.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 59 | 60 | 66 | --------------------------------------------------------------------------------