├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── bin └── ansi2html ├── lib └── index.js ├── package.json └── test └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.6 4 | - 0.8 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2011 by Isaac Wolkerstorfer 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ansi2html.js [![build status](https://secure.travis-ci.org/agnoster/ansi2html.png?branch=master)](http://travis-ci.org/agnoster/ansi2html) 2 | 3 | 4 | Convert text with ANSI escape sequences to styled HTML. 5 | 6 | ## Example 7 | 8 | ``` 9 | test[1mBold[32mGreen[31mRed[0mNone 10 | ``` 11 | 12 | becomes 13 | 14 | ```html 15 | testBoldGreenRedNone 16 | ``` 17 | 18 | ## Usage 19 | 20 | In Node.js: 21 | 22 | ```js 23 | var ansi2html = require('ansi2html') 24 | 25 | console.log(ansi2html("test[1mBold")) 26 | ``` 27 | 28 | In the browser: 29 | 30 | ```js 31 |

32 | 
33 | 
36 | ```
37 | 
38 | In the terminal:
39 | 
40 | ```bash
41 | git log --color | ansi2html > result.html
42 | ```
43 | 
44 | That's right, ansi2html.js works in Node *and* in the browser, in more or less the same way.
45 | 
46 | ## Supported
47 | 
48 | * bold
49 | * underline
50 | * foreground & background color
51 | 
52 | ## MIT License
53 | 
54 | Copyright (C) 2011 by Isaac Wolkerstorfer
55 | 
56 | Permission is hereby granted, free of charge, to any person obtaining a copy
57 | of this software and associated documentation files (the "Software"), to deal
58 | in the Software without restriction, including without limitation the rights
59 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
60 | copies of the Software, and to permit persons to whom the Software is
61 | furnished to do so, subject to the following conditions:
62 | 
63 | The above copyright notice and this permission notice shall be included in
64 | all copies or substantial portions of the Software.
65 | 
66 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
67 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
68 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
69 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
70 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
71 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
72 | THE SOFTWARE.
73 | 
74 | 


--------------------------------------------------------------------------------
/bin/ansi2html:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/env node
 2 | var data = ''
 3 |   , ansi2html = require('../lib/index.js')
 4 | 
 5 | process.stdin.on('data', function(chunk) {
 6 |   data += chunk
 7 | })
 8 | 
 9 | process.stdin.on('end', function() {
10 |   // strip escape characters (e.g. git log --color | ansi2html)
11 |   console.log(ansi2html(data.replace(/\u001B/g, '')))
12 | })
13 | 
14 | process.stdin.resume()
15 | 


--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
  1 | (function(){
  2 |   function declare(module_name, exports) {
  3 |     if (typeof module != 'undefined') module.exports = exports
  4 |     else window[module_name] = exports
  5 |   }
  6 | 
  7 |   function ansi2html(str) {
  8 |     var props = {}
  9 |       , open = false
 10 | 
 11 |     var stylemap =
 12 |       { bold: "font-weight"
 13 |       , underline: "text-decoration"
 14 |       , color: "color"
 15 |       , background: "background"
 16 |       }
 17 | 
 18 |     function style() {
 19 |       var key, val, style = []
 20 |       for (var key in props) {
 21 |         val = props[key]
 22 |         if (!val) continue
 23 |         if (val == true) {
 24 |           style.push(stylemap[key] + ':' + key)
 25 |         } else {
 26 |           style.push(stylemap[key] + ':' + val)
 27 |         }
 28 |       }
 29 |       return style.join(';')
 30 |     }
 31 | 
 32 | 
 33 |     function tag(code) {
 34 |       var i
 35 |         , tag = ''
 36 |         , n = ansi2html.table[code]
 37 | 
 38 |       if (open) tag += ''
 39 |       open = false
 40 | 
 41 |       if (n) {
 42 |         for (i in n) props[i] = n[i]
 43 |         tag += ''
 44 |         open = true
 45 |       } else {
 46 |         props = {}
 47 |       }
 48 | 
 49 |       return tag
 50 |     }
 51 | 
 52 |     return str.replace(/\[(\d+;)?(\d+)*m/g, function(match, b1, b2) {
 53 |       var i, code, res = ''
 54 |       if (b2 == '' || b2 == null) b2 = '0'
 55 |       for (i = 1; i < arguments.length - 2; i++) {
 56 |         if (!arguments[i]) continue
 57 |         code = parseInt(arguments[i])
 58 |         res += tag(code)
 59 |       }
 60 |       return res
 61 |     }) + tag()
 62 |   }
 63 | 
 64 |   /* not implemented:
 65 |    *   italic
 66 |    *   blink
 67 |    *   invert
 68 |    *   strikethrough
 69 |    */
 70 |   ansi2html.table =
 71 |   { 0: null
 72 |   , 1: { bold: true }
 73 |   , 3: { italic: true }
 74 |   , 4: { underline: true }
 75 |   , 5: { blink: true }
 76 |   , 6: { blink: true }
 77 |   , 7: { invert: true }
 78 |   , 9: { strikethrough: true }
 79 |   , 23: { italic: false }
 80 |   , 24: { underline: false }
 81 |   , 25: { blink: false }
 82 |   , 27: { invert: false }
 83 |   , 29: { strikethrough: false }
 84 |   , 30: { color: 'black' }
 85 |   , 31: { color: 'red' }
 86 |   , 32: { color: 'green' }
 87 |   , 33: { color: 'yellow' }
 88 |   , 34: { color: 'blue' }
 89 |   , 35: { color: 'magenta' }
 90 |   , 36: { color: 'cyan' }
 91 |   , 37: { color: 'white' }
 92 |   , 39: { color: null }
 93 |   , 40: { background: 'black' }
 94 |   , 41: { background: 'red' }
 95 |   , 42: { background: 'green' }
 96 |   , 43: { background: 'yellow' }
 97 |   , 44: { background: 'blue' }
 98 |   , 45: { background: 'magenta' }
 99 |   , 46: { background: 'cyan' }
100 |   , 47: { background: 'white' }
101 |   , 49: { background: null }
102 |   }
103 | 
104 |   declare('ansi2html', ansi2html)
105 | })()
106 | 
107 | 


--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "author": "Isaac Wolkerstorfer  (http://agnoster.net/)",
 3 |   "name": "ansi2html",
 4 |   "description": "Convert text with ANSI escape sequences to HTML markup",
 5 |   "version": "0.0.1",
 6 |   "homepage": "https://github.com/agnoster/ansi2html",
 7 |   "bin": {
 8 |     "ansi2html": "./bin/ansi2html"
 9 |   },
10 |   "repository": {
11 |     "url": ""
12 |   },
13 |   "main": "./lib/",
14 |   "engines": {
15 |     "node": ">0.4"
16 |   },
17 |   "dependencies": {},
18 |   "devDependencies": {
19 |     "vows": "~0.5.8"
20 |   },
21 |   "scripts": {
22 |     "test": "./node_modules/vows/bin/vows test/* --spec"
23 |   }
24 | }
25 | 


--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
 1 | var ansi2html = require('../lib/')
 2 |   , vows = require('vows')
 3 |   , assert = require('assert')
 4 | 
 5 | function makeBatchFromTestCases(testCases) {
 6 |   function makeTest(input, expected) {
 7 |     var test = { topic: function() { return ansi2html(input) } }
 8 |     test['we get "' + expected + '"'] = function(topic) { assert.equal(topic, expected) }
 9 |     return test
10 |   }
11 | 
12 |   var batch = {}
13 |   for (var key in testCases) {
14 |     if (!testCases.hasOwnProperty(key)) continue
15 |     batch['When encoding "' + key + '"'] = makeTest(key, testCases[key])
16 |   }
17 |   return batch
18 | }
19 | 
20 | var suite = vows.describe('ansi2html')
21 | suite.addBatch(makeBatchFromTestCases(
22 | { 'testString': 'testString'
23 | , 'test[0mString': 'testString'
24 | , 'test[32mString': 'testString'
25 | , 'test[1mBold[32mGreen[31mRed[0mNone': 'testBoldGreenRedNone'
26 | , 'test[31mRed[1mBold[39mString': 'testRedBoldString'
27 | , 'test[42mGreenBG': 'testGreenBG'
28 | , 'test[32mString[0mNone': 'testStringNone'
29 | , 'test[32mString[mNone': 'testStringNone'
30 | }))
31 | suite.export(module)
32 | 
33 | 


--------------------------------------------------------------------------------