a/src/query/plaintorich.cpp b/src/query/plaintorich.cpp
...
...
21
#include <list>
21
#include <list>
22
#include <set>
22
#include <set>
23
#include <vector>
23
#include <vector>
24
#include <map>
24
#include <map>
25
#include <algorithm>
25
#include <algorithm>
26
#include <regex>
26
27
27
using std::vector;
28
using std::vector;
28
using std::list;
29
using std::list;
29
using std::pair;
30
using std::pair;
30
using std::set;
31
using std::set;
...
...
147
              }
148
              }
148
        );
149
        );
149
    return true;
150
    return true;
150
}
151
}
151
152
153
// Replace HTTP(s) urls in text/plain with proper HTML anchors so that
154
// they become clickable in the preview. We don't make a lot of effort
155
// for validating, or catching things which are probably urls but miss
156
// a scheme (e.g. www.xxx.com/index.html), because complicated.
157
static const string urlRE = "(https?://[[:alnum:]~_/.%?&=,#@]+)[[:space:]|]";
158
static std::regex url_re(urlRE);
159
static string activate_urls(const string& in)
160
{
161
    return std::regex_replace(in, url_re, "<a href=\"$1\">$1</a>");
162
}
152
163
153
// Fix result text for display inside the gui text window.
164
// Fix result text for display inside the gui text window.
154
//
165
//
155
// We call overridden functions to output header data, beginnings and ends of
166
// We call overridden functions to output header data, beginnings and ends of
156
// matches etc.
167
// matches etc.
...
...
184
    out.push_back("");
195
    out.push_back("");
185
    list<string>::iterator olit = out.begin();
196
    list<string>::iterator olit = out.begin();
186
197
187
    // Rich text output
198
    // Rich text output
188
    *olit = header();
199
    *olit = header();
189
200
    
190
    // No term matches. Happens, for example on a snippet selected for
201
    // No term matches. Happens, for example on a snippet selected for
191
    // a term match when we are actually looking for a group match
202
    // a term match when we are actually looking for a group match
192
    // (the snippet generator does this...).
203
    // (the snippet generator does this...).
193
    if (splitter.m_tboffs.empty()) {
204
    if (splitter.m_tboffs.empty()) {
194
        LOGDEB1("plaintorich: no term matches\n");
205
        LOGDEB1("plaintorich: no term matches\n");
...
...
286
            // Maybe end this chunk, begin next. Don't do it on html
297
            // Maybe end this chunk, begin next. Don't do it on html
287
            // there is just no way to do it right (qtextedit cant grok
298
            // there is just no way to do it right (qtextedit cant grok
288
            // chunks cut in the middle of <a></a> for example).
299
            // chunks cut in the middle of <a></a> for example).
289
            if (!m_inputhtml && !inrcltag && 
300
            if (!m_inputhtml && !inrcltag && 
290
                olit->size() > (unsigned int)chunksize) {
301
                olit->size() > (unsigned int)chunksize) {
302
                if (m_activatelinks) {
303
                    *olit = activate_urls(*olit);
304
                }
291
                out.push_back(string(startChunk()));
305
                out.push_back(string(startChunk()));
292
                olit++;
306
                olit++;
293
            }
307
            }
294
        }
308
        }
295
309
...
...
363
        fprintf(fp, "ENDOFPLAINTORICHOUTPUT\n");
377
        fprintf(fp, "ENDOFPLAINTORICHOUTPUT\n");
364
        fclose(fp);
378
        fclose(fp);
365
    }
379
    }
366
#endif
380
#endif
367
    LOGDEB2("plaintorich: done " << chron.millis() << " mS\n");
381
    LOGDEB2("plaintorich: done " << chron.millis() << " mS\n");
382
    if (!m_inputhtml && m_activatelinks) {
383
        out.back() = activate_urls(out.back());
384
    }
368
    return ret;
385
    return ret;
369
}
386
}