| 105 | } |
| 106 | |
| 107 | QString TemplateRenderer::render(const QString& content, const QString& name) |
| 108 | { |
| 109 | Q_D(TemplateRenderer); |
| 110 | |
| 111 | Template t = d->engine->newTemplate(content, name); |
| 112 | |
| 113 | QString output; |
| 114 | QTextStream textStream(&output); |
| 115 | NoEscapeStream stream(&textStream); |
| 116 | t->render(&stream, &d->context); |
| 117 | |
| 118 | if (t->error() != KTextTemplate::NoError) { |
| 119 | d->errorString = t->errorString(); |
| 120 | } else { |
| 121 | d->errorString.clear(); |
| 122 | } |
| 123 | |
| 124 | if (d->emptyLinesPolicy == TrimEmptyLines && output.contains(QLatin1Char('\n'))) { |
| 125 | QStringList lines = output.split(QLatin1Char('\n'), Qt::KeepEmptyParts); |
| 126 | QMutableStringListIterator it(lines); |
| 127 | |
| 128 | // Remove empty lines from the start of the document |
| 129 | while (it.hasNext()) { |
| 130 | if (it.next().trimmed().isEmpty()) { |
| 131 | it.remove(); |
| 132 | } else |
| 133 | { |
| 134 | break; |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | // Remove single empty lines |
| 139 | it.toFront(); |
| 140 | bool prePreviousEmpty = false; |
| 141 | bool previousEmpty = false; |
| 142 | while (it.hasNext()) { |
| 143 | bool currentEmpty = it.peekNext().trimmed().isEmpty(); |
| 144 | if (!prePreviousEmpty && previousEmpty && !currentEmpty) { |
| 145 | it.remove(); |
| 146 | } |
| 147 | prePreviousEmpty = previousEmpty; |
| 148 | previousEmpty = currentEmpty; |
| 149 | it.next(); |
| 150 | } |
| 151 | |
| 152 | // Compress multiple empty lines |
| 153 | it.toFront(); |
| 154 | previousEmpty = false; |
| 155 | while (it.hasNext()) { |
| 156 | bool currentEmpty = it.next().trimmed().isEmpty(); |
| 157 | if (currentEmpty && previousEmpty) { |
| 158 | it.remove(); |
| 159 | } |
| 160 | previousEmpty = currentEmpty; |
| 161 | } |
| 162 | |
| 163 | // Remove empty lines from the end |
| 164 | it.toBack(); |