lazarus/components/wiki/wikiconvert.lpr

372 lines
12 KiB
ObjectPascal

{ Converter for wiki pages to fpdoc, html, xhtml
Copyright (C) 2012 Mattias Gaertner mattias@freepascal.org
This source is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
This code is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
A copy of the GNU General Public License is available on the World Wide Web
at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
}
program wikiconvert;
{$mode objfpc}{$H+}
uses
Classes, SysUtils, CustApp, WikiParser, WikiFormat,
Wiki2XHTMLConvert, Wiki2HTMLConvert, Wiki2CHMConvert, Wiki2FPDocConvert,
LazFileUtils, FileUtil, LazLogger, KeywordFuncLists;
type
{ TWiki2FPDocApplication }
TWiki2FPDocApplication = class(TCustomApplication)
private
FCHMConverter: TWiki2CHMConverter;
FConverter: TWiki2FormatConverter;
FFPDocConverter: TWiki2FPDocConverter;
FHTMLConverter: TWiki2HTMLConverter;
FLanguageTags: TKeyWordFunctionList;
FQuiet: boolean;
FVerbose: boolean;
FXHTMLConverter: TWiki2XHTMLConverter;
procedure SetQuiet(AValue: boolean);
procedure SetVerbose(AValue: boolean);
procedure Test;
protected
procedure DoRun; override;
procedure SearchFileFound(FileIterator: TFileIterator);
procedure AddFiles(aFileMask: string);
public
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;
procedure WriteHelp; virtual;
property FPDocConverter: TWiki2FPDocConverter read FFPDocConverter;
property XHTMLConverter: TWiki2XHTMLConverter read FXHTMLConverter;
property HTMLConverter: TWiki2HTMLConverter read FHTMLConverter;
property CHMConverter: TWiki2CHMConverter read FCHMConverter;
property Converter: TWiki2FormatConverter read FConverter;
property LanguageTags: TKeyWordFunctionList read FLanguageTags;
property Verbose: boolean read FVerbose write SetVerbose;
property Quiet: boolean read FQuiet write SetQuiet;
end;
{ TMyApplication }
procedure TWiki2FPDocApplication.DoRun;
var
i: Integer;
Param: String;
ParamName: String;
p: SizeInt;
ParamValue: String;
procedure E(ErrorMsg: string; ShowHelp: boolean = false);
begin
writeln('ERROR: ',ErrorMsg);
if ShowHelp then WriteHelp;
Terminate;
end;
begin
//Test;
// parse parameters
// first parse --format= to give nicer help
if HasOption('format') then begin
Param:=GetOptionValue('format');
if Param='fpdoc' then
fConverter:=FPDocConverter
else if Param='xhtml' then
fConverter:=XHTMLConverter
else if Param='html' then
fConverter:=HTMLConverter
else if Param='chm' then
fConverter:=CHMConverter
else begin
writeln('Error: invalid format: '+Param);
writeln('use option -h to see all formats');
Terminate; exit;
end;
end;
if HasOption('h','help') then begin
WriteHelp;
Terminate; exit;
end;
if not HasOption('format') then begin
writeln('Error: missing option --format=');
writeln('use option -h to see all options');
Terminate;
exit;
end;
// wiki files
for i:=1 to ParamCount do begin
Param:=ParamStrUTF8(i);
if Param='' then continue;
if (length(Param)>2) and (Param[1]='-') and (Param[2]='-') then begin
ParamName:=copy(Param,3,length(Param));
if (Converter is TWiki2XHTMLConverter) then begin
if ParamName = 'nowikicategories' then begin
TWiki2XHTMLConverter(FConverter).AddCategories:= false;
continue;
end;
end;
p:=Pos('=',ParamName);
if p<1 then begin
E('invalid parameter "'+Param+'"');
exit;
end;
ParamValue:=copy(ParamName,p+1,length(ParamName));
ParamName:=copy(ParamName,1,p-1);
// general parameters
if ParamName='format' then begin
// already handled above
continue;
end else if ParamName='outputdir' then begin
Param:=TrimAndExpandDirectory(ParamValue);
if not DirPathExists(Param) then begin
E('outputdir not found: '+Param);
exit;
end;
Converter.OutputDir:=Param;
continue;
end else if ParamName='imagesdir' then begin
Param:=TrimAndExpandDirectory(ParamValue);
if not DirPathExists(Param) then begin
E('imagesdir not found: '+Param);
exit;
end;
Converter.ImagesDir:=Param;
continue;
end else if ParamName='title' then begin
Converter.Title:=ParamValue;
continue;
end else if ParamName='nowarnurl' then begin
Converter.NoWarnBaseURLs[ParamName]:='1';
continue;
end;
if Converter is TWiki2FPDocConverter then begin
// FPDoc parameters
if ParamName='root' then begin
TWiki2FPDocConverter(Converter).RootName:=ParamValue;
continue;
end
else if ParamName='package' then begin
TWiki2FPDocConverter(Converter).PackageName:=ParamValue;
continue;
end;
end;
if Converter is TWiki2HTMLConverter then begin
// HTML parameters
if ParamName='html' then begin
ParamValue := TrimAndExpandFilename(ParamValue);
if (ParamValue='') or (not DirPathExists(ExtractFilepath(ParamValue)))
then begin
E('Directory for html files does not exist: '+Paramvalue);
exit;
end;
TWiki2HTMLConverter(Converter).OutputDir := ExtractFilepath(Paramvalue);
Continue;
end;
end;
if Converter is TWiki2CHMConverter then begin
// CHM parameters
if ParamName='chm' then begin
ParamValue:=TrimAndExpandFilename(ParamValue);
if (ParamValue='') or (not DirPathExists(ExtractFilePath(ParamValue)))
then begin
E('directory of chm file does not exist: '+ParamValue);
exit;
end;
TWiki2CHMConverter(Converter).CHMFile:=ParamValue;
TWiki2CHMConverter(Converter).OutputDir := ExtractFilepath(ParamValue);
continue;
end else
if ParamName='root' then begin
TWiki2CHMConverter(Converter).TOCRootName := ParamValue;
Continue;
end;
end;
if Converter is TWiki2XHTMLConverter then begin
// shared parameters for HTML and CHM
if ParamName='css' then begin
TWiki2XHTMLConverter(Converter).CSSFilename:=ParamValue;
continue;
end;
end;
end else if Param[1]<>'-' then begin
AddFiles(Param);
if Terminated then exit;
end else begin
E('unknown parameter "'+Param+'"');
exit;
end;
end;
if Converter.Count=0 then begin
writeln('Error: give at last one wiki file');
WriteHelp;
Terminate; exit;
end;
Converter.OutputDir:=TrimAndExpandDirectory(Converter.OutputDir);
Converter.ImagesDir:=TrimAndExpandDirectory(Converter.ImagesDir);
Converter.Convert;
// stop program loop
Terminate;
end;
procedure TWiki2FPDocApplication.SearchFileFound(FileIterator: TFileIterator);
var
Filename: String;
begin
Filename:=TrimAndExpandFilename(FileIterator.FileName);
Converter.AddWikiPage(Filename);
end;
procedure TWiki2FPDocApplication.AddFiles(aFileMask: string);
var
Filename: String;
Search: TFileSearcher;
begin
if (Pos('*',aFileMask)>0) or (Pos('?',aFileMask)>0) then begin
// file mask
Search:=TFileSearcher.Create;
try
Search.OnFileFound:=@SearchFileFound;
Search.Search(ExtractFilePath(aFileMask),ExtractFilename(aFileMask),false);
finally
Search.Free;
end;
end else begin
// single file
Filename:=TrimAndExpandFilename(aFileMask);
if not FileExistsUTF8(Filename) then begin
writeln('Error: wiki file not found: ',Filename);
Terminate; exit;
end;
if DirPathExists(Filename) then begin
writeln('Error: wiki file is a directory: ',Filename,'. Note: You can use file masks.');
Terminate; exit;
end;
Converter.AddWikiPage(Filename);
end;
end;
procedure TWiki2FPDocApplication.Test;
procedure t(Page: string);
var
Filename: String;
NewPage: String;
begin
Filename:=WikiPageToFilename(Page,false,true);
NewPage:=WikiFilenameToPage(Filename);
writeln('t Page="',Page,'" NewPage="',NewPage,'" File="',Filename,'" Fits=',Page=NewPage);
end;
begin
t('ACS_demo.jpg');
Halt;
end;
procedure TWiki2FPDocApplication.SetQuiet(AValue: boolean);
begin
if FQuiet=AValue then Exit;
FQuiet:=AValue;
if Converter<>nil then
Converter.Quiet:=Quiet;
end;
procedure TWiki2FPDocApplication.SetVerbose(AValue: boolean);
begin
if FVerbose=AValue then Exit;
FVerbose:=AValue;
if Converter<>nil then
Converter.Verbose:=Verbose;
end;
constructor TWiki2FPDocApplication.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
StopOnException:=True;
FLanguageTags:=WikiCreateCommonCodeTagList(true);
FFPDocConverter:=TWiki2FPDocConverter.Create;
FPDocConverter.CodeTags:=LanguageTags;
FXHTMLConverter:=TWiki2XHTMLConverter.Create;
XHTMLConverter.CodeTags:=LanguageTags;
FHTMLConverter:=TWiki2HTMLConverter.Create;
HTMLConverter.CodeTags:=LanguageTags;
FCHMConverter:=TWiki2CHMConverter.Create;
CHMConverter.CodeTags:=LanguageTags;
FConverter:=FHTMLConverter;
end;
destructor TWiki2FPDocApplication.Destroy;
begin
FreeAndNil(FCHMConverter);
FreeAndNil(FHTMLConverter);
FreeAndNil(FXHTMLConverter);
FreeAndNil(FFPDocConverter);
FreeAndNil(FLanguageTags);
inherited Destroy;
end;
procedure TWiki2FPDocApplication.WriteHelp;
begin
writeln('Usage: ',ExeName,' -h');
writeln;
writeln(' -h or --help : this help');
writeln(' --format=[fpdoc|html|xhtml|chm]');
writeln(' --outputdir=<output directory> : directory for all files. default: ',Converter.OutputDir);
writeln(' --imagesdir=<images directory> : directory of image files. default: ',Converter.ImagesDir);
writeln(' --title=<string> : the title of the wiki. default: "',Converter.Title,'"');
writeln(' --nowarnurl=<string> : do not warn for URLs starting with this. Can be given multiple times.');
writeln(' --verbose');
writeln(' --quiet');
writeln(' <inputfile> : wiki page in xml format, can be given multiple times');
writeln(' Duplicates are ignored.');
writeln(' You can use globbing, like "wikixml/*.xml". You must quote such parameters on console/shell.');
writeln;
writeln('Options for --format=xhtml,html,chm :');
writeln(' --css=<path of stylesheet> : default: ',XHTMLConverter.CSSFilename);
writeln(' --nowikicategories : do not add links to wiki categories.');
writeln;
writeln('Options for --format=chm :');
writeln(' Note: the default page is the first page');
writeln(' --chm=<output chm file> : default: ',CHMConverter.CHMFile);
writeln(' --root=<text used for root of table-of-contents> : default: "', CHMConverter.TocRootName, '"');
writeln;
writeln('Options for --format=fpdoc :');
writeln(' --root=<fpdoc xml root node> : default: ',FPDocConverter.RootName);
writeln(' --package=<fpdoc package name> : default: ',FPDocConverter.PackageName);
writeln;
writeln('Examples:');
writeln(' ',ParamStrUTF8(0),' --format=html --outputdir=html --css=html/wiki.css "wikixml/*.xml"');
writeln(' ',ParamStrUTF8(0),' --format=fpdoc --outputdir=fpdocxml wikipage1.xml wikipage2.xml');
end;
var
Application: TWiki2FPDocApplication;
begin
Application:=TWiki2FPDocApplication.Create(nil);
Application.Title:='WikiConvert';
Application.Run;
Application.Free;
end.