📄 usavetranslation.pas
字号:
{ JADD - Just Another DelphiDoc: Documentation from Delphi Source Code
Copyright (C) 2006-2008 Gerold Veith
This file is part of JADD - Just Another DelphiDoc.
DelphiDoc is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as
published by the Free Software Foundation.
DelphiDoc 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.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
}
unit USaveTranslation;
{Contains a pseudo-generator, ~[link TSaveTranslation], to save/export the
currently set of translated strings to a new unit that can be used
subsequently in this project. }
interface
uses UOptions, UGenerationMessages, UMakeDoc;
type
{ * * * *** * * * *** TSaveTranslation *** * * * *** * * * }
{The messages that can be generated by the pseudo-generator of class
~[link TSaveTranslation]. }
TSaveTranslationMessageKind = (
//a text might not have been translated
stmkMaybeNotTranslated
);
{This is not a generator of documentation about parsed Pascal source code,
instead it generates a Pascal unit containing the current translated values
for texts that can be included in above mentioned documentation. The unit
can then simply be included in this project (in unit
~[link UDocumentationTexts]) so the translated texts can be used. }
TSaveTranslation = class(TMakeDoc)
private
//ID of the messages of this class
FSaveTranslationMessagesID: TMessageID;
{used as base for names of identifiers (U$Texts, DocumentationTexts$),
used in comments (+ copyright notice?), registered with }
FLanguageNameEnglish: String;
//registered with
FLanguageNameItself: String;
//registered with
FLanguageCode: String;
//for copyright notice
FTranslatorName: String;
//used for comparison
FTranslationBaseLanguage: String;
protected
//Process parsed data; extract the source code into files.
function DoGenerateDocumentation: Boolean; override;
public
//Creates the generator object.
constructor Create; override;
//Destroys the generator object.
destructor Destroy; override;
//Returns a description of the documentation of the generator.
class function GetDescription: TGeneratorDescription; override;
//Returns the number of available options in this class.
class function GetOptionCount: Cardinal; override;
//Gets a description of an option.
class procedure GetOptionDescription(Index: Cardinal;
var Desc: TOptionDescription);
override;
//Gets the value of an option.
function GetOption(Index: Cardinal): TOptionValue; override;
//Sets the value of an option.
procedure SetOption(Index: Cardinal; const Value: TOptionValue); override;
end;
implementation
uses SysUtils,
General,
UPascalConsts,
UDocumentationTexts;
{ * * * *** * * * *** TSaveTranslation *** * * * *** * * * }
//the descriptions of messages that can be added in the class
//~[link TSaveTranslation]
var SaveTranslationMessageDescriptions: TMessageDescriptions = nil;
{Creates the generator object and the list of messages. }
constructor TSaveTranslation.Create;
begin
inherited Create; //create object
//register messages of this class
FSaveTranslationMessagesID := RegisterMessages(
SaveTranslationMessageDescriptions);
end;
{Destroys the generator object. }
destructor TSaveTranslation.Destroy;
begin
//unregister messages of this class
UnRegisterMessages(FSaveTranslationMessagesID);
inherited Destroy; //free the object
end;
{Returns a description of the documentation of the generator.
~result a description of the documentation of the generator }
class function TSaveTranslation.GetDescription: TGeneratorDescription;
begin
Result.Name := 'Save Translation';
Result.Identification := 'SaveTranslation';
Result.Description := 'This is a Pseudo-Generator!' + LineDelimiter +
'It saves the currently set translated texts that would be included in the documentation in a Pascal file ready to be included in this program as a unit.' + LineDelimiter +
'Please make sure all options in category "Translation" are correctly specified.';
end;
{Returns the number of available options in this class.
~result the number of available options }
class function TSaveTranslation.GetOptionCount: Cardinal;
begin
Result := inherited GetOptionCount + 5;
end;
{Gets a description of an option.
~param Index index of the option to get data of
~param Desc out: the description of the option (name, type, default value,
etc.)
~see GetOptionCount }
class procedure TSaveTranslation.GetOptionDescription(Index: Cardinal;
var Desc: TOptionDescription);
var PreOptionCount :Cardinal; //number of inherited options
begin
PreOptionCount := inherited GetOptionCount; //get number of inherited ones
if Index < PreOptionCount then //asked for inherited option?
inherited GetOptionDescription(Index, Desc) //forward to parent class
else
begin
ClearDescription(Desc); //clear structure
case Index - PreOptionCount of //depending on index of option
0: begin //set the values describing the option
Desc.Name := 'LanguageNameEnglish';
Desc.Category := 'Translation';
Desc.Description := 'The English name of the language the texts have been translated into (languages start with a capital letter).';
Desc.DataType := otString;
end;
1: begin
Desc.Name := 'LanguageNameItself';
Desc.Category := 'Translation';
Desc.Description := 'The name of the language in the language itself.';
Desc.DataType := otString;
end;
2: begin
Desc.Name := 'LanguageCode';
Desc.Category := 'Translation';
Desc.Description := 'The two (low) letter 639-1 ISO-Code for the language, f.i. "en", optionally after an underscore with the region, f.i. "en_US".';
Desc.DataType := otString;
Desc.StrMaxLen := 5; //two is normal, but sub-languages are: 'mm_SS'
end;
3: begin
Desc.Name := 'TranslatorName';
Desc.Category := 'Translation';
Desc.Description := 'The name of translator/author to be used for the copyright notice.';
Desc.DataType := otString;
end;
4: begin
Desc.Name := 'TranslationBaseLanguage';
Desc.Category := 'Translation';
Desc.Description := 'The name of the language the translation was based on. For every entry equal to the text in that language a notice will be logged.';
Desc.DataType := otString;
end;
else
assert(Index >= GetOptionCount);
raise EInvalidOption.Create('Invalid index for option supplied!');
end;
end;
end;
{Gets the value of an option. Call ~[link GetOptionDescription] to get the type
and the meaning of the option.
~param Index index of the option to get the value of
~result the value of the option }
function TSaveTranslation.GetOption(Index: Cardinal): TOptionValue;
var PreOptionCount :Cardinal; //number of inherited options
begin
PreOptionCount := inherited GetOptionCount; //get number of inherited ones
if Index < PreOptionCount then //asked for inherited option?
Result := inherited GetOption(Index) //forward to parent class
else
begin
case Index - PreOptionCount of //depending on index of option
0: Result.StrData := FLanguageNameEnglish; //get the value
1: Result.StrData := FLanguageNameItself;
2: Result.StrData := FLanguageCode;
3: Result.StrData := FTranslatorName;
4: Result.StrData := FTranslationBaseLanguage;
else
assert(Index >= GetOptionCount);
raise EInvalidOption.Create('Invalid index for option supplied!');
end;
end;
end;
{Sets the value of an option. Call ~[link GetOptionDescription] to get the type
and the meaning of the option.
~param Index index of the option to set the value
~param Value the new value of the option }
procedure TSaveTranslation.SetOption(Index: Cardinal;
const Value: TOptionValue);
{Sets the language code after checking it for validity. It only checks the
syntax and not whether the actual code really exists.
~param Code the ISO language code to set
~exception EInvalidOption if the code it not valid }
procedure SetLanguageCode(Code: String);
const Alpha = ['A'..'Z', 'a'..'z']; //all (valid) letters
begin
//the empty string has to be valid, for instance for resetting the options
if Code <> '' then //code not empty?
begin
if not (Length(Code) in [2, 5]) or //neither 'xx' nor 'xx[_-]XX' ?
not (Code[1] in Alpha) or not (Code[2] in Alpha) or
((Length(Code) = 5) and (not (Code[3] in ['_', '-']) or
not (Code[4] in Alpha) or not (Code[5] in Alpha))) then
raise EInvalidOption.CreateFmt('Invalid ISO 639-1 language (locale) code!: "%s"', [Code]);
//make sure the case is right when assigning, lower case for language
Code := LowerCase(Copy(Code, 1, 2)) + Copy(Code, 3, 3);
if length(Code) = 5 then //geographical region set?
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -