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$
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, SysUtils, SynEditStrConst;
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 const
115   DocType = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"' + LineEnding +
116             '"http://www.w3.org/TR/html4/loose.dtd">';  //cannot use strict, because we use <font> tag
117   Generator = '<meta name="generator" content="Lazarus SynEdit Html Exporter">';
118   CharSet = '<meta http-equiv="content-type" content="text/html; charset=utf-8">';
119   DocumentStart = '<html>'+LineEnding+
120                   '<head>'+LineEnding+
121                   '%s'+LineEnding+
122                   '</head>'+LineEnding+
123                   '<body text="%s" bgcolor="%s">';
124   DocumentEnd = '</body>'+LineEnding+'</html>';
125   CodeStart = '<pre><code>';
126   CodeEnd = '</code></pre>';
127   FontStart = '<font %s face="%s">';
128   FontEnd = '</font>';
129   WinClipHeaderFmt = 'Version:0.9' + LineEnding +
130                      'StartHTML:%.8d' + LineEnding +
131                      'EndHTML:%.8d' + LineEnding +
132                      'StartFragment:%.8d' + LineEnding +
133                      'EndFragment:%.8d' + LineEnding;
134 
135   StartFragmentComment = '<!--StartFragment-->';
136   EndFragmentComment = '<!--EndFragment-->';
137 
138 
ColorToHTMLnull139 function ColorToHTML(AColor: TColor): string;
140 var
141   RGBColor: TColorRef;
142   RGBValue: byte;
143 const
144   Digits: array[0..15] of char = '0123456789ABCDEF';
145 begin
146   Result := '';
147   case AColor of
148     clRed:     Result := 'red';
149     clGreen:   Result := 'green';
150     clBlue:    Result := 'blue';
151     clPurple:  Result := 'purple';
152     clYellow:  Result := 'yellow';
153     clBlack:   Result := 'black';
154     clWhite:   Result := 'white';
155     clGray:    Result := 'gray';
156     clMaroon:  Result := 'maroon';
157     clFuchsia: Result := 'fuchsia';
158     clLime:    Result := 'lime';
159     clNavy:    Result := 'navy';
160     clAqua:    Result := 'aqua';
161     clTeal:    Result := 'teal';
162     clSilver:  Result := 'silver';
163   end;
164   if (Result <> '') then
165     Exit;
166   RGBColor := ColorToRGB(AColor);
167   Result := '#000000';
168  {****************}
169   RGBValue := GetRValue(RGBColor);
170   if RGBValue > 0 then begin
171     Result[2] := Digits[RGBValue shr  4];
172     Result[3] := Digits[RGBValue and 15];
173   end;
174  {****************}
175   RGBValue := GetGValue(RGBColor);
176   if RGBValue > 0 then begin
177     Result[4] := Digits[RGBValue shr  4];
178     Result[5] := Digits[RGBValue and 15];
179   end;
180  {****************}
181   RGBValue := GetBValue(RGBColor);
182   if RGBValue > 0 then begin
183     Result[6] := Digits[RGBValue shr  4];
184     Result[7] := Digits[RGBValue and 15];
185   end;
186 end;
187 
188 { TSynExporterHTML }
189 
190 constructor TSynExporterHTML.Create(AOwner: TComponent);
191 const
192   HTML_Format = {$ifdef windows}'HTML Format'{$else}'text/html'{$endif};
193 begin
194   inherited Create(AOwner);
195   {**************}
196   fClipboardFormat := RegisterClipboardFormat(HTML_Format);
197   fFontSize := fs03;
198   fOptions := [heoDocType, heoCharset];
199   fDefaultFilter := SYNS_FilterHTML;
200   // setup array of chars to be replaced
201   fReplaceReserved['&'] := '&amp;';
202   fReplaceReserved['<'] := '&lt;';
203   fReplaceReserved['>'] := '&gt;';
204   //fReplaceReserved['"'] := '&quot;';   //no need to replace this
205   //fReplaceReserved[''''] := '&apos;';  //no need to replace this
206 { The following characters are multi-byte in UTF-8:
207   fReplaceReserved['™'] := '&trade;';
208   fReplaceReserved['©'] := '&copy;';
209   fReplaceReserved['®'] := '&reg;';
210   fReplaceReserved['À'] := '&Agrave;';
211   fReplaceReserved['Á'] := '&Aacute;';
212   fReplaceReserved['Â'] := '&Acirc;';
213   fReplaceReserved['Ã'] := '&Atilde;';
214   fReplaceReserved['Ä'] := '&Auml;';
215   fReplaceReserved['Å'] := '&Aring;';
216   fReplaceReserved['Æ'] := '&AElig;';
217   fReplaceReserved['Ç'] := '&Ccedil;';
218   fReplaceReserved['È'] := '&Egrave;';
219   fReplaceReserved['É'] := '&Eacute;';
220   fReplaceReserved['Ê'] := '&Ecirc;';
221   fReplaceReserved['Ë'] := '&Euml;';
222   fReplaceReserved['Ì'] := '&Igrave;';
223   fReplaceReserved['Í'] := '&Iacute;';
224   fReplaceReserved['Î'] := '&Icirc;';
225   fReplaceReserved['Ï'] := '&Iuml;';
226   fReplaceReserved['Ð'] := '&ETH;';
227   fReplaceReserved['Ñ'] := '&Ntilde;';
228   fReplaceReserved['Ò'] := '&Ograve;';
229   fReplaceReserved['Ó'] := '&Oacute;';
230   fReplaceReserved['Ô'] := '&Ocirc;';
231   fReplaceReserved['Õ'] := '&Otilde;';
232   fReplaceReserved['Ö'] := '&Ouml;';
233   fReplaceReserved['Ø'] := '&Oslash;';
234   fReplaceReserved['Ù'] := '&Ugrave;';
235   fReplaceReserved['Ú'] := '&Uacute;';
236   fReplaceReserved['Û'] := '&Ucirc;';
237   fReplaceReserved['Ü'] := '&Uuml;';
238   fReplaceReserved['Ý'] := '&Yacute;';
239   fReplaceReserved['Þ'] := '&THORN;';
240   fReplaceReserved['ß'] := '&szlig;';
241   fReplaceReserved['à'] := '&agrave;';
242   fReplaceReserved['á'] := '&aacute;';
243   fReplaceReserved['â'] := '&acirc;';
244   fReplaceReserved['ã'] := '&atilde;';
245   fReplaceReserved['ä'] := '&auml;';
246   fReplaceReserved['å'] := '&aring;';
247   fReplaceReserved['æ'] := '&aelig;';
248   fReplaceReserved['ç'] := '&ccedil;';
249   fReplaceReserved['è'] := '&egrave;';
250   fReplaceReserved['é'] := '&eacute;';
251   fReplaceReserved['ê'] := '&ecirc;';
252   fReplaceReserved['ë'] := '&euml;';
253   fReplaceReserved['ì'] := '&igrave;';
254   fReplaceReserved['í'] := '&iacute;';
255   fReplaceReserved['î'] := '&icirc;';
256   fReplaceReserved['ï'] := '&iuml;';
257   fReplaceReserved['ð'] := '&eth;';
258   fReplaceReserved['ñ'] := '&ntilde;';
259   fReplaceReserved['ò'] := '&ograve;';
260   fReplaceReserved['ó'] := '&oacute;';
261   fReplaceReserved['ô'] := '&ocirc;';
262   fReplaceReserved['õ'] := '&otilde;';
263   fReplaceReserved['ö'] := '&ouml;';
264   fReplaceReserved['ø'] := '&oslash;';
265   fReplaceReserved['ù'] := '&ugrave;';
266   fReplaceReserved['ú'] := '&uacute;';
267   fReplaceReserved['û'] := '&ucirc;';
268   fReplaceReserved['ü'] := '&uuml;';
269   fReplaceReserved['ý'] := '&yacute;';
270   fReplaceReserved['þ'] := '&thorn;';
271   fReplaceReserved['ÿ'] := '&yuml;';
272   fReplaceReserved['¡'] := '&iexcl;';
273   fReplaceReserved['¢'] := '&cent;';
274   fReplaceReserved['£'] := '&pound;';
275   fReplaceReserved['¤'] := '&curren;';
276   fReplaceReserved['¥'] := '&yen;';
277   fReplaceReserved['¦'] := '&brvbar;';
278   fReplaceReserved['§'] := '&sect;';
279   fReplaceReserved['¨'] := '&uml;';
280   fReplaceReserved['ª'] := '&ordf;';
281   fReplaceReserved['«'] := '&laquo;';
282   fReplaceReserved['¬'] := '&shy;';
283   fReplaceReserved['¯'] := '&macr;';
284   fReplaceReserved['°'] := '&deg;';
285   fReplaceReserved['±'] := '&plusmn;';
286   fReplaceReserved['²'] := '&sup2;';
287   fReplaceReserved['³'] := '&sup3;';
288   fReplaceReserved['´'] := '&acute;';
289   fReplaceReserved['µ'] := '&micro;';
290   fReplaceReserved['·'] := '&middot;';
291   fReplaceReserved['¸'] := '&cedil;';
292   fReplaceReserved['¹'] := '&sup1;';
293   fReplaceReserved['º'] := '&ordm;';
294   fReplaceReserved['»'] := '&raquo;';
295   fReplaceReserved['¼'] := '&frac14;';
296   fReplaceReserved['½'] := '&frac12;';
297   fReplaceReserved['¾'] := '&frac34;';
298   fReplaceReserved['¿'] := '&iquest;';
299   fReplaceReserved['×'] := '&times;';
300   fReplaceReserved['÷'] := '&divide';
301   fReplaceReserved['€'] := '&euro;';}
302 end;
303 
304 
305 procedure TSynExporterHTML.FormatAfterLastAttribute;
306 begin
307   if fsStrikeout in fLastStyle then
308     AddData('</strike>');
309   if fsUnderline in fLastStyle then
310     AddData('</u>');
311   if fsItalic in fLastStyle then
312     AddData('</i>');
313   if fsBold in fLastStyle then
314     AddData('</b>');
315   if fLastFG <> fFont.Color then
316     AddData('</font>');
317   if UseBackground and (fLastBG <> fBackgroundColor) then
318     AddData('</span>');
319 end;
320 
321 procedure TSynExporterHTML.FormatAttributeDone(BackgroundChanged,
322   ForegroundChanged: boolean; FontStylesChanged: TFontStyles);
323 begin
324   if BackgroundChanged or ForegroundChanged or (FontStylesChanged <> []) then
325   begin
326     if fsStrikeout in fLastStyle then
327       AddData('</strike>');
328     if fsUnderline in fLastStyle then
329       AddData('</u>');
330     if fsItalic in fLastStyle then
331       AddData('</i>');
332     if fsBold in fLastStyle then
333       AddData('</b>');
334   end;
335   if (BackgroundChanged or ForegroundChanged) and (fLastFG <> fFont.Color) then //mh 2000-10-10
336     AddData('</font>');
337   if BackgroundChanged then
338     AddData('</span>');
339 end;
340 
341 procedure TSynExporterHTML.FormatAttributeInit(BackgroundChanged,
342   ForegroundChanged: boolean; FontStylesChanged: TFontStyles);
343 begin
344   if BackgroundChanged then
345     AddData('<span style="background-color: ' +
346       ColorToHtml(fLastBG) {Copy(ColorToHtml(fLastBG), 2, 9)} + '>');
347   if (BackgroundChanged or ForegroundChanged) and (fLastFG <> fFont.Color) then
348     AddData('<font color="' + ColorToHtml(fLastFG) + '">');
349   if BackgroundChanged or ForegroundChanged or (FontStylesChanged <> []) then
350   begin
351     if fsBold in fLastStyle then
352       AddData('<b>');
353     if fsItalic in fLastStyle then
354       AddData('<i>');
355     if fsUnderline in fLastStyle then
356       AddData('<u>');
357     if fsStrikeout in fLastStyle then
358       AddData('<strike>');
359   end;
360 end;
361 
362 {begin}                                                                         //mh 2000-10-10
363 procedure TSynExporterHTML.FormatBeforeFirstAttribute(BackgroundChanged,
364   ForegroundChanged: boolean; FontStylesChanged: TFontStyles);
365 begin
366   if BackgroundChanged then
367     AddData('<span style="background-color: ' +
368       ColorToHtml(fLastBG) {Copy(ColorToHtml(fLastBG), 2, 9)} + '>');
369   AddData('<font color="' + ColorToHtml(fLastFG) + '">');
370   if FontStylesChanged <> [] then begin
371     if fsBold in fLastStyle then
372       AddData('<b>');
373     if fsItalic in fLastStyle then
374       AddData('<i>');
375     if fsUnderline in fLastStyle then
376       AddData('<u>');
377     if fsStrikeout in fLastStyle then
378       AddData('<strike>');
379   end;
380 end;
381 
382 procedure TSynExporterHTML.FormatBeforeFirstAttributeImmediate(BG, FG: TColor);
383 var
384   Span: String;
385 begin
386   {$ifdef debug_synexporthtml}
387   debugln(['TSynExporterHTML.FormatBeforeFirstAttributeImmediate']);
388   {$endif}
389   // if not heoFragmentOnly this is handled in GetHeader
390   if (heoFragmentOnly in Options) then
391   begin
392     Span := MakeFontSpan(FG, BG);
393     AddData(Span);
394   end;
395 end;
396 
397 procedure TSynExporterHTML.FormatAfterLastAttributeImmediate;
398 begin
399   {$ifdef debug_synexporthtml}
400   debugln(['TSynExporterHTML.FormatAfterLastAttributeImmediate']);
401   {$endif}
402   if (heoFragmentOnly in Options) then
403     AddData('</span>');
404 end;
405 
406 procedure TSynExporterHTML.FormatAttributeInitImmediate(
407   Attri: TSynHighlighterAttributes; IsSpace: Boolean);
408 var
409   Span, StyleStr: String;
410   FG, BG: TColor;
411 begin
412   {$ifdef debug_synexporthtml}
413   debugln(['TSynExporterHTML.FormatAttributeInitImmediate']);
414   {$endif}
415   FG := ValidatedColor(Attri.Foreground, fFont.Color);
416   BG := ValidatedColor(Attri.Background, fBackgroundColor);
417   if (not IsSpace and (FG <> fFont.Color)) or
418      (UseBackGround and (BG <> fbackGroundColor)) then
419   begin
420     Span := MakeFontSpan(FG, BG);
421     AddData(Span);
422   end;
423   if (Attri.Style <> []) then
424   begin
425     StyleStr := StyleToHtml(Attri.Style, IsSpace, True);
426     AddData(StyleStr);
427   end;
428 end;
429 
430 procedure TSynExporterHTML.FormatAttributeDoneImmediate(
431   Attri: TSynHighlighterAttributes; IsSpace: Boolean);
432 var
433   FG, BG: TColor;
434   StyleStr: String;
435 begin
436   {$ifdef debug_synexporthtml}
437   debugln(['TSynExporterHTML.FormatAttributeDoneImmediate']);
438   {$endif}
439   //reversed order compared to FormatAttributeInitImmediate
440   if (Attri.Style <> []) then
441   begin
442     StyleStr := StyleToHtml(Attri.Style, IsSpace, False);
443     AddData(StyleStr);
444   end;
445   FG := ValidatedColor(Attri.Foreground, fFont.Color);
446   BG := ValidatedColor(Attri.Background, fBackgroundColor);
447   if (not IsSpace and (FG <> fFont.Color)) or
448      (UseBackGround and (BG <> fbackGroundColor)) then
449   begin
450     AddData('</span>');
451   end;
452 
453 end;
454 
455 {end}                                                                           //mh 2000-10-10
456 
457 procedure TSynExporterHTML.FormatNewLine;
458 begin
459   AddNewLine;
460 end;
461 
GetFooternull462 function TSynExporterHTML.GetFooter: string;
463 begin
464   Result := FontEnd + LineEnding + CodeEnd;
465   if (heoWinClipHeader in Options) then
466     Result := Result + EndFragmentComment;
467 
468   if not (heoFragmentOnly in Options) then
469   begin
470     if (Result <> '') then Result := Result + LineEnding;
471     Result := Result + DocumentEnd;
472   end;
473 end;
474 
GetFormatNamenull475 function TSynExporterHTML.GetFormatName: string;
476 begin
477   Result := SYNS_ExporterFormatHTML;
478 end;
479 
TSynExporterHTML.GetHeadernull480 function TSynExporterHTML.GetHeader: string;
481 var
482   sFontSize: string;                                                            //eb 2000-10-12
483   DocHeader, HeadText, WinClipHeader, SFooter: String;
484   WinClipHeaderSize, FooterLen: Integer;
485 begin
486   Result := '';
487   DocHeader := '';
488   if not (heoFragmentOnly in Options) then
489   begin
490     if (heoDocType in fOptions) then
491       DocHeader := DocHeader + DocType + LineEnding;
492     HeadText := Generator;
493     if (heoCharSet in fOptions) then
494       HeadText := HeadText + LineEnding + CharSet;
495     HeadText := HeadText + LineEnding + Format('<title>%s</title>',[Title]);
496     DocHeader := DocHeader + Format(DocumentStart,[HeadText,ColorToHtml(fFont.Color),ColorToHTML(fBackgroundColor)]);
497     if (heoWinClipHeader in fOptions) then
498       DocHeader := DocHeader + LineEnding + StartFragmentComment;
499     DocHeader := DocHeader + CodeStart; //Don't add LineEndings after this point, because of <pre> tag
500   end  //not heoFragmentOnly
501   else
502   begin
503     if (heoWinClipHeader in fOptions) then
504       DocHeader := DocHeader + StartFragmentComment + CodeStart
505     else
506       DocHeader := DocHeader + CodeStart;
507   end;
508   if fFontSize <> fsDefault then
509     sFontSize := Format(' size=%d', [1 + Ord(fFontSize)])
510   else
511     sFontSize := '';
512   DocHeader := DocHeader + Format(FontStart,[sFontSize, fFont.Name]);
513 
514   if (heoWinClipHeader in fOptions) then
515   begin
516     WinClipHeaderSize := Length(Format(WinClipHeaderFmt,[0,0,0,0]));
517     SFooter := GetFooter;
518     FooterLen := Length(SFooter);
519 
520     {$ifdef debug_synexporthtml}
521     debugln(['TSynExporterHtml.GetHeader: WinClipHeaderSize=',WinClipHeadersize]);
522     debugln(['  Footer="',Sfooter,'"']);
523     debugln(['  FooterLen=',FooterLen]);
524     debugln(['  BufferSize=',getBufferSize]);
525     debugln(['  length(docHeader)=',length(docheader)]);
526     {$endif}
527 
528     // Described in http://msdn.microsoft.com/library/sdkdoc/htmlclip/htmlclipboard.htm
529     WinClipHeader := Format(WinClipHeaderFmt,
530       [WinClipHeaderSize,  //HtmlStart
531        WinClipHeaderSize + Length(DocHeader) + FooterLen + GetBufferSize - 1, //HtmlEnd
532        WinClipHeaderSize + Utf8Pos(StartFragmentComment, DocHeader) + Length(StartfragmentComment) - 1, //StartFragment
533        WinClipHeaderSize + Length(DocHeader) + Utf8Pos(EndFragmentComment, SFooter) + GetBufferSize - 1  //EndFragment
534       ]);
535       DocHeader := WinClipHeader + DocHeader;
536   end;
537 
538   Result := DocHeader;
539 end;
540 
541 procedure TSynExporterHTML.SetExportAsText(Value: boolean);
542 begin
543   if (Value <> ExportAsText) then
544   begin
545     inherited SetExportAsText(Value);
546     if Value then
547       fOptions := fOptions - [heoWinClipHeader];
548   end;
549 end;
550 
551 procedure TSynExporterHTML.SetExportHtmlOptions(Value: TExportHtmlOptions);
552 begin
553   if (fOptions <> Value) then
554   begin
555     Clear;
556     fOptions := Value;
557     if ExportAsText then fOptions := fOptions - [heoWinClipHeader];
558     if (heoFragmentOnly in Value) then
559     begin
560       fOptions := fOptions - [heoDoctype, heoCharSet];
561     end;
562   end;
563 end;
564 
GetCreateHTMLFragmentnull565 function TSynExporterHTML.GetCreateHTMLFragment: Boolean;
566 begin
567   Result := (heoFragmentOnly in fOptions);
568 end;
569 
570 procedure TSynExporterHTML.SetCreateHTMLFragment(Value: Boolean);
571 begin
572   if (GetCreateHTMLFragment <> Value) then
573   begin
574     if Value then
575       Options := Options + [heoFragmentOnly]
576     else
577       Options := Options - [heoFragmentOnly];
578   end;
579 end;
580 
MakeFontSpannull581 function TSynExporterHTML.MakeFontSpan(FG, BG: TColor): String;
582 begin
583   Result := '<span style="color: ';
584   FG := ValidatedColor(FG, fFont.Color);
585   Result := Result + ColorToHtml(FG);
586   BG := ValidatedColor(BG, fBackgroundColor);
587   if UseBackGround then
588   begin
589     Result := Result + '; background-color: ' + ColorToHtml(BG);
590   end;
591   Result := Result + ';">';
592 end;
593 
StyleToHtmlnull594 function TSynExporterHTML.StyleToHtml(AStyle: TFontStyles; IsSpace, DoSet: Boolean): String;
595 begin
596   Result := '';
597   if DoSet then
598   begin
599     if not IsSpace then
600     begin
601       if (fsBold in AStyle) then Result := Result + '<b>';
602       if (fsItalic in AStyle) then Result := Result + '<i>';
603       if (fsUnderline in AStyle) then Result := Result + '<u>';
604     end;
605     //the only style that actually is applied to whitespace in HTML
606     if (fsStrikeOut in AStyle) then Result := Result + '<strike>';
607   end
608   else
609   begin //unset in the opposite order as set
610     if (fsStrikeOut in AStyle) then Result := Result + '</strike>';
611     if not IsSpace then
612     begin
613       if (fsUnderline in AStyle) then Result := Result + '</u>';
614       if (fsItalic in AStyle) then Result := Result + '</i>';
615       if (fsBold in AStyle) then Result := Result + '</b>';
616     end;
617   end;
618 end;
619 
620 end.
621 
622