1 module nxt.quoting;
2 
3 import nxt.array_traits : isCharArray;
4 
5 Chars[] quotedWords(Chars)(Chars s,
6                            const scope string quoteBeginChar = `"`,
7                            const scope string quoteEndChar = `"`)
8 if (isCharArray!Chars)
9 {
10     typeof(return) words;
11     import std.array : array;
12     import nxt.splitter_ex : splitterASCIIAmong;
13     import std.algorithm : filter;
14     import std.string : indexOf, lastIndexOf;
15     import std.range.primitives : empty;
16     while (!s.empty)
17     {
18         auto quoteBeginI = s.indexOf(quoteBeginChar);
19         if (quoteBeginI >= 0)
20         {
21             auto currI = quoteBeginI;
22 
23             auto prefixBeginI = s[0 .. currI].lastIndexOf(' ');
24             if (prefixBeginI >= 0)
25             {
26                 currI = prefixBeginI + 1;
27             }
28 
29             words ~= s[0 .. currI].splitterASCIIAmong!(' ')
30                                   .filter!(a => !a.empty)
31                                   .array;
32 
33             auto quoteEndI = s[quoteBeginI + 1 .. $].indexOf(quoteEndChar) + quoteBeginI + 1;
34             auto suffixEndI = s[quoteEndI + 1 .. $].indexOf(' ');
35             if (suffixEndI >= 0)
36             {
37                 quoteEndI = quoteEndI + suffixEndI;
38             }
39             words ~= s[currI .. quoteEndI + 1];
40             s = s[quoteEndI + 1 .. $];
41         }
42         else
43         {
44             words ~= s.splitterASCIIAmong!(' ')
45                       .filter!(a => !a.empty)
46                       .array;
47             s = [];
48         }
49     }
50     return words;
51 }
52 
53 ///
54 @safe pure unittest
55 {
56     import std.stdio;
57     import std.algorithm.comparison : equal;
58     const t = `verb:is   noun:"New York" a noun:"big  city"@en `;
59     const x = t.quotedWords;
60     const xs = [`verb:is`, `noun:"New York"`, `a`, `noun:"big  city"@en`];
61     assert(equal(x, xs));
62     // TODO assert(equal(` verb:is   name:"New York"@en article:a noun:"big  city"@en `.quotedWords,
63     //              [`verb:is`, `name:"New York"@en`, `article:a`, `noun:"big  city"@en`]));
64 }