synexporttex.pas
来自「一个mwEdit控件原码,比mwCuuEdit0.92a功能先进.」· PAS 代码 · 共 399 行
PAS
399 行
{-------------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: SynExportTeX.pas, released 2002-09-12.
The Original Code is partly based on the mwHTMLExport.pas file from the
mwEdit component suite by Martin Waldenburg and other developers, the Initial
Author of this file is Ascher Stefan.
Portions created by Ascher Stefan are Copyright 2002 Ascher Stefan.
All Rights Reserved.
Contributors to the SynEdit project are listed in the Contributors.txt file.
Alternatively, the contents of this file may be used under the terms of the
GNU General Public License Version 2 or later (the "GPL"), in which case
the provisions of the GPL are applicable instead of those above.
If you wish to allow use of your version of this file only under the terms
of the GPL and not to allow others to use your version of this file
under the MPL, indicate your decision by deleting the provisions above and
replace them with the notice and other provisions required by the GPL.
If you do not delete the provisions above, a recipient may use your version
of this file under either the MPL or the GPL.
$Id: SynExportTeX.pas,v 1.5 2004/03/04 22:47:35 maelh Exp $
You may retrieve the latest version of this file at the SynEdit home page,
located at http://SynEdit.SourceForge.net
Known Issues:
-------------------------------------------------------------------------------}
{$IFNDEF QSYNEXPORTTEX}
unit SynExportTeX;
{$ENDIF}
{$I SynEdit.inc}
interface
uses
{$IFDEF SYN_CLX}
Qt,
QGraphics,
QSynEditExport,
QSynEditHighlighter,
{$ELSE}
Windows,
Graphics,
SynEditExport,
SynEditHighlighter,
{$ENDIF}
Classes;
type
TSynExporterTeX = class(TSynCustomExporter)
private
fMargin: integer;
fLastToken: TSynHighlighterAttributes;
function GetNewCommands: string;
function AttriStyleName(const AName: string): string;
protected
fCreateTeXFragment: boolean;
fTabWidth: integer;
fPageStyleEmpty: boolean;
procedure FormatNewLine; override;
function GetFooter: string; override;
function GetFormatName: string; override;
function GetHeader: string; override;
procedure SetTokenAttribute(IsSpace: Boolean; Attri: TSynHighlighterAttributes); override;
procedure FormatToken(Token: String); override;
// overriding these as they are abstract, and though will never be called,
// this will prevent abstract instance warnings
procedure FormatAfterLastAttribute; override;
procedure FormatAttributeDone(BackgroundChanged: Boolean;
ForegroundChanged: Boolean; FontStylesChanged: TFontStyles); override;
procedure FormatAttributeInit(BackgroundChanged: Boolean;
ForegroundChanged: Boolean; FontStylesChanged: TFontStyles); override;
procedure FormatBeforeFirstAttribute(BackgroundChanged: Boolean;
ForegroundChanged: Boolean; FontStylesChanged: TFontStyles); override;
public
constructor Create(AOwner: TComponent); override;
published
property Margin: integer read fMargin write fMargin default 2;
property TabWidth: integer read fTabWidth write fTabWidth default 2;
property Color;
property CreateTeXFragment: boolean read fCreateTeXFragment
write fCreateTeXFragment default false;
property PageStyleEmpty: boolean read fPageStyleEmpty write fPageStyleEmpty
default false;
property DefaultFilter;
property Font;
property Highlighter;
property Title;
property UseBackground;
end;
implementation
uses
{$IFDEF SYN_CLX}
QSynEditMiscProcs,
QSynEditStrConst,
QSynHighlighterMulti,
{$ELSE}
SynEditStrConst,
SynHighlighterMulti,
{$ENDIF}
SysUtils;
const
{$IFDEF SYN_WIN32}
NewLine = #13#10;
{$ELSE}
NewLine = #10;
{$ENDIF}
function ReplaceDecSep(const AIn: string): string;
var
p: PChar;
begin
// LaTeX uses a Dot as decimal separator, in some languages a comma is used.
p := PChar(AIn);
while p^ <> #0 do begin
if p^ = #44 then
Result := Result + #46
else
Result := Result + p^;
Inc(p);
end;
end;
function ColorToTeX(AColor: TColor): string;
const
f = '%1.2g';
f2 = '%s,%s,%s';
var
RGBColor: longint;
RValue, GValue, BValue: string;
begin
RGBColor := ColorToRGB(AColor);
RValue := ReplaceDecSep(Format(f, [GetRValue(RGBColor) / 255]));
GValue := ReplaceDecSep(Format(f, [GetGValue(RGBColor) / 255]));
BValue := ReplaceDecSep(Format(f, [GetBValue(RGBColor) / 255]));
Result := Format(f2, [RValue, GValue, BValue]);
end;
{ TSynExporterTeX }
constructor TSynExporterTeX.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
fMargin := 2;
fTabWidth := 2;
fPageStyleEmpty := false;
fDefaultFilter := SYNS_FilterTeX;
// setup array of chars to be replaced
fReplaceReserved['{'] := '\{';
fReplaceReserved['}'] := '\}';
fReplaceReserved['\'] := '\BS ';
fReplaceReserved['~'] := '\TLD ';
fReplaceReserved['^'] := '\CIR ';
fReplaceReserved[' '] := '\SPC ';
fReplaceReserved[#9] := '\TAB ';
fReplaceReserved['-'] := '\HYP ';
fReplaceReserved['"'] := '\QOT ';
fReplaceReserved['@'] := '$@$';
fReplaceReserved['$'] := '\$';
fReplaceReserved['&'] := '\&';
fReplaceReserved['<'] := '$<$';
fReplaceReserved['>'] := '$>$';
fReplaceReserved['_'] := '\_';
fReplaceReserved['#'] := '\#';
fReplaceReserved['%'] := '\%';
end;
procedure TSynExporterTeX.SetTokenAttribute(IsSpace: Boolean;
Attri: TSynHighlighterAttributes);
begin
fLastToken := Attri;
end;
procedure TSynExporterTeX.FormatToken(Token: String);
const
SToken = '\hspace*{%sem}';
f = '%1.1g';
function FindHighFromAttri(Attri: TSynHighlighterAttributes): TSynCustomHighlighter;
var
i, j: integer;
begin
Result := Highlighter;
with (Highlighter as TSynMultiSyn) do begin
for j := 0 to DefaultHighlighter.AttrCount - 1 do
if DefaultHighlighter.Attribute[j] = Attri then begin
Result := DefaultHighlighter;
Exit;
end;
for i := 0 to Schemes.Count - 1 do
for j := 0 to Schemes[i].Highlighter.AttrCount - 1 do
if Schemes[i].Highlighter.Attribute[j] = Attri then begin
Result := Schemes[i].Highlighter;
Exit;
end;
end;
end;
begin
if not (Highlighter is TSynMultiSyn) then
AddData(Format('\%s{%s}', [AttriStyleName(fLastToken.Name), Token]))
else
AddData(Format('\%s{%s}', [AttriStyleName(
FindHighFromAttri(fLastToken).LanguageName + fLastToken.Name), Token]));
end;
procedure TSynExporterTeX.FormatNewLine;
begin
AddData('\\' + NewLine);
end;
// do nothing with these
procedure TSynExporterTeX.FormatAfterLastAttribute;
begin
end;
procedure TSynExporterTeX.FormatAttributeDone;
begin
end;
procedure TSynExporterTeX.FormatAttributeInit;
begin
end;
procedure TSynExporterTeX.FormatBeforeFirstAttribute;
begin
end;
function TSynExporterTeX.GetFooter: string;
begin
if not fCreateTeXFragment then
Result := NewLine + '\end{ttfamily}' + NewLine + '\end{document}'
else
Result := NewLine + '\end{ttfamily}';
end;
function TSynExporterTeX.GetFormatName: string;
begin
Result := SYNS_LangTeX;
end;
// the purpose of this function is to leave only valid characters in AName
function TSynExporterTeX.AttriStyleName(const AName: string): string;
var
pCurr: PChar;
begin
Result := '';
pCurr := PChar(AName);
while pCurr^ <> #0 do begin
if pCurr^ in ['A'..'Z', 'a'..'z'] then
Result := Result + pCurr^;
Inc(pCurr);
end;
end;
function TSynExporterTeX.GetNewCommands: string;
const
FixedCommands = '%% Special Characters' + NewLine +
'\newcommand\SPC{\hspace*{0.6em}}' + NewLine +
'\newcommand\TAB{\hspace*{%sem}}' + NewLine +
'\newcommand\BS{\mbox{\char 92}}' + NewLine + // Backslash
'\newcommand\TLD{\mbox{\char 126}}' + NewLine + // ~
'\newcommand\CIR{\mbox{\char 94}}' + NewLine + // ^
'\newcommand\HYP{\mbox{\char 45}}' + NewLine + // a simple -
'\newcommand\QOT{\mbox{\char 34}}' + NewLine + // "
'\newcommand{\uln}[1]{\bgroup \markoverwith{\hbox{\_}}\ULon{{#1}}}' + NewLine +
'%% Highlighter Attributes' + NewLine;
NewCommand = '\newcommand{\%s}[1]{%s%s%s%s%s#1%s}' + NewLine;
SBold = '\textbf{';
SItalic = '\textit{';
SUnderline = '\uln{';
SColor = '\textcolor[rgb]{%s}{';
SBackColor = '\colorbox[rgb]{%s}{';
f = '%1.1g';
function GetAttriCommand(AHigh: TSynCustomHighlighter; Attri: TSynHighlighterAttributes): string;
var
bold, italic, underline, color, backcol: string;
b: integer;
begin
with Attri do begin
b := 0;
if fsBold in Style then begin
bold := SBold;
Inc(b);
end else
bold := '';
if fsItalic in Style then begin
italic := SItalic;
Inc(b);
end else
italic := '';
if fsUnderline in Style then begin
underline := SUnderline;
Inc(b);
end else
underline := '';
if (Foreground <> clBlack) and (Foreground <> clNone) then begin
color := Format(SColor, [ColorToTeX(Foreground)]);
Inc(b);
end else
color := '';
if fUseBackground and (Background <> clNone) then begin
backcol := Format(SBackColor, [ColorToTeX(Background)]);
Inc(b);
end else
backcol := '';
if not (Highlighter is TSynMultiSyn) then
Result := Format(NewCommand, [AttriStyleName(Name), bold, italic, color,
backcol, underline, StringOfChar('}', b)])
else
Result := Format(NewCommand, [AttriStyleName(AHigh.LanguageName + Name),
bold, italic, color, backcol, underline, StringOfChar('}', b)]);
end;
end;
function GetHighlighterCommand(AHigh: TSynCustomHighlighter): string;
var
i: integer;
begin
Result := '';
for i := 0 to AHigh.AttrCount - 1 do
Result := Result + GetAttriCommand(AHigh, AHigh.Attribute[i]);
end;
var
i: integer;
tw: string;
begin
tw := ReplaceDecSep(Format(f, [fTabWidth * 0.6]));
Result := Format(FixedCommands, [tw]);
if (Highlighter is TSynMultiSyn) then begin
with (Highlighter as TSynMultiSyn) do begin
Result := Result + GetAttriCommand(Highlighter, Attribute[0]); // Marker
Result := Result + GetHighlighterCommand(DefaultHighlighter);
for i := 0 to Schemes.Count - 1 do
Result := Result + GetHighlighterCommand(Schemes[i].Highlighter)
end;
end else
Result := Result + GetHighlighterCommand(Highlighter);
end;
function TSynExporterTeX.GetHeader: string;
const
TeXHeader = '\documentclass[a4paper, %dpt]{article}' + NewLine +
'\usepackage[a4paper, margin=%dcm]{geometry}' + NewLine +
'\usepackage[T1]{fontenc}' + NewLine +
'\usepackage{color}' + NewLine +
'\usepackage{alltt}' + NewLine +
'\usepackage{times}' + NewLine +
'\usepackage{ulem}' + NewLine +
{$IFDEF WIN32}
// It is recommennded to use AnsiNew on Windows
'\usepackage[ansinew]{inputenc}' + NewLine +
{$ELSE}
// and Latin1 on UNIX Systems, see also DE FAQ 8.5.3
'\usepackage[latin1]{inputenc}' + NewLine +
{$ENDIF}
'%s' + NewLine + // New Commands
'\title{%s}' + NewLine +
'%% Generated by SynEdit TeX exporter' + NewLine + NewLine +
'\begin{document}%s';
EmptyPage = '\pagestyle{empty}';
TeXDocument = '\begin{ttfamily}' + NewLine +
'\noindent' + NewLine;
var
PageStyle: string;
begin
if not fCreateTeXFragment then begin
if fPageStyleEmpty then
PageStyle := NewLine + EmptyPage
else
PageStyle := '';
Result := Format(TeXHeader + NewLine + NewLine,
[Font.Size, fMargin, GetNewCommands, Title, PageStyle]);
end;
Result := Result + TeXDocument;
end;
end.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?