source: node_modules/gauge/lib/render-template.js@ 62b2964

finki-main main
Last change on this file since 62b2964 was 81bc7da, checked in by Klimentina Efremova <klimentina08642@…>, 3 months ago

Initial commit

  • Property mode set to 100644
File size: 5.8 KB
RevLine 
[81bc7da]1'use strict'
2var align = require('wide-align')
3var validate = require('aproba')
4var wideTruncate = require('./wide-truncate')
5var error = require('./error')
6var TemplateItem = require('./template-item')
7
8function renderValueWithValues (values) {
9 return function (item) {
10 return renderValue(item, values)
11 }
12}
13
14var renderTemplate = module.exports = function (width, template, values) {
15 var items = prepareItems(width, template, values)
16 var rendered = items.map(renderValueWithValues(values)).join('')
17 return align.left(wideTruncate(rendered, width), width)
18}
19
20function preType (item) {
21 var cappedTypeName = item.type[0].toUpperCase() + item.type.slice(1)
22 return 'pre' + cappedTypeName
23}
24
25function postType (item) {
26 var cappedTypeName = item.type[0].toUpperCase() + item.type.slice(1)
27 return 'post' + cappedTypeName
28}
29
30function hasPreOrPost (item, values) {
31 if (!item.type) {
32 return
33 }
34 return values[preType(item)] || values[postType(item)]
35}
36
37function generatePreAndPost (baseItem, parentValues) {
38 var item = Object.assign({}, baseItem)
39 var values = Object.create(parentValues)
40 var template = []
41 var pre = preType(item)
42 var post = postType(item)
43 if (values[pre]) {
44 template.push({ value: values[pre] })
45 values[pre] = null
46 }
47 item.minLength = null
48 item.length = null
49 item.maxLength = null
50 template.push(item)
51 values[item.type] = values[item.type]
52 if (values[post]) {
53 template.push({ value: values[post] })
54 values[post] = null
55 }
56 return function ($1, $2, length) {
57 return renderTemplate(length, template, values)
58 }
59}
60
61function prepareItems (width, template, values) {
62 function cloneAndObjectify (item, index, arr) {
63 var cloned = new TemplateItem(item, width)
64 var type = cloned.type
65 if (cloned.value == null) {
66 if (!(type in values)) {
67 if (cloned.default == null) {
68 throw new error.MissingTemplateValue(cloned, values)
69 } else {
70 cloned.value = cloned.default
71 }
72 } else {
73 cloned.value = values[type]
74 }
75 }
76 if (cloned.value == null || cloned.value === '') {
77 return null
78 }
79 cloned.index = index
80 cloned.first = index === 0
81 cloned.last = index === arr.length - 1
82 if (hasPreOrPost(cloned, values)) {
83 cloned.value = generatePreAndPost(cloned, values)
84 }
85 return cloned
86 }
87
88 var output = template.map(cloneAndObjectify).filter(function (item) {
89 return item != null
90 })
91
92 var remainingSpace = width
93 var variableCount = output.length
94
95 function consumeSpace (length) {
96 if (length > remainingSpace) {
97 length = remainingSpace
98 }
99 remainingSpace -= length
100 }
101
102 function finishSizing (item, length) {
103 if (item.finished) {
104 throw new error.Internal('Tried to finish template item that was already finished')
105 }
106 if (length === Infinity) {
107 throw new error.Internal('Length of template item cannot be infinity')
108 }
109 if (length != null) {
110 item.length = length
111 }
112 item.minLength = null
113 item.maxLength = null
114 --variableCount
115 item.finished = true
116 if (item.length == null) {
117 item.length = item.getBaseLength()
118 }
119 if (item.length == null) {
120 throw new error.Internal('Finished template items must have a length')
121 }
122 consumeSpace(item.getLength())
123 }
124
125 output.forEach(function (item) {
126 if (!item.kerning) {
127 return
128 }
129 var prevPadRight = item.first ? 0 : output[item.index - 1].padRight
130 if (!item.first && prevPadRight < item.kerning) {
131 item.padLeft = item.kerning - prevPadRight
132 }
133 if (!item.last) {
134 item.padRight = item.kerning
135 }
136 })
137
138 // Finish any that have a fixed (literal or intuited) length
139 output.forEach(function (item) {
140 if (item.getBaseLength() == null) {
141 return
142 }
143 finishSizing(item)
144 })
145
146 var resized = 0
147 var resizing
148 var hunkSize
149 do {
150 resizing = false
151 hunkSize = Math.round(remainingSpace / variableCount)
152 output.forEach(function (item) {
153 if (item.finished) {
154 return
155 }
156 if (!item.maxLength) {
157 return
158 }
159 if (item.getMaxLength() < hunkSize) {
160 finishSizing(item, item.maxLength)
161 resizing = true
162 }
163 })
164 } while (resizing && resized++ < output.length)
165 if (resizing) {
166 throw new error.Internal('Resize loop iterated too many times while determining maxLength')
167 }
168
169 resized = 0
170 do {
171 resizing = false
172 hunkSize = Math.round(remainingSpace / variableCount)
173 output.forEach(function (item) {
174 if (item.finished) {
175 return
176 }
177 if (!item.minLength) {
178 return
179 }
180 if (item.getMinLength() >= hunkSize) {
181 finishSizing(item, item.minLength)
182 resizing = true
183 }
184 })
185 } while (resizing && resized++ < output.length)
186 if (resizing) {
187 throw new error.Internal('Resize loop iterated too many times while determining minLength')
188 }
189
190 hunkSize = Math.round(remainingSpace / variableCount)
191 output.forEach(function (item) {
192 if (item.finished) {
193 return
194 }
195 finishSizing(item, hunkSize)
196 })
197
198 return output
199}
200
201function renderFunction (item, values, length) {
202 validate('OON', arguments)
203 if (item.type) {
204 return item.value(values, values[item.type + 'Theme'] || {}, length)
205 } else {
206 return item.value(values, {}, length)
207 }
208}
209
210function renderValue (item, values) {
211 var length = item.getBaseLength()
212 var value = typeof item.value === 'function' ? renderFunction(item, values, length) : item.value
213 if (value == null || value === '') {
214 return ''
215 }
216 var alignWith = align[item.align] || align.left
217 var leftPadding = item.padLeft ? align.left('', item.padLeft) : ''
218 var rightPadding = item.padRight ? align.right('', item.padRight) : ''
219 var truncated = wideTruncate(String(value), length)
220 var aligned = alignWith(truncated, length)
221 return leftPadding + aligned + rightPadding
222}
Note: See TracBrowser for help on using the repository browser.