1/*
2 This file is part of KHelpcenter.
3
4 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19*/
20
21#include "formatter.h"
22
23#include <KLocale>
24#include <KGlobal>
25#include <KDebug>
26#include <KConfig>
27#include <KConfigGroup>
28#include <KStandardDirs>
29
30#include <QFile>
31#include <QTextStream>
32
33using namespace KHC;
34
35Formatter::Formatter()
36 : mHasTemplate( false )
37{
38}
39
40Formatter:: ~Formatter()
41{
42}
43
44bool Formatter::readTemplates()
45{
46 KConfigGroup cfg(KGlobal::config(), "Templates");
47 QString mainTemplate = cfg.readEntry( "MainTemplate" );
48
49 if ( mainTemplate.isEmpty() )
50 {
51 mainTemplate = KStandardDirs::locate( "appdata", "maintemplate" );
52 }
53
54 if ( mainTemplate.isEmpty() )
55 {
56 kWarning() << "Main template file name is empty." ;
57 return false;
58 }
59
60 QFile f( mainTemplate );
61 if ( !f.open( QIODevice::ReadOnly ) )
62 {
63 kWarning() << "Unable to open main template file '" << mainTemplate
64 << "'." << endl;
65 return false;
66 }
67
68 QTextStream ts( &f );
69 QString line;
70 enum State { IDLE, SINGLELINE, MULTILINE };
71 State state = IDLE;
72 QString symbol;
73 QString endMarker;
74 QString value;
75 while( !( line = ts.readLine() ).isNull() ) {
76 switch ( state ) {
77 case IDLE:
78 if ( !line.isEmpty() && !line.startsWith( '#' ) )
79 {
80 int pos = line.indexOf( "<<" );
81 if ( pos >= 0 )
82 {
83 state = MULTILINE;
84 symbol = line.left( pos ).trimmed();
85 endMarker = line.mid( pos + 2 ).trimmed();
86 } else {
87 state = SINGLELINE;
88 symbol = line.trimmed();
89 }
90 }
91 break;
92 case SINGLELINE:
93 mSymbols.insert( symbol, line );
94 state = IDLE;
95 break;
96 case MULTILINE:
97 if ( line.startsWith( endMarker ) )
98 {
99 mSymbols.insert( symbol, value );
100 value = "";
101 state = IDLE;
102 }
103 else
104 {
105 value += line + '\n';
106 }
107 break;
108 default:
109 kError() << "Formatter::readTemplates(): Illegal state: "
110 << static_cast<int>(state) << endl;
111 break;
112 }
113 }
114
115 f.close();
116
117 QStringList requiredSymbols;
118 requiredSymbols << "HEADER" << "FOOTER";
119
120 bool success = true;
121 QStringList::ConstIterator it2;
122 for( it2 = requiredSymbols.constBegin(); it2 != requiredSymbols.constEnd(); ++it2 )
123 {
124 if ( !mSymbols.contains( *it2 ) )
125 {
126 success = false;
127 kError() << "Symbol '" << *it2 << "' is missing from main template file."
128 << endl;
129 }
130 }
131
132 if ( success ) mHasTemplate = true;
133 return success;
134}
135
136QString Formatter::header( const QString &title )
137{
138 QString s;
139 if ( mHasTemplate )
140 {
141 s = mSymbols[ "HEADER" ];
142 s.replace( "--TITLE:--", title );
143 } else {
144 s = QLatin1String("<html><head><title>") + title + QLatin1String("</title></head>\n<body>\n");
145 }
146 return s;
147}
148
149QString Formatter::footer()
150{
151 if ( mHasTemplate )
152 {
153 return mSymbols[ "FOOTER" ];
154 } else {
155 return QLatin1String("</body></html>");
156 }
157}
158
159QString Formatter::separator()
160{
161 return "<hr>";
162}
163
164QString Formatter::docTitle( const QString &title )
165{
166 return QLatin1String("<h3><font color=\"red\">") + title + QLatin1String("</font></h3>");
167}
168
169QString Formatter::sectionHeader( const QString &section )
170{
171 return QLatin1String("<h2><font color=\"blue\">") + section + QLatin1String("</font></h2>");
172}
173
174QString Formatter::processResult( const QString &data )
175{
176 QString result;
177
178 enum { Header, BodyTag, Body, Footer };
179
180 int state = Header;
181
182 for( int i = 0; i < data.length(); ++i )
183 {
184 QChar c = data[i];
185 switch ( state )
186 {
187 case Header:
188 if ( c == QLatin1Char('<') && data.mid( i, 5 ).toLower() == QLatin1String("<body") )
189 {
190 state = BodyTag;
191 i += 4;
192 }
193 break;
194 case BodyTag:
195 if ( c == '>' ) state = Body;
196 break;
197 case Body:
198 if ( c == QLatin1Char('<') && data.mid( i, 7 ).toLower() == QLatin1String("</body>") )
199 {
200 state = Footer;
201 } else {
202 result.append( c );
203 }
204 break;
205 case Footer:
206 break;
207 default:
208 result.append( c );
209 break;
210 }
211 }
212
213 if ( state == Header ) return data;
214 else return result;
215}
216
217QString Formatter::paragraph( const QString &str )
218{
219 return QLatin1String("<p>") + str + QLatin1String("</p>");
220}
221
222QString Formatter::title( const QString &title )
223{
224 return QLatin1String("<h2>") + title + QLatin1String("</h2>");
225}
226
227// vim:ts=2:sw=2:et
228