1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 module utils.IndentedStringBuilder;
21 
22 import std.algorithm: canFind, startsWith, endsWith;
23 import std.string: strip;
24 
25 /** Keeps track of indentation level while building up a string */
26 public class IndentedStringBuilder
27 {
28 	string tabs;
29 	bool statement;
30 	bool paramList;
31 
32 	this()
33 	{
34 		this("");
35 	}
36 
37 	this(string t)
38 	{
39 		tabs = t;
40 	}
41 
42 	/**
43 	 * Formats the input line while keeping track of indentation.
44 	 * Params:
45 	 *    	lines = The lines to format
46 	 */
47 	public string format(string line)
48 	{
49 		string text;
50 		line = line.strip();
51 
52 		if ( (endsWith(line, '{') && !startsWith(line, "}")) || endsWith(line, "(") )
53 		{
54 			statement = false;
55 		}
56 
57 		//Don't change the indentation when the line is a comment.
58 		if ( startsWith(line, '*') )
59 		{
60 			return tabs ~" "~ line ~ "\n";
61 		}
62 
63 		if ( endsWith(line, "}", "};") || startsWith(line, "}", "};") || line == "));" || line == "connectFlags);" || (paramList && endsWith(line, ");", ")")) )
64 		{
65 			if ( !canFind(line, '{') && tabs.length > 0 )
66 				tabs.length = tabs.length -1;
67 
68 			if ( line == "connectFlags);" )
69 				statement = true;
70 
71 			if ( endsWith(line, ");") && !endsWith(line, "));") && line != ");" )
72 				statement = true;
73 
74 			paramList = false;
75 		}
76 
77 		if ( statement )
78 		{
79 			text = tabs ~"\t"~ line ~"\n";
80 			statement = false;
81 		}
82 		else
83 		{
84 			text = tabs ~ line ~"\n";
85 		}
86 
87 		if ( startsWith(line, "if", "else", "version", "debug", "do", "while") && !endsWith(line, "}", ";") )
88 		{
89 			statement = true;
90 		}
91 		else if ( (endsWith(line, '{') && !startsWith(line, "}")) )
92 		{
93 			tabs ~= '\t';
94 		}
95 		else if ( endsWith(line, "(") )
96 		{
97 			tabs ~= '\t';
98 			paramList = true;
99 		}
100 
101 		return text;
102 	}
103 
104 	/**
105 	 * Formats the input lines while keeping track of indentation
106 	 * Params:
107 	 *    	lines = The lines to format
108 	 */
109 	public string format(string[] lines)
110 	{
111 		string text = "";
112 		foreach(string line ; lines )
113 			text ~= format(line);
114 		return text;
115 	}
116 
117 	public void setIndent(string t)
118 	{
119 		tabs = t;
120 	}
121 }