| 173 | } |
| 174 | |
| 175 | write(paragraph) { |
| 176 | const lines = paragraph.lines; |
| 177 | const breakAfter = []; |
| 178 | let i; |
| 179 | |
| 180 | for (i = 0; i < lines.length - 1; i++) { |
| 181 | const line = lines[i]; |
| 182 | |
| 183 | // When a line is really short, the line was probably kept separate for a |
| 184 | // reason. |
| 185 | if (line.length < 50) { |
| 186 | // If the first word on the next line really didn't fit after the line, |
| 187 | // it probably was just ordinary wrapping after all. |
| 188 | const nextFirstWordLength = lines[i + 1].replace(/\s.*$/, '').length; |
| 189 | if (line.length + nextFirstWordLength < 60) { |
| 190 | breakAfter[i] = true; |
| 191 | } |
| 192 | } |
| 193 | } |
| 194 | |
| 195 | for (i = 0; i < lines.length - 1;) { |
| 196 | if (!breakAfter[i]) { |
| 197 | lines[i] += ` ${lines.splice(i + 1, 1)[0]}`; |
| 198 | } else { |
| 199 | i++; |
| 200 | } |
| 201 | } |
| 202 | |
| 203 | for (i = 0; i < lines.length; i++) { |
| 204 | // Replace multiple whitespace characters by a single one, and strip |
| 205 | // trailing whitespace. |
| 206 | lines[i] = lines[i].replace(/\s+/g, ' ').replace(/\s+$/, ''); |
| 207 | } |
| 208 | |
| 209 | this.emit('data', paragraph); |
| 210 | } |
| 211 | |
| 212 | end(data) { |
| 213 | if (data) |