1 {-------------------------------------------------------------------------------
2 The contents of this file are subject to the Mozilla Public License
3 Version 1.1 (the "License"); you may not use this file except in compliance
4 with the License. You may obtain a copy of the License at
5 http://www.mozilla.org/MPL/
6 
7 Software distributed under the License is distributed on an "AS IS" basis,
8 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
9 the specific language governing rights and limitations under the License.
10 
11 The Original Code is: SynExportHTML.pas, released 2000-04-16.
12 
13 The Original Code is partly based on the mwHTMLExport.pas file from the
14 mwEdit component suite by Martin Waldenburg and other developers, the Initial
15 Author of this file is Michael Hieke.
16 Portions created by Michael Hieke are Copyright 2000 Michael Hieke.
17 Portions created by James D. Jacobson are Copyright 1999 Martin Waldenburg.
18 All Rights Reserved.
19 
20 Contributors to the SynEdit project are listed in the Contributors.txt file.
21 
22 Alternatively, the contents of this file may be used under the terms of the
23 GNU General Public License Version 2 or later (the "GPL"), in which case
24 the provisions of the GPL are applicable instead of those above.
25 If you wish to allow use of your version of this file only under the terms
26 of the GPL and not to allow others to use your version of this file
27 under the MPL, indicate your decision by deleting the provisions above and
28 replace them with the notice and other provisions required by the GPL.
29 If you do not delete the provisions above, a recipient may use your version
30 of this file under either the MPL or the GPL.
31 
32 $Id: synexporthtml.pas 53363 2016-11-12 16:33:33Z bart $
33 
34 You may retrieve the latest version of this file at the SynEdit home page,
35 located at http://SynEdit.SourceForge.net
36 
37 Known Issues:
38 -------------------------------------------------------------------------------}
39 
40 unit SynExportHTML;
41 
42 {$I synedit.inc}
43 {.$define debug_synexporthtml}
44 
45 interface
46 
47 uses
48   Classes,
49   LCLIntf, LCLType, Graphics, ClipBrd,
50   SynEditHighlighter, SynEditExport, LCLProc, LazUtf8;
51 
52 type
53   THTMLFontSize = (fs01, fs02, fs03, fs04, fs05, fs06, fs07, fsDefault);        //eb 2000-10-12
54 
55   TExportHtmlOption = (
56     heoFragmentOnly, //no surrounding <html><body>...</body><html> Note: will exclude heoDoctype, heoCharset
57     heoDoctype,      //add doctype declaration
58     heoCharset,      //add charset (UTF-8) information
59     heoWinClipHeader //add Clipboard header (affects Windows only) Note: cannot be set if ExportAsText = True!
60   );
61   TExportHtmlOptions = set of TExportHtmlOption;
62 
63 
64   { TSynExporterHTML }
65 
66   TSynExporterHTML = class(TSynCustomExporter)
67   private
68     fOptions: TExportHtmlOptions;
69     fFontSize: THTMLFontSize;
70     procedure SetExportHtmlOptions(Value: TExportHtmlOptions);
GetCreateHTMLFragmentnull71     function GetCreateHTMLFragment: Boolean;
72     procedure SetCreateHTMLFragment(Value: Boolean);
MakeFontSpannull73     function MakeFontSpan(FG, BG: TColor): String;
StyleToHtmlnull74     function StyleToHtml(AStyle: TFontStyles; IsSpace, DoSet: Boolean): String;
75   protected
76     procedure FormatAfterLastAttribute; override;
77     procedure FormatAttributeDone(BackgroundChanged, ForegroundChanged: boolean;
78       FontStylesChanged: TFontStyles); override;
79     procedure FormatAttributeInit(BackgroundChanged, ForegroundChanged: boolean;
80       FontStylesChanged: TFontStyles); override;
81 {begin}                                                                         //mh 2000-10-10
82     procedure FormatBeforeFirstAttribute(BackgroundChanged,
83       ForegroundChanged: boolean; FontStylesChanged: TFontStyles); override;
84 {end}                                                                           //mh 2000-10-10
85     procedure FormatBeforeFirstAttributeImmediate(BG, FG: TColor); override;
86     procedure FormatAfterLastAttributeImmediate; override;
87     procedure FormatAttributeInitImmediate(Attri: TSynHighlighterAttributes; IsSpace: Boolean); override;
88     procedure FormatAttributeDoneImmediate(Attri: TSynHighlighterAttributes; IsSpace: Boolean); override;
89 
90     procedure FormatNewLine; override;
GetFooternull91     function GetFooter: string; override;
GetFormatNamenull92     function GetFormatName: string; override;
GetHeadernull93     function GetHeader: string; override;
94     procedure SetExportAsText(Value: boolean); override;
95   public
96     constructor Create(AOwner: TComponent); override;
97   published
98     property Color;
99     property CreateHTMLFragment: boolean read GetCreateHTMLFragment
100       write SetCreateHTMLFragment default FALSE; deprecated 'Use Options instead';
101     property DefaultFilter;
102     property Options: TExportHtmlOptions read fOptions write SetExportHtmlOptions default [heoDoctype, heoCharset];
103     property Font;
104     property Highlighter;
105     property HTMLFontSize: THTMLFontSize read fFontSize write fFontSize;        //eb 2000-10-12
106     property Title;
107     property UseBackground;
108   end;
109 
ColorToHTMLnull110 function ColorToHTML(AColor: TColor): string;
111 
112 implementation
113 
114 uses
115   SysUtils,
116   SynEditStrConst;
117 
118 const
119   DocType = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"' + LineEnding +
120             '"http://www.w3.org/TR/html4/loose.dtd">';  //cannot use strict, because we use <font> tag
121   Generator = '<meta name="generator" content="Lazarus SynEdit Html Exporter">';
122   CharSet = '<meta http-equiv="content-type" content="text/html; charset=utf-8">';
123   DocumentStart = '<html>'+LineEnding+
124                   '<head>'+LineEnding+
125                   '%s'+LineEnding+
126                   '</head>'+LineEnding+
127                   '<body text="%s" bgcolor="%s">';
128   DocumentEnd = '</body>'+LineEnding+'</html>';
129   CodeStart = '<pre><code>';
130   CodeEnd = '</code></pre>';
131   FontStart = '<font %s face="%s">';
132   FontEnd = '</font>';
133   WinClipHeaderFmt = 'Version:0.9' + LineEnding +
134                      'StartHTML:%.8d' + LineEnding +
135                      'EndHTML:%.8d' + LineEnding +
136                      'StartFragment:%.8d' + LineEnding +
137                      'EndFragment:%.8d' + LineEnding;
138 
139   StartFragmentComment = '<!--StartFragment-->';
140   EndFragmentComment = '<!--EndFragment-->';
141 
142 
ColorToHTMLnull143 function ColorToHTML(AColor: TColor): string;
144 var
145   RGBColor: TColorRef;
146   RGBValue: byte;
147 const
148   Digits: array[0..15] of char = '0123456789ABCDEF';
149 begin
150   Result := '';
151   case AColor of
152     clRed:     Result := 'red';
153     clGreen:   Result := 'green';
154     clBlue:    Result := 'blue';
155     clPurple:  Result := 'purple';
156     clYellow:  Result := 'yellow';
157     clBlack:   Result := 'black';
158     clWhite:   Result := 'white';
159     clGray:    Result := 'gray';
160     clMaroon:  Result := 'maroon';
161     clFuchsia: Result := 'fuchsia';
162     clLime:    Result := 'lime';
163     clNavy:    Result := 'navy';
164     clAqua:    Result := 'aqua';
165     clTeal:    Result := 'teal';
166     clSilver:  Result := 'silver';
167   end;
168   if (Result <> '') then
169     Exit;
170   RGBColor := ColorToRGB(AColor);
171   Result := '#000000';
172  {****************}
173   RGBValue := GetRValue(RGBColor);
174   if RGBValue > 0 then begin
175     Result[2] := Digits[RGBValue shr  4];
176     Result[3] := Digits[RGBValue and 15];
177   end;
178  {****************}
179   RGBValue := GetGValue(RGBColor);
180   if RGBValue > 0 then begin
181     Result[4] := Digits[RGBValue shr  4];
182     Result[5] := Digits[RGBValue and 15];
183   end;
184  {****************}
185   RGBValue := GetBValue(RGBColor);
186   if RGBValue > 0 then begin
187     Result[6] := Digits[RGBValue shr  4];
188     Result[7] := Digits[RGBValue and 15];
189   end;
190 end;
191 
192 { TSynExporterHTML }
193 
194 constructor TSynExporterHTML.Create(AOwner: TComponent);
195 const
196   HTML_Format = {$ifdef windows}'HTML Format'{$else}'text/html'{$endif};
197 begin
198   inherited Create(AOwner);
199   {**************}
200   fClipboardFormat := RegisterClipboardFormat(HTML_Format);
201   fFontSize := fs03;
202   fOptions := [heoDocType, heoCharset];
203   fDefaultFilter := SYNS_FilterHTML;
204   // setup array of chars to be replaced
205   fReplaceReserved['&'] := '&amp;';
206   fReplaceReserved['<'] := '&lt;';
207   fReplaceReserved['>'] := '&gt;';
208   //fReplaceReserved['"'] := '&quot;';   //no need to replace this
209   //fReplaceReserved[''''] := '&apos;';  //no need to replace this
210 { The following characters are multi-byte in UTF-8:
211   fReplaceReserved['™'] := '&trade;';
212   fReplaceReserved['©'] := '&copy;';
213   fReplaceReserved['®'] := '&reg;';
214   fReplaceReserved['À'] := '&Agrave;';
215   fReplaceReserved['Á'] := '&Aacute;';
216   fReplaceReserved['Â'] := '&Acirc;';
217   fReplaceReserved['Ã'] := '&Atilde;';
218   fReplaceReserved['Ä'] := '&Auml;';
219   fReplaceReserved['Å'] := '&Aring;';
220   fReplaceReserved['Æ'] := '&AElig;';
221   fReplaceReserved['Ç'] := '&Ccedil;';
222   fReplaceReserved['È'] := '&Egrave;';
223   fReplaceReserved['É'] := '&Eacute;';
224   fReplaceReserved['Ê'] := '&Ecirc;';
225   fReplaceReserved['Ë'] := '&Euml;';
226   fReplaceReserved['Ì'] := '&Igrave;';
227   fReplaceReserved['Í'] := '&Iacute;';
228   fReplaceReserved['Î'] := '&Icirc;';
229   fReplaceReserved['Ï'] := '&Iuml;';
230   fReplaceReserved['Ð'] := '&ETH;';
231   fReplaceReserved['Ñ'] := '&Ntilde;';
232   fReplaceReserved['Ò'] := '&Ograve;';
233   fReplaceReserved['Ó'] := '&Oacute;';
234   fReplaceReserved['Ô'] := '&Ocirc;';
235   fReplaceReserved['Õ'] := '&Otilde;';
236   fReplaceReserved['Ö'] := '&Ouml;';
237   fReplaceReserved['Ø'] := '&Oslash;';
238   fReplaceReserved['Ù'] := '&Ugrave;';
239   fReplaceReserved['Ú'] := '&Uacute;';
240   fReplaceReserved['Û'] := '&Ucirc;';
241   fReplaceReserved['Ü'] := '&Uuml;';
242   fReplaceReserved['Ý'] := '&Yacute;';
243   fReplaceReserved['Þ'] := '&THORN;';
244   fReplaceReserved['ß'] := '&szlig;';
245   fReplaceReserved['à'] := '&agrave;';
246   fReplaceReserved['á'] := '&aacute;';
247   fReplaceReserved['â'] := '&acirc;';
248   fReplaceReserved['ã'] := '&atilde;';
249   fReplaceReserved['ä'] := '&auml;';
250   fReplaceReserved['å'] := '&aring;';
251   fReplaceReserved['æ'] := '&aelig;';
252   fReplaceReserved['ç'] := '&ccedil;';
253   fReplaceReserved['è'] := '&egrave;';
254   fReplaceReserved['é'] := '&eacute;';
255   fReplaceReserved['ê'] := '&ecirc;';
256   fReplaceReserved['ë'] := '&euml;';
257   fReplaceReserved['ì'] := '&igrave;';
258   fReplaceReserved['í'] := '&iacute;';
259   fReplaceReserved['î'] := '&icirc;';
260   fReplaceReserved['ï'] := '&iuml;';
261   fReplaceReserved['ð'] := '&eth;';
262   fReplaceReserved['ñ'] := '&ntilde;';
263   fReplaceReserved['ò'] := '&ograve;';
264   fReplaceReserved['ó'] := '&oacute;';
265   fReplaceReserved['ô'] := '&ocirc;';
266   fReplaceReserved['õ'] := '&otilde;';
267   fReplaceReserved['ö'] := '&ouml;';
268   fReplaceReserved['ø'] := '&oslash;';
269   fReplaceReserved['ù'] := '&ugrave;';
270   fReplaceReserved['ú'] := '&uacute;';
271   fReplaceReserved['û'] := '&ucirc;';
272   fReplaceReserved['ü'] := '&uuml;';
273   fReplaceReserved['ý'] := '&yacute;';
274   fReplaceReserved['þ'] := '&thorn;';
275   fReplaceReserved['ÿ'] := '&yuml;';
276   fReplaceReserved['¡'] := '&iexcl;';
277   fReplaceReserved['¢'] := '&cent;';
278   fReplaceReserved['£'] := '&pound;';
279   fReplaceReserved['¤'] := '&curren;';
280   fReplaceReserved['¥'] := '&yen;';
281   fReplaceReserved['¦'] := '&brvbar;';
282   fReplaceReserved['§'] := '&sect;';
283   fReplaceReserved['¨'] := '&uml;';
284   fReplaceReserved['ª'] := '&ordf;';
285   fReplaceReserved['«'] := '&laquo;';
286   fReplaceReserved['¬'] := '&shy;';
287   fReplaceReserved['¯'] := '&macr;';
288   fReplaceReserved['°'] := '&deg;';
289   fReplaceReserved['±'] := '&plusmn;';
290   fReplaceReserved['²'] := '&sup2;';
291   fReplaceReserved['³'] := '&sup3;';
292   fReplaceReserved['´'] := '&acute;';
293   fReplaceReserved['µ'] := '&micro;';
294   fReplaceReserved['·'] := '&middot;';
295   fReplaceReserved['¸'] := '&cedil;';
296   fReplaceReserved['¹'] := '&sup1;';
297   fReplaceReserved['º'] := '&ordm;';
298   fReplaceReserved['»'] := '&raquo;';
299   fReplaceReserved['¼'] := '&frac14;';
300   fReplaceReserved['½'] := '&frac12;';
301   fReplaceReserved['¾'] := '&frac34;';
302   fReplaceReserved['¿'] := '&iquest;';
303   fReplaceReserved['×'] := '&times;';
304   fReplaceReserved['÷'] := '&divide';
305   fReplaceReserved['€'] := '&euro;';}
306 end;
307 
308 
309 procedure TSynExporterHTML.FormatAfterLastAttribute;
310 begin
311   if fsStrikeout in fLastStyle then
312     AddData('</strike>');
313   if fsUnderline in fLastStyle then
314     AddData('</u>');
315   if fsItalic in fLastStyle then
316     AddData('</i>');
317   if fsBold in fLastStyle then
318     AddData('</b>');
319   if fLastFG <> fFont.Color then
320     AddData('</font>');
321   if UseBackground and (fLastBG <> fBackgroundColor) then
322     AddData('</span>');
323 end;
324 
325 procedure TSynExporterHTML.FormatAttributeDone(BackgroundChanged,
326   ForegroundChanged: boolean; FontStylesChanged: TFontStyles);
327 begin
328   if BackgroundChanged or ForegroundChanged or (FontStylesChanged <> []) then
329   begin
330     if fsStrikeout in fLastStyle then
331       AddData('</strike>');
332     if fsUnderline in fLastStyle then
333       AddData('</u>');
334     if fsItalic in fLastStyle then
335       AddData('</i>');
336     if fsBold in fLastStyle then
337       AddData('</b>');
338   end;
339   if (BackgroundChanged or ForegroundChanged) and (fLastFG <> fFont.Color) then //mh 2000-10-10
340     AddData('</font>');
341   if BackgroundChanged then
342     AddData('</span>');
343 end;
344 
345 procedure TSynExporterHTML.FormatAttributeInit(BackgroundChanged,
346   ForegroundChanged: boolean; FontStylesChanged: TFontStyles);
347 begin
348   if BackgroundChanged then
349     AddData('<span style="background-color: ' +
350       ColorToHtml(fLastBG) {Copy(ColorToHtml(fLastBG), 2, 9)} + '>');
351   if (BackgroundChanged or ForegroundChanged) and (fLastFG <> fFont.Color) then
352     AddData('<font color="' + ColorToHtml(fLastFG) + '">');
353   if BackgroundChanged or ForegroundChanged or (FontStylesChanged <> []) then
354   begin
355     if fsBold in fLastStyle then
356       AddData('<b>');
357     if fsItalic in fLastStyle then
358       AddData('<i>');
359     if fsUnderline in fLastStyle then
360       AddData('<u>');
361     if fsStrikeout in fLastStyle then
362       AddData('<strike>');
363   end;
364 end;
365 
366 {begin}                                                                         //mh 2000-10-10
367 procedure TSynExporterHTML.FormatBeforeFirstAttribute(BackgroundChanged,
368   ForegroundChanged: boolean; FontStylesChanged: TFontStyles);
369 begin
370   if BackgroundChanged then
371     AddData('<span style="background-color: ' +
372       ColorToHtml(fLastBG) {Copy(ColorToHtml(fLastBG), 2, 9)} + '>');
373   AddData('<font color="' + ColorToHtml(fLastFG) + '">');
374   if FontStylesChanged <> [] then begin
375     if fsBold in fLastStyle then
376       AddData('<b>');
377     if fsItalic in fLastStyle then
378       AddData('<i>');
379     if fsUnderline in fLastStyle then
380       AddData('<u>');
381     if fsStrikeout in fLastStyle then
382       AddData('<strike>');
383   end;
384 end;
385 
386 procedure TSynExporterHTML.FormatBeforeFirstAttributeImmediate(BG, FG: TColor);
387 var
388   Span: String;
389 begin
390   {$ifdef debug_synexporthtml}
391   debugln(['TSynExporterHTML.FormatBeforeFirstAttributeImmediate']);
392   {$endif}
393   // if not heoFragmentOnly this is handled in GetHeader
394   if (heoFragmentOnly in Options) then
395   begin
396     Span := MakeFontSpan(FG, BG);
397     AddData(Span);
398   end;
399 end;
400 
401 procedure TSynExporterHTML.FormatAfterLastAttributeImmediate;
402 begin
403   {$ifdef debug_synexporthtml}
404   debugln(['TSynExporterHTML.FormatAfterLastAttributeImmediate']);
405   {$endif}
406   if (heoFragmentOnly in Options) then
407     AddData('</span>');
408 end;
409 
410 procedure TSynExporterHTML.FormatAttributeInitImmediate(
411   Attri: TSynHighlighterAttributes; IsSpace: Boolean);
412 var
413   Span, StyleStr: String;
414   FG, BG: TColor;
415 begin
416   {$ifdef debug_synexporthtml}
417   debugln(['TSynExporterHTML.FormatAttributeInitImmediate']);
418   {$endif}
419   FG := ValidatedColor(Attri.Foreground, fFont.Color);
420   BG := ValidatedColor(Attri.Background, fBackgroundColor);
421   if (not IsSpace and (FG <> fFont.Color)) or
422      (UseBackGround and (BG <> fbackGroundColor)) then
423   begin
424     Span := MakeFontSpan(FG, BG);
425     AddData(Span);
426   end;
427   if (Attri.Style <> []) then
428   begin
429     StyleStr := StyleToHtml(Attri.Style, IsSpace, True);
430     AddData(StyleStr);
431   end;
432 end;
433 
434 procedure TSynExporterHTML.FormatAttributeDoneImmediate(
435   Attri: TSynHighlighterAttributes; IsSpace: Boolean);
436 var
437   FG, BG: TColor;
438   StyleStr: String;
439 begin
440   {$ifdef debug_synexporthtml}
441   debugln(['TSynExporterHTML.FormatAttributeDoneImmediate']);
442   {$endif}
443   //reversed order compared to FormatAttributeInitImmediate
444   if (Attri.Style <> []) then
445   begin
446     StyleStr := StyleToHtml(Attri.Style, IsSpace, False);
447     AddData(StyleStr);
448   end;
449   FG := ValidatedColor(Attri.Foreground, fFont.Color);
450   BG := ValidatedColor(Attri.Background, fBackgroundColor);
451   if (not IsSpace and (FG <> fFont.Color)) or
452      (UseBackGround and (BG <> fbackGroundColor)) then
453   begin
454     AddData('</span>');
455   end;
456 
457 end;
458 
459 {end}                                                                           //mh 2000-10-10
460 
461 procedure TSynExporterHTML.FormatNewLine;
462 begin
463   AddNewLine;
464 end;
465 
GetFooternull466 function TSynExporterHTML.GetFooter: string;
467 begin
468   Result := FontEnd + LineEnding + CodeEnd;
469   if (heoWinClipHeader in Options) then
470     Result := Result + EndFragmentComment;
471 
472   if not (heoFragmentOnly in Options) then
473   begin
474     if (Result <> '') then Result := Result + LineEnding;
475     Result := Result + DocumentEnd;
476   end;
477 end;
478 
GetFormatNamenull479 function TSynExporterHTML.GetFormatName: string;
480 begin
481   Result := SYNS_ExporterFormatHTML;
482 end;
483 
TSynExporterHTML.GetHeadernull484 function TSynExporterHTML.GetHeader: string;
485 var
486   sFontSize: string;                                                            //eb 2000-10-12
487   DocHeader, HeadText, WinClipHeader, SFooter: String;
488   WinClipHeaderSize, FooterLen: Integer;
489 begin
490   Result := '';
491   DocHeader := '';
492   if not (heoFragmentOnly in Options) then
493   begin
494     if (heoDocType in fOptions) then
495       DocHeader := DocHeader + DocType + LineEnding;
496     HeadText := Generator;
497     if (heoCharSet in fOptions) then
498       HeadText := HeadText + LineEnding + CharSet;
499     HeadText := HeadText + LineEnding + Format('<title>%s</title>',[Title]);
500     DocHeader := DocHeader + Format(DocumentStart,[HeadText,ColorToHtml(fFont.Color),ColorToHTML(fBackgroundColor)]);
501     if (heoWinClipHeader in fOptions) then
502       DocHeader := DocHeader + LineEnding + StartFragmentComment;
503     DocHeader := DocHeader + CodeStart; //Don't add LineEndings after this point, because of <pre> tag
504   end  //not heoFragmentOnly
505   else
506   begin
507     if (heoWinClipHeader in fOptions) then
508       DocHeader := DocHeader + StartFragmentComment + CodeStart
509     else
510       DocHeader := DocHeader + CodeStart;
511   end;
512   if fFontSize <> fsDefault then
513     sFontSize := Format(' size=%d', [1 + Ord(fFontSize)])
514   else
515     sFontSize := '';
516   DocHeader := DocHeader + Format(FontStart,[sFontSize, fFont.Name]);
517 
518   if (heoWinClipHeader in fOptions) then
519   begin
520     WinClipHeaderSize := Length(Format(WinClipHeaderFmt,[0,0,0,0]));
521     SFooter := GetFooter;
522     FooterLen := Length(SFooter);
523 
524     {$ifdef debug_synexporthtml}
525     debugln(['TSynExporterHtml.GetHeader: WinClipHeaderSize=',WinClipHeadersize]);
526     debugln(['  Footer="',Sfooter,'"']);
527     debugln(['  FooterLen=',FooterLen]);
528     debugln(['  BufferSize=',getBufferSize]);
529     debugln(['  length(docHeader)=',length(docheader)]);
530     {$endif}
531 
532     // Described in http://msdn.microsoft.com/library/sdkdoc/htmlclip/htmlclipboard.htm
533     WinClipHeader := Format(WinClipHeaderFmt,
534       [WinClipHeaderSize,  //HtmlStart
535        WinClipHeaderSize + Length(DocHeader) + FooterLen + GetBufferSize - 1, //HtmlEnd
536        WinClipHeaderSize + Utf8Pos(StartFragmentComment, DocHeader) + Length(StartfragmentComment) - 1, //StartFragment
537        WinClipHeaderSize + Length(DocHeader) + Utf8Pos(EndFragmentComment, SFooter) + GetBufferSize - 1  //EndFragment
538       ]);
539       DocHeader := WinClipHeader + DocHeader;
540   end;
541 
542   Result := DocHeader;
543 end;
544 
545 procedure TSynExporterHTML.SetExportAsText(Value: boolean);
546 begin
547   if (Value <> ExportAsText) then
548   begin
549     inherited SetExportAsText(Value);
550     if Value then
551       fOptions := fOptions - [heoWinClipHeader];
552   end;
553 end;
554 
555 procedure TSynExporterHTML.SetExportHtmlOptions(Value: TExportHtmlOptions);
556 begin
557   if (fOptions <> Value) then
558   begin
559     Clear;
560     fOptions := Value;
561     if ExportAsText then fOptions := fOptions - [heoWinClipHeader];
562     if (heoFragmentOnly in Value) then
563     begin
564       fOptions := fOptions - [heoDoctype, heoCharSet];
565     end;
566   end;
567 end;
568 
GetCreateHTMLFragmentnull569 function TSynExporterHTML.GetCreateHTMLFragment: Boolean;
570 begin
571   Result := (heoFragmentOnly in fOptions);
572 end;
573 
574 procedure TSynExporterHTML.SetCreateHTMLFragment(Value: Boolean);
575 begin
576   if (GetCreateHTMLFragment <> Value) then
577   begin
578     if Value then
579       Options := Options + [heoFragmentOnly]
580     else
581       Options := Options - [heoFragmentOnly];
582   end;
583 end;
584 
MakeFontSpannull585 function TSynExporterHTML.MakeFontSpan(FG, BG: TColor): String;
586 begin
587   Result := '<span style="color: ';
588   FG := ValidatedColor(FG, fFont.Color);
589   Result := Result + ColorToHtml(FG);
590   BG := ValidatedColor(BG, fBackgroundColor);
591   if UseBackGround then
592   begin
593     Result := Result + '; background-color: ' + ColorToHtml(BG);
594   end;
595   Result := Result + ';">';
596 end;
597 
StyleToHtmlnull598 function TSynExporterHTML.StyleToHtml(AStyle: TFontStyles; IsSpace, DoSet: Boolean): String;
599 begin
600   Result := '';
601   if DoSet then
602   begin
603     if not IsSpace then
604     begin
605       if (fsBold in AStyle) then Result := Result + '<b>';
606       if (fsItalic in AStyle) then Result := Result + '<i>';
607       if (fsUnderline in AStyle) then Result := Result + '<u>';
608     end;
609     //the only style that actually is applied to whitespace in HTML
610     if (fsStrikeOut in AStyle) then Result := Result + '<strike>';
611   end
612   else
613   begin //unset in the opposite order as set
614     if (fsStrikeOut in AStyle) then Result := Result + '</strike>';
615     if not IsSpace then
616     begin
617       if (fsUnderline in AStyle) then Result := Result + '</u>';
618       if (fsItalic in AStyle) then Result := Result + '</i>';
619       if (fsBold in AStyle) then Result := Result + '</b>';
620     end;
621   end;
622 end;
623 
624 end.
625 
626