forked from antonmedv/fx
-
Notifications
You must be signed in to change notification settings - Fork 1
/
print.js
113 lines (91 loc) · 3.11 KB
/
print.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
'use strict'
const indent = require('indent-string')
const config = require('./config')
function format(value, style, highlightStyle, regexp, transform = x => x) {
if (!regexp) {
return style(transform(value))
}
const marked = value
.replace(regexp, s => '<highlight>' + s + '<highlight>')
return transform(marked)
.split(/<highlight>/g)
.map((s, i) => i % 2 !== 0 ? highlightStyle(s) : style(s))
.join('')
}
function print(input, options = {}) {
const {expanded, highlight, currentPath} = options
const index = new Map()
let row = 0
function doPrint(v, path = '') {
index.set(row, path)
// Code for highlighting parts become cumbersome.
// Maybe we should refactor this part.
const highlightStyle = (currentPath === path) ? config.highlightCurrent : config.highlight
const formatStyle = (v, style) => format(JSON.stringify(v), style, highlightStyle, highlight)
const formatText = (v, style, path) => {
const highlightStyle = (currentPath === path) ? config.highlightCurrent : config.highlight
return format(v, style, highlightStyle, highlight, JSON.stringify)
}
const eol = () => {
row++
return '\n'
}
if (typeof v === 'undefined') {
return void 0
}
if (v === null) {
return formatStyle(v, config.null)
}
if (typeof v === 'number' && Number.isFinite(v)) {
return formatStyle(v, config.number)
}
if (typeof v === 'boolean') {
return formatStyle(v, config.boolean)
}
if (typeof v === 'string') {
return formatText(v, config.string, path)
}
if (Array.isArray(v)) {
let output = config.bracket('[')
const len = v.length
if (len > 0) {
if (expanded && !expanded.has(path)) {
output += '\u2026'
} else {
output += eol()
let i = 0
for (let item of v) {
const value = typeof item === 'undefined' ? null : item // JSON.stringify compatibility
output += indent(doPrint(value, path + '[' + i + ']'), config.space)
output += i++ < len - 1 ? config.comma(',') : ''
output += eol()
}
}
}
return output + config.bracket(']')
}
if (typeof v === 'object' && v.constructor === Object) {
let output = config.bracket('{')
const entries = Object.entries(v).filter(([key, value]) => typeof value !== 'undefined') // JSON.stringify compatibility
const len = entries.length
if (len > 0) {
if (expanded && !expanded.has(path)) {
output += '\u2026'
} else {
output += eol()
let i = 0
for (let [key, value] of entries) {
const part = formatText(key, config.key, path + '.' + key) + config.colon(':') + ' ' + doPrint(value, path + '.' + key)
output += indent(part, config.space)
output += i++ < len - 1 ? config.comma(',') : ''
output += eol()
}
}
}
return output + config.bracket('}')
}
return JSON.stringify(v, null, config.space)
}
return [doPrint(input), index]
}
module.exports = print