1 /**
2 	Utility functions for string processing
3 	Copyright: © 2012-2014 RejectedSoftware e.K.
4 	License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file.
5 	Authors: Sönke Ludwig
6 */
7 module dmarkdown..string;
8 
9 public import std..string;
10 
11 import std.algorithm;
12 import std.array;
13 import std.ascii;
14 import std.format;
15 import std.uni;
16 import std.utf;
17 import core.exception;
18 
19 
20 package:
21 
22 /**
23 	Checks if all characters in 'str' are contained in 'chars'.
24  */
25 bool allOf(string str, string chars)
26 @safe pure {
27 	foreach (dchar ch; str)
28 		if (!chars.canFind(ch))
29 			return false;
30 	return true;
31 }
32 
33 ptrdiff_t indexOfCT(Char)(in Char[] s, dchar c, CaseSensitive cs = CaseSensitive.yes)
34 @safe pure {
35 	if (__ctfe) {
36 		if (cs == CaseSensitive.yes) {
37 			foreach (i, dchar ch; s)
38 				if (ch == c)
39 					return i;
40 		} else {
41 			c = std.uni.toLower(c);
42 			foreach (i, dchar ch; s)
43 				if (std.uni.toLower(ch) == c)
44 					return i;
45 		}
46 		return -1;
47 	} else return std..string.indexOf(s, c, cs);
48 }
49 
50 /**
51   Checks if any character in 'str' is contained in 'chars'.
52  */
53 bool anyOf(string str, string chars)
54 @safe pure {
55 	foreach (ch; str)
56 		if (chars.canFind(ch))
57 			return true;
58 	return false;
59 }
60 
61 /**
62 	Finds the closing bracket (works with any of '[', '$(LPAREN)', '<', '{').
63 
64 	Params:
65 		str = input string
66 		nested = whether to skip nested brackets
67 	Returns:
68 		The index of the closing bracket or -1 for unbalanced strings
69 		and strings that don't start with a bracket.
70 */
71 sizediff_t matchBracket(string str, bool nested = true)
72 @safe pure nothrow {
73 	if (str.length < 2) return -1;
74 	
75 	char open = str[0], close = void;
76 	switch (str[0]) {
77 		case '[': close = ']'; break;
78 		case '(': close = ')'; break;
79 		case '<': close = '>'; break;
80 		case '{': close = '}'; break;
81 		default: return -1;
82 	}
83 	
84 	size_t level = 1;
85 	foreach (i, char c; str[1 .. $]) {
86 		if (nested && c == open) ++level;
87 		else if (c == close) --level;
88 		if (level == 0) return i + 1;
89 	}
90 	return -1;
91 }