Rev 7 | Rev 9 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 7 | Rev 8 | ||
---|---|---|---|
Line 2... | Line 2... | ||
2 | 2 | ||
3 | interface |
3 | interface |
4 | 4 | ||
5 | uses |
5 | uses |
6 | Windows, Messages, SysUtils, StrUtils, IniFiles, Classes, Forms, Variants, MsHTML, |
6 | Windows, Messages, SysUtils, StrUtils, IniFiles, Classes, Forms, Variants, MsHTML, |
7 | SHDocVw_TLB, StdCtrls, SynEdit; |
7 | SHDocVw_TLB, StdCtrls, SynEdit, ActiveX; |
8 | 8 | ||
9 | function GetDosOutput(CommandLine: string; Work: string = ''): string; |
9 | function GetDosOutput(CommandLine: string; Work: string = ''): string; |
10 | function StrIPos(const SubStr, S: string): Integer; |
10 | function StrIPos(const SubStr, S: string): Integer; |
11 | procedure WaitForBrowser(WB: TWebbrowser); |
- | |
12 | function LoadFileToStr(const FileName: TFileName): AnsiString; |
11 | function LoadFileToStr(const FileName: TFileName): AnsiString; |
13 | function LastPos(const SubStr, S: string): integer; |
12 | function LastPos(const SubStr, S: string): integer; |
14 | function ParseCHM(chmFile: string): boolean; |
- | |
15 | procedure BrowseURL(WebBrowser1: TWebBrowser; url: string); |
- | |
16 | procedure BrowseContent(WebBrowser1: TWebBrowser; html: string); |
- | |
17 | function IsTextHTML(s: string): boolean; |
13 | function IsTextHTML(s: string): boolean; |
18 | function GetWordUnderCaret(AMemo: TSynEdit): string; |
14 | function GetWordUnderCaret(AMemo: TSynEdit): string; |
19 | function IsValidPHPExe(const exeFile: string): boolean; |
15 | function IsValidPHPExe(const exeFile: string): boolean; |
20 | 16 | ||
21 | implementation |
17 | implementation |
Line 80... | Line 76... | ||
80 | function StrIPos(const SubStr, S: string): Integer; |
76 | function StrIPos(const SubStr, S: string): Integer; |
81 | begin |
77 | begin |
82 | Result := Pos(UpperCase(SubStr), UpperCase(S)); |
78 | Result := Pos(UpperCase(SubStr), UpperCase(S)); |
83 | end; |
79 | end; |
84 | 80 | ||
85 | procedure WaitForBrowser(WB: TWebbrowser); |
- | |
86 | begin |
- | |
87 | while (WB.Busy) |
- | |
88 | and not (Application.Terminated) do |
- | |
89 | begin |
- | |
90 | Application.ProcessMessages; |
- | |
91 | Sleep(100); |
- | |
92 | end; |
- | |
93 | end; |
- | |
94 | - | ||
95 | function LoadFileToStr(const FileName: TFileName): AnsiString; |
81 | function LoadFileToStr(const FileName: TFileName): AnsiString; |
96 | var |
82 | var |
97 | FileStream : TFileStream; |
83 | FileStream : TFileStream; |
98 | 84 | ||
99 | begin |
85 | begin |
Line 130... | Line 116... | ||
130 | end; |
116 | end; |
131 | Dec(I); |
117 | Dec(I); |
132 | end; |
118 | end; |
133 | end; |
119 | end; |
134 | 120 | ||
135 | function ParseCHM(chmFile: string): boolean; |
- | |
136 | var |
- | |
137 | test, candidate, candidate2: string; |
- | |
138 | p, p2, q: integer; |
- | |
139 | i: integer; |
- | |
140 | good: Boolean; |
- | |
141 | ini: TMemIniFile; |
- | |
142 | domain: string; |
- | |
143 | sl: TStringList; |
- | |
144 | symbolCount: Integer; |
- | |
145 | sl2: TStrings; |
- | |
146 | outFile: string; |
- | |
147 | begin |
- | |
148 | // TODO: problem: mysqli::commit has /res/mysqli.commit.html -> keyword is NOT commit alone |
- | |
149 | - | ||
150 | outFile := ChangeFileExt(chmFile, '.ini'); |
- | |
151 | DeleteFile(outFile); |
- | |
152 | test := LoadFileToStr(chmFile); |
- | |
153 | if Pos('/php_manual_', test) = -1 then |
- | |
154 | begin |
- | |
155 | result := false; |
- | |
156 | exit; |
- | |
157 | end; |
- | |
158 | p := 0; |
- | |
159 | ini := TMemIniFile.Create(outFile); |
- | |
160 | try |
- | |
161 | ini.WriteString('_Info_', 'Source', chmFile); |
- | |
162 | ini.WriteString('_Info_', 'Generated', DateTimeToStr(Now)); |
- | |
163 | ini.WriteString('_Info_', 'GeneratorVer', '1.0'); |
- | |
164 | ini.WriteString('_Info_', 'Signature', '$ViaThinkSoft$'); |
- | |
165 | {$REGION 'Excludes'} |
- | |
166 | // TODO: more excludes |
- | |
167 | ini.WriteBool('_HelpExclude_', 'about', true); |
- | |
168 | ini.WriteBool('_HelpExclude_', 'apache', true); |
- | |
169 | {$ENDREGION} |
- | |
170 | while true do |
- | |
171 | begin |
- | |
172 | Application.ProcessMessages; |
- | |
173 | - | ||
174 | p := PosEx('/res/', Test, p+1); |
- | |
175 | if p = 0 then break; |
- | |
176 | p2 := PosEx('.html', Test, p); |
- | |
177 | if p = 0 then break; |
- | |
178 | candidate := copy(Test, p+5, p2-p-5); |
- | |
179 | if candidate = '' then continue; |
- | |
180 | if Length(candidate) > 50 then continue; |
- | |
181 | good := true; |
- | |
182 | for i := p+5 to p2-1 do |
- | |
183 | begin |
- | |
184 | if ord(test[i]) < 32 then |
- | |
185 | begin |
- | |
186 | good := false; |
- | |
187 | break; |
- | |
188 | end; |
- | |
189 | if not (test[i] in ['a'..'z', 'A'..'Z', '.', '-', '_', '0'..'9']) then |
- | |
190 | begin |
- | |
191 | ini.WriteInteger('_Errors_', 'Contains unexpected character! ' + candidate, ini.ReadInteger('_Errors_', 'Contains unexpected character! ' + candidate, 0)+1); |
- | |
192 | good := false; |
- | |
193 | break; |
- | |
194 | end; |
- | |
195 | end; |
- | |
196 | if good then |
- | |
197 | begin |
- | |
198 | candidate2 := LowerCase(StringReplace(candidate, '-', '_', [rfReplaceAll])); |
- | |
199 | q := LastPos('.', candidate2); |
- | |
200 | domain := copy(candidate2, 1, q-1); |
- | |
201 | if domain = '' then continue; |
- | |
202 | candidate2 := copy(candidate2, q+1, Length(candidate2)-q); |
- | |
203 | ini.WriteInteger('_Category_', domain, ini.ReadInteger('_Category_', domain, 0)+1); |
- | |
204 | ini.WriteString(domain, candidate2, '/res/'+candidate+'.html'); |
- | |
205 | if not ini.ReadBool('_HelpExclude_', domain, false) |
- | |
206 | and (candidate2 <> 'configuration') |
- | |
207 | and (candidate2 <> 'constants') |
- | |
208 | and (candidate2 <> 'installation') |
- | |
209 | and (candidate2 <> 'requirements') |
- | |
210 | and (candidate2 <> 'resources') |
- | |
211 | and (candidate2 <> 'setup') then |
- | |
212 | begin |
- | |
213 | if ini.ReadString('_HelpWords_', candidate2, '') <> '' then |
- | |
214 | begin |
- | |
215 | ini.WriteInteger('_Conflicts_', candidate2, ini.ReadInteger('_Conflicts_', candidate2, 0)+1); |
- | |
216 | end; |
- | |
217 | - | ||
218 | ini.WriteString('_HelpWords_', candidate2, '/res/'+candidate+'.html'); |
- | |
219 | end; |
- | |
220 | end; |
- | |
221 | end; |
- | |
222 | - | ||
223 | sl := TStringList.Create; |
- | |
224 | sl2 := TStringList.Create; |
- | |
225 | try |
- | |
226 | ini.ReadSections(sl); |
- | |
227 | ini.WriteInteger('_Info_', 'TotalDomains', sl.Count); |
- | |
228 | symbolCount := 0; |
- | |
229 | for domain in sl do |
- | |
230 | begin |
- | |
231 | ini.ReadSection(domain, sl2); |
- | |
232 | Inc(symbolCount, sl2.Count) |
- | |
233 | end; |
- | |
234 | ini.WriteInteger('_Info_', 'TotalSymbols', symbolCount); |
- | |
235 | finally |
- | |
236 | sl.Free; |
- | |
237 | sl2.Free; |
- | |
238 | end; |
- | |
239 | - | ||
240 | ini.UpdateFile; |
- | |
241 | result := true; |
- | |
242 | finally |
- | |
243 | ini.Free; |
- | |
244 | end; |
- | |
245 | end; |
- | |
246 | - | ||
247 | procedure BrowseURL(WebBrowser1: TWebBrowser; url: string); |
- | |
248 | var |
- | |
249 | BrowserFlags : olevariant; |
- | |
250 | MyTargetFrameName : olevariant; |
- | |
251 | MyPostaData : olevariant; |
- | |
252 | MyHeaders : olevariant; |
- | |
253 | begin |
- | |
254 | { Flags: |
- | |
255 | Constant Value Meaning |
- | |
256 | NavOpenInNewWindow $01 Open the resource or file in a new window. |
- | |
257 | NavNoHistory $02 Do not add the resource or file to the history list. The new page replaces the current page in the list. |
- | |
258 | NavNoReadFromCache $04 Do not read from the disk cache for this navigation. |
- | |
259 | NavNoWriteToCache $08 Do not write the results of this navigation to the disk cache. |
- | |
260 | NavAllowAutosearch $10 If the navigation fails, the Web browser attempts to navigate common root domains (.com, .org, and so on). If this still fails, the URL is passed to a search engine. |
- | |
261 | } |
- | |
262 | BrowserFlags := $02; |
- | |
263 | MyTargetFrameName := null; |
- | |
264 | MyPostaData := null; |
- | |
265 | MyHeaders := null; |
- | |
266 | WebBrowser1.Silent := true; // no JavaScript errors |
- | |
267 | Webbrowser1.Navigate(url, BrowserFlags,MyTargetFrameName,MyPostaData,MyHeaders); |
- | |
268 | WaitForBrowser(WebBrowser1); |
- | |
269 | end; |
- | |
270 | - | ||
271 | procedure BrowseContent(WebBrowser1: TWebBrowser; html: string); |
- | |
272 | var |
- | |
273 | BrowserFlags : olevariant; |
- | |
274 | MyTargetFrameName : olevariant; |
- | |
275 | MyPostaData : olevariant; |
- | |
276 | MyHeaders : olevariant; |
- | |
277 | Doc: Variant; |
- | |
278 | begin |
- | |
279 | { Flags: |
- | |
280 | Constant Value Meaning |
- | |
281 | NavOpenInNewWindow $01 Open the resource or file in a new window. |
- | |
282 | NavNoHistory $02 Do not add the resource or file to the history list. The new page replaces the current page in the list. |
- | |
283 | NavNoReadFromCache $04 Do not read from the disk cache for this navigation. |
- | |
284 | NavNoWriteToCache $08 Do not write the results of this navigation to the disk cache. |
- | |
285 | NavAllowAutosearch $10 If the navigation fails, the Web browser attempts to navigate common root domains (.com, .org, and so on). If this still fails, the URL is passed to a search engine. |
- | |
286 | } |
- | |
287 | if WebBrowser1.Document = nil then |
- | |
288 | begin |
- | |
289 | BrowserFlags := $02 + $04 + $08 + $10; |
- | |
290 | MyTargetFrameName := null; |
- | |
291 | MyPostaData := null; |
- | |
292 | MyHeaders := null; |
- | |
293 | Webbrowser1.Navigate('about:blank', BrowserFlags,MyTargetFrameName,MyPostaData,MyHeaders); |
- | |
294 | WaitForBrowser(WebBrowser1); |
- | |
295 | end; |
- | |
296 | - | ||
297 | Doc := WebBrowser1.Document; |
- | |
298 | Doc.Clear; |
- | |
299 | Doc.Write(html); |
- | |
300 | Doc.Close; |
- | |
301 | WaitForBrowser(WebBrowser1); |
- | |
302 | end; |
- | |
303 | - | ||
304 | function IsTextHTML(s: string): boolean; |
121 | function IsTextHTML(s: string): boolean; |
305 | 122 | ||
306 | function _Tag(const tag: string): integer; |
123 | function _Tag(const tag: string): integer; |
307 | begin |
124 | begin |
308 | result := 0; |
125 | result := 0; |
Line 325... | Line 142... | ||
325 | // Template: http://stackoverflow.com/questions/6339446/delphi-get-the-whole-word-where-the-caret-is-in-a-memo |
142 | // Template: http://stackoverflow.com/questions/6339446/delphi-get-the-whole-word-where-the-caret-is-in-a-memo |
326 | function GetWordUnderCaret(AMemo: TSynEdit): string; |
143 | function GetWordUnderCaret(AMemo: TSynEdit): string; |
327 | 144 | ||
328 | function ValidChar(c: char): boolean; |
145 | function ValidChar(c: char): boolean; |
329 | begin |
146 | begin |
330 | result := c in ['a'..'z', 'A'..'Z', '0'..'9', '_']; |
147 | result := CharInSet(c, ['a'..'z', 'A'..'Z', '0'..'9', '_']); |
331 | end; |
148 | end; |
332 | 149 | ||
333 | var |
150 | var |
334 | Line : Integer; |
151 | Line : Integer; |
335 | Column : Integer; |
152 | Column : Integer; |