xEdit 的 Pascal 脚本 - 如何检查字符串中是否存在子字符串?
Pascal scripting for xEdit - how do I check whether a substring is present in a string?
看起来这应该很简单,但也许不是。完全披露:我无论如何都不是程序员。我只知道通过业余爱好项目混日子,Pascal 对我来说是全新的。所以,如果有什么是非常糟糕的代码,我愿意改进。不过,我可能只打算使用这个脚本一次,所以我不太关心优化,只关心可靠的操作。
我正在为 xEdit(又名 SSEEDit)编写脚本 - 大多数人使用该工具来处理不更改丰富游戏资产的 Skyrim 和 Fallout 4 模组。目标是为游戏中的每个 BOOK 对象(原版 + 原始 DLC)转储 DESC 属性 的原始文本内容。我已经走得很远了,对我在做什么有了很好的理解,但我这辈子都无法让这部分工作。
我有一个字符串黑名单,在遍历所有 BOOK 对象时应该跳过它。我已经尝试使用 pos()
几种不同的方式,但它永远不会返回零以外的任何东西。
奇怪的是,即使我在测试中可以从 pos()
中得到正确的结果,但当我 运行 我的实际脚本时,每本书都是正匹配。看起来我实际上并没有遍历黑名单中的第一个条目。
以下是我搜索黑名单条目时返回的示例:
EDID: DLC2dunFahlbtharzJournal02
looking in DLC2dunFahlbtharzJournal02
for DLC1ElderScroll...
skipped DLC2dunFahlbtharzJournal02
这不应该从 pos('DLC1ElderScroll','DLC2dunFahlbtharzJournal02')
返回 0...但它是。
(顺便说一句 - 如果你有 Skyrim SE,你只需要 SSEEdit 来测试它。)
这是我的完整脚本:
{
Dump book text
Dumps "book text" property of every vanilla book
Source for most copypasta:
https://github.com/AngryAndConflict/skyrim-utils/
}
unit UserScript;
uses mteFunctions;
// uses RegExpr;
function Initialize: integer;
var
f, group, e: IInterface;
i, j: integer;
btext,fname: String;
slItems: TStringList;
FileInfo: File_Content;
begin
AddMessage('Dumping books.....');
slItems := TStringList.Create;
// load item and perk stringlists
for i := 0 to FileCount - 1 do begin
f := FileByIndex(i);
group := GroupBySignature(f, 'BOOK');
for j := 0 to ElementCount(group) - 1 do begin
e := ElementByIndex(group, j);
slItems.Add(geev(e, 'EDID'));
// if it's a book, do things
if (isBook(e) = True) then begin
// this it the raw text content of each BOOK's DESC attribute
btext := geev(e,'DESC');
if (Length(btext) > 0) then begin
fname := ProgramPath + 'Output\' + (geev(e, 'EDID')) + '.txt';
// AddMessage('Successfully saved!');
// AddMessage(#9 + fname);
// AddMessage(#20);
// AddMessage('===ERROR=== Unable to save ' + fname + '!');
end;
end;
end;
end;
//AddMessage(btext)
end;
// check if item is book
// exclude blacklisted books and spell tomes
function isBook(item: IInterface): boolean;
var
formID,test: String;
blacklist: TStringList;
ignore: Boolean;
i,t: integer;
begin
Result := false;
ignore := false;
blacklist := TStringList.Create;
// blacklist to exclude - these are can be FormIDs or friendly names
blacklist.Add('DLC1ElderScroll');
blacklist.Add('DLC1FVBook01Falmer');
blacklist.Add('DLC1FVBook02Falmer');
blacklist.Add('DLC1FVBook03Falmer');
blacklist.Add('DLC1FVBook04Falmer');
blacklist.Add('DLC2BlackBook');
blacklist.Add('DA04ElderScroll');
blacklist.Add('ExpSpiderCrftBook');
blacklist.Add('QA');
blacklist.Add('Recipe');
formID := geev(item,'Record Header\FormID');
t := pos(blacklist(1),'Elder');
test := IntToStr(t);
AddMessage(test);
for i := 0 to (blacklist.Count - 1) do begin
if (pos(formID, blacklist(i)) >= 0) then begin
AddMessage('====' + formID + '====');
AddMessage(blacklist(i));
// AddMessage('skipped ' + formID);
ignore := true;
Result := false;
break;
end;
end;
// has Keyword excludes all spell tomes
if (Signature(item) = 'BOOK') and not (hasKeyword(item,'000937A5')) and not ignore then begin
Result := true;
end;
end;
end.{
Dump book text
Dumps "book text" property of every vanilla book
Source for most copypasta:
https://github.com/AngryAndConflict/skyrim-utils/
}
unit UserScript;
uses mteFunctions;
// uses RegExpr;
function Initialize: integer;
var
f, group, e: IInterface;
i, j: integer;
btext,fname: TString;
slItems: TStringList;
FileInfo: File_Content;
blacklist: TStringList;
begin
AddMessage('Dumping books.....');
slItems := TStringList.Create;
// load item and perk stringlists
for i := 0 to FileCount - 1 do begin
f := FileByIndex(i);
group := GroupBySignature(f, 'BOOK');
for j := 0 to ElementCount(group) - 1 do begin
e := ElementByIndex(group, j);
slItems.Add(geev(e, 'EDID'));
// if it's a book, do things
if (isBook(e) = True) then begin
// this it the raw text content of each BOOK's DESC attribute
btext := geev(e,'DESC');
if (Length(btext) > 0) then begin
fname := ProgramPath + 'Output\' + (geev(e, 'EDID')) + '.txt';
// AddMessage('Successfully saved!');
// AddMessage(#9 + fname);
// AddMessage(#20);
// AddMessage('===ERROR=== Unable to save ' + fname + '!');
end;
end;
// AddMessage('----------')
end;
end;
//AddMessage(btext)
end;
// check if item is book
// exclude blacklisted books and spell tomes
function isBook(item: IInterface): boolean;
var
formID,needle,haystack,test: TString;
blacklist: TStringList;
ignore: Boolean;
i,t,p: integer;
begin
Result := false;
ignore := false;
blacklist := TStringList.Create;
// blacklist to exclude - these are can be FormIDs or friendly names
blacklist.Add('DLC1ElderScroll');
blacklist.Add('DLC1FVBook01Falmer');
blacklist.Add('DLC1FVBook02Falmer');
blacklist.Add('DLC1FVBook03Falmer');
blacklist.Add('DLC1FVBook04Falmer');
blacklist.Add('DLC2BlackBook');
blacklist.Add('DA04ElderScroll');
blacklist.Add('ExpSpiderCrftBook');
blacklist.Add('QA');
blacklist.Add('Recipe');
formID := geev(item,'EDID');
for i := 0 to (blacklist.Count - 1) do begin
needle := blacklist[i];
haystack := formID;
// AddMessage('====' + formID + '====');
// AddMessage('looking in ' + haystack);
// AddMessage(#9 + ' for ' + needle + '...');
t := pos(haystack, needle);
test := IntToStr(t);
// AddMessage(test);
if (pos(blacklist[i], formID) >= 0) then begin
// AddMessage(blacklist[i]);
AddMessage('skipped ' + formID);
ignore := true;
break;
end;
end;
// hasKeyword excludes all spell tomes
if (not (Signature(item) = 'BOOK')) or (hasKeyword(item,'000937A5')) then begin
ignore := true;
end;
if ignore then begin
Result := false;
end;
if not ignore then begin
Result := true;
end;
end;
end.
继official Pascal documentation之后,pos
函数的正确调用是pos(SubString, SourceString)
。此外,我认为索引 TStringList
的正确方法是 blacklist[i]
.
您可以试试这个示例代码:
uses SysUtils, Classes;
var blacklist: TStringList;
begin
blacklist := TStringList.Create;
blacklist.Add('Black');
blacklist.Add('White');
WriteLn(Pos(blacklist[1], 'Robert White'));
ReadLn;
end.
输出:
8
似乎 SSEEdit 的捆绑 Pascal 引擎从 1 开始与 pos()
进行字符串匹配 - 只要我更改代码以排除 1 而不是 0,它就会按预期工作。
下面是脚本的重写,设置为仅打印消息而不写入任何文件:如果您对它的工作方式感到满意,只需将 14 行更改为
DRY_RUN = False;
让它实际将书籍内容转储到 Output 子文件夹中。
我从你连接的两个脚本中的后者开始,我认为这是你的最新版本。
主要变化:
- 只在
Initialize
中填充 blacklist
一次,不需要对每条记录都这样做;
- 你不需要检查你的记录是否是一本书,因为你已经在遍历
BOOK
组,所以我颠倒了逻辑,只检查编辑器 ID 是否包含任何字符串blacklist
;
- 你真的不需要
mteFunctions
,所以我删除了它并使用现有逻辑将编辑 ID 中带有 SpellTome
的记录列入黑名单 - 如果你需要再次检查关键字,您可以重新启用 mteFunctions
并使用其实用程序;
- 检查记录是否
IsMaster
然后仅在其 WinningOverride
上工作一次 - 这避免了多次处理同一条记录,以防被官方 DLC 或 mod 覆盖,参考:https://tes5edit.github.io/docs/13-Scripting-Functions.html#IwbMainRecord
小改动:
- 在使用任何
TStringList
; 后调用 Free
- 为系统单位添加
uses
子句 - 运行 xEdit 脚本实际上不需要,但如果您为 Delphi Pascal 使用 linter,则有助于捕获错误;
- 使用
Pred
而不是 Count - 1
- 结果应该是相同的,但看起来像在 Delphi 世界中进行迭代的标准方法;
- 在任何
begin
之前换行,以及遵循样式指南的其他类似更改:https://docwiki.embarcadero.com/RADStudio/Sydney/en/Delphi_Statements
{
Dump book text
Dumps "book text" property of every book in loaded plugins
Source for most copypasta:
https://github.com/AngryAndConflict/skyrim-utils/
}
unit UserScript;
interface
const
// change this to False to actually write the text files
DRY_RUN = True;
// change this to False if you want to continue after the first error
STOP_ON_ERROR = True;
implementation
uses
//mteFunctions,
System.Classes, // TStringList
System.SysUtils, // CreateDir, IntToStr
xEditAPI;
// check if rec editor ID contains any string in blacklist
function IsBlacklisted(rec: IwbMainRecord; blacklist: TStringList): Boolean;
var
i: Cardinal;
edid: string;
//needle, haystack: string;
begin
Result := False;
edid := EditorID(rec);
for i := 0 to Pred(blacklist.Count) do
begin
//needle := blacklist[i];
//haystack := edid;
//AddMessage('====' + edid + '====');
//AddMessage('looking in ' + haystack);
//AddMessage(#9 + ' for ' + needle + '...');
//AddMessage(' test: ' + IntToStr(Pos(needle, haystack));
if (Pos(blacklist[i], edid) > 0) then
begin
Result := True;
//AddMessage(blacklist[i]);
AddMessage('Skipping: ' + edid);
Break;
end;
end;
end;
function Initialize: Integer;
var
i, j: Cardinal;
f: IwbFile;
bookGroup: IwbGroupRecord;
book: IwbMainRecord;
btext, outputPath, fname: string;
blacklist, output: TStringList;
begin
Result := 0;
outputPath := ProgramPath + 'Output\';
if not DRY_RUN then
begin
CreateDir(outputPath);
end;
blacklist := TStringList.Create;
try
// match editor IDs containing any of following
blacklist.Add('DLC1ElderScroll');
blacklist.Add('DLC1FVBook01Falmer');
blacklist.Add('DLC1FVBook02Falmer');
blacklist.Add('DLC1FVBook03Falmer');
blacklist.Add('DLC1FVBook04Falmer');
blacklist.Add('DLC2BlackBook');
blacklist.Add('DA04ElderScroll');
blacklist.Add('ExpSpiderCrftBook');
blacklist.Add('QA');
blacklist.Add('Recipe');
blacklist.Add('SpellTome');
AddMessage('Dumping books...');
for i := 0 to Pred(FileCount) do
begin
f := FileByIndex(i);
bookGroup := GroupBySignature(f, 'BOOK');
for j := 0 to Pred(ElementCount(bookGroup)) do
begin
book := ElementByIndex(bookGroup, j);
if IsMaster(book) then
begin
book := WinningOverride(book);
// if it's not blacklisted, do things
if (not IsBlacklisted(book, blacklist)) then
begin
// this it the raw text content of each BOOK's DESC attribute
btext := GetElementEditValues(book, 'DESC');
if (Length(btext) > 0) then
begin
fname := outputPath + GetElementEditValues(book, 'EDID') + '.txt';
AddMessage('Outputting to: ' + fname);
if not DRY_RUN then
begin
output := TStringList.Create;
try
try
output.Add(btext);
output.SaveToFile(fname);
//AddMessage('Successfully saved!');
//AddMessage(#9 + fname);
//AddMessage(#20);
except
AddMessage('===ERROR=== Unable to save ' + fname + '!');
if STOP_ON_ERROR then
begin
raise;
end;
end;
finally
output.Free;
end;
end;
end;
end;
end;
//AddMessage('----------')
end;
end;
//AddMessage(btext)
finally
blacklist.Free;
end;
end;
end.
看起来这应该很简单,但也许不是。完全披露:我无论如何都不是程序员。我只知道通过业余爱好项目混日子,Pascal 对我来说是全新的。所以,如果有什么是非常糟糕的代码,我愿意改进。不过,我可能只打算使用这个脚本一次,所以我不太关心优化,只关心可靠的操作。
我正在为 xEdit(又名 SSEEDit)编写脚本 - 大多数人使用该工具来处理不更改丰富游戏资产的 Skyrim 和 Fallout 4 模组。目标是为游戏中的每个 BOOK 对象(原版 + 原始 DLC)转储 DESC 属性 的原始文本内容。我已经走得很远了,对我在做什么有了很好的理解,但我这辈子都无法让这部分工作。
我有一个字符串黑名单,在遍历所有 BOOK 对象时应该跳过它。我已经尝试使用 pos()
几种不同的方式,但它永远不会返回零以外的任何东西。
奇怪的是,即使我在测试中可以从 pos()
中得到正确的结果,但当我 运行 我的实际脚本时,每本书都是正匹配。看起来我实际上并没有遍历黑名单中的第一个条目。
以下是我搜索黑名单条目时返回的示例:
EDID: DLC2dunFahlbtharzJournal02
looking in DLC2dunFahlbtharzJournal02
for DLC1ElderScroll...
skipped DLC2dunFahlbtharzJournal02
这不应该从 pos('DLC1ElderScroll','DLC2dunFahlbtharzJournal02')
返回 0...但它是。
(顺便说一句 - 如果你有 Skyrim SE,你只需要 SSEEdit 来测试它。)
这是我的完整脚本:
{
Dump book text
Dumps "book text" property of every vanilla book
Source for most copypasta:
https://github.com/AngryAndConflict/skyrim-utils/
}
unit UserScript;
uses mteFunctions;
// uses RegExpr;
function Initialize: integer;
var
f, group, e: IInterface;
i, j: integer;
btext,fname: String;
slItems: TStringList;
FileInfo: File_Content;
begin
AddMessage('Dumping books.....');
slItems := TStringList.Create;
// load item and perk stringlists
for i := 0 to FileCount - 1 do begin
f := FileByIndex(i);
group := GroupBySignature(f, 'BOOK');
for j := 0 to ElementCount(group) - 1 do begin
e := ElementByIndex(group, j);
slItems.Add(geev(e, 'EDID'));
// if it's a book, do things
if (isBook(e) = True) then begin
// this it the raw text content of each BOOK's DESC attribute
btext := geev(e,'DESC');
if (Length(btext) > 0) then begin
fname := ProgramPath + 'Output\' + (geev(e, 'EDID')) + '.txt';
// AddMessage('Successfully saved!');
// AddMessage(#9 + fname);
// AddMessage(#20);
// AddMessage('===ERROR=== Unable to save ' + fname + '!');
end;
end;
end;
end;
//AddMessage(btext)
end;
// check if item is book
// exclude blacklisted books and spell tomes
function isBook(item: IInterface): boolean;
var
formID,test: String;
blacklist: TStringList;
ignore: Boolean;
i,t: integer;
begin
Result := false;
ignore := false;
blacklist := TStringList.Create;
// blacklist to exclude - these are can be FormIDs or friendly names
blacklist.Add('DLC1ElderScroll');
blacklist.Add('DLC1FVBook01Falmer');
blacklist.Add('DLC1FVBook02Falmer');
blacklist.Add('DLC1FVBook03Falmer');
blacklist.Add('DLC1FVBook04Falmer');
blacklist.Add('DLC2BlackBook');
blacklist.Add('DA04ElderScroll');
blacklist.Add('ExpSpiderCrftBook');
blacklist.Add('QA');
blacklist.Add('Recipe');
formID := geev(item,'Record Header\FormID');
t := pos(blacklist(1),'Elder');
test := IntToStr(t);
AddMessage(test);
for i := 0 to (blacklist.Count - 1) do begin
if (pos(formID, blacklist(i)) >= 0) then begin
AddMessage('====' + formID + '====');
AddMessage(blacklist(i));
// AddMessage('skipped ' + formID);
ignore := true;
Result := false;
break;
end;
end;
// has Keyword excludes all spell tomes
if (Signature(item) = 'BOOK') and not (hasKeyword(item,'000937A5')) and not ignore then begin
Result := true;
end;
end;
end.{
Dump book text
Dumps "book text" property of every vanilla book
Source for most copypasta:
https://github.com/AngryAndConflict/skyrim-utils/
}
unit UserScript;
uses mteFunctions;
// uses RegExpr;
function Initialize: integer;
var
f, group, e: IInterface;
i, j: integer;
btext,fname: TString;
slItems: TStringList;
FileInfo: File_Content;
blacklist: TStringList;
begin
AddMessage('Dumping books.....');
slItems := TStringList.Create;
// load item and perk stringlists
for i := 0 to FileCount - 1 do begin
f := FileByIndex(i);
group := GroupBySignature(f, 'BOOK');
for j := 0 to ElementCount(group) - 1 do begin
e := ElementByIndex(group, j);
slItems.Add(geev(e, 'EDID'));
// if it's a book, do things
if (isBook(e) = True) then begin
// this it the raw text content of each BOOK's DESC attribute
btext := geev(e,'DESC');
if (Length(btext) > 0) then begin
fname := ProgramPath + 'Output\' + (geev(e, 'EDID')) + '.txt';
// AddMessage('Successfully saved!');
// AddMessage(#9 + fname);
// AddMessage(#20);
// AddMessage('===ERROR=== Unable to save ' + fname + '!');
end;
end;
// AddMessage('----------')
end;
end;
//AddMessage(btext)
end;
// check if item is book
// exclude blacklisted books and spell tomes
function isBook(item: IInterface): boolean;
var
formID,needle,haystack,test: TString;
blacklist: TStringList;
ignore: Boolean;
i,t,p: integer;
begin
Result := false;
ignore := false;
blacklist := TStringList.Create;
// blacklist to exclude - these are can be FormIDs or friendly names
blacklist.Add('DLC1ElderScroll');
blacklist.Add('DLC1FVBook01Falmer');
blacklist.Add('DLC1FVBook02Falmer');
blacklist.Add('DLC1FVBook03Falmer');
blacklist.Add('DLC1FVBook04Falmer');
blacklist.Add('DLC2BlackBook');
blacklist.Add('DA04ElderScroll');
blacklist.Add('ExpSpiderCrftBook');
blacklist.Add('QA');
blacklist.Add('Recipe');
formID := geev(item,'EDID');
for i := 0 to (blacklist.Count - 1) do begin
needle := blacklist[i];
haystack := formID;
// AddMessage('====' + formID + '====');
// AddMessage('looking in ' + haystack);
// AddMessage(#9 + ' for ' + needle + '...');
t := pos(haystack, needle);
test := IntToStr(t);
// AddMessage(test);
if (pos(blacklist[i], formID) >= 0) then begin
// AddMessage(blacklist[i]);
AddMessage('skipped ' + formID);
ignore := true;
break;
end;
end;
// hasKeyword excludes all spell tomes
if (not (Signature(item) = 'BOOK')) or (hasKeyword(item,'000937A5')) then begin
ignore := true;
end;
if ignore then begin
Result := false;
end;
if not ignore then begin
Result := true;
end;
end;
end.
继official Pascal documentation之后,pos
函数的正确调用是pos(SubString, SourceString)
。此外,我认为索引 TStringList
的正确方法是 blacklist[i]
.
您可以试试这个示例代码:
uses SysUtils, Classes;
var blacklist: TStringList;
begin
blacklist := TStringList.Create;
blacklist.Add('Black');
blacklist.Add('White');
WriteLn(Pos(blacklist[1], 'Robert White'));
ReadLn;
end.
输出:
8
似乎 SSEEdit 的捆绑 Pascal 引擎从 1 开始与 pos()
进行字符串匹配 - 只要我更改代码以排除 1 而不是 0,它就会按预期工作。
下面是脚本的重写,设置为仅打印消息而不写入任何文件:如果您对它的工作方式感到满意,只需将 14 行更改为
DRY_RUN = False;
让它实际将书籍内容转储到 Output 子文件夹中。
我从你连接的两个脚本中的后者开始,我认为这是你的最新版本。
主要变化:
- 只在
Initialize
中填充blacklist
一次,不需要对每条记录都这样做; - 你不需要检查你的记录是否是一本书,因为你已经在遍历
BOOK
组,所以我颠倒了逻辑,只检查编辑器 ID 是否包含任何字符串blacklist
; - 你真的不需要
mteFunctions
,所以我删除了它并使用现有逻辑将编辑 ID 中带有SpellTome
的记录列入黑名单 - 如果你需要再次检查关键字,您可以重新启用mteFunctions
并使用其实用程序; - 检查记录是否
IsMaster
然后仅在其WinningOverride
上工作一次 - 这避免了多次处理同一条记录,以防被官方 DLC 或 mod 覆盖,参考:https://tes5edit.github.io/docs/13-Scripting-Functions.html#IwbMainRecord
小改动:
- 在使用任何
TStringList
; 后调用 - 为系统单位添加
uses
子句 - 运行 xEdit 脚本实际上不需要,但如果您为 Delphi Pascal 使用 linter,则有助于捕获错误; - 使用
Pred
而不是Count - 1
- 结果应该是相同的,但看起来像在 Delphi 世界中进行迭代的标准方法; - 在任何
begin
之前换行,以及遵循样式指南的其他类似更改:https://docwiki.embarcadero.com/RADStudio/Sydney/en/Delphi_Statements
Free
{
Dump book text
Dumps "book text" property of every book in loaded plugins
Source for most copypasta:
https://github.com/AngryAndConflict/skyrim-utils/
}
unit UserScript;
interface
const
// change this to False to actually write the text files
DRY_RUN = True;
// change this to False if you want to continue after the first error
STOP_ON_ERROR = True;
implementation
uses
//mteFunctions,
System.Classes, // TStringList
System.SysUtils, // CreateDir, IntToStr
xEditAPI;
// check if rec editor ID contains any string in blacklist
function IsBlacklisted(rec: IwbMainRecord; blacklist: TStringList): Boolean;
var
i: Cardinal;
edid: string;
//needle, haystack: string;
begin
Result := False;
edid := EditorID(rec);
for i := 0 to Pred(blacklist.Count) do
begin
//needle := blacklist[i];
//haystack := edid;
//AddMessage('====' + edid + '====');
//AddMessage('looking in ' + haystack);
//AddMessage(#9 + ' for ' + needle + '...');
//AddMessage(' test: ' + IntToStr(Pos(needle, haystack));
if (Pos(blacklist[i], edid) > 0) then
begin
Result := True;
//AddMessage(blacklist[i]);
AddMessage('Skipping: ' + edid);
Break;
end;
end;
end;
function Initialize: Integer;
var
i, j: Cardinal;
f: IwbFile;
bookGroup: IwbGroupRecord;
book: IwbMainRecord;
btext, outputPath, fname: string;
blacklist, output: TStringList;
begin
Result := 0;
outputPath := ProgramPath + 'Output\';
if not DRY_RUN then
begin
CreateDir(outputPath);
end;
blacklist := TStringList.Create;
try
// match editor IDs containing any of following
blacklist.Add('DLC1ElderScroll');
blacklist.Add('DLC1FVBook01Falmer');
blacklist.Add('DLC1FVBook02Falmer');
blacklist.Add('DLC1FVBook03Falmer');
blacklist.Add('DLC1FVBook04Falmer');
blacklist.Add('DLC2BlackBook');
blacklist.Add('DA04ElderScroll');
blacklist.Add('ExpSpiderCrftBook');
blacklist.Add('QA');
blacklist.Add('Recipe');
blacklist.Add('SpellTome');
AddMessage('Dumping books...');
for i := 0 to Pred(FileCount) do
begin
f := FileByIndex(i);
bookGroup := GroupBySignature(f, 'BOOK');
for j := 0 to Pred(ElementCount(bookGroup)) do
begin
book := ElementByIndex(bookGroup, j);
if IsMaster(book) then
begin
book := WinningOverride(book);
// if it's not blacklisted, do things
if (not IsBlacklisted(book, blacklist)) then
begin
// this it the raw text content of each BOOK's DESC attribute
btext := GetElementEditValues(book, 'DESC');
if (Length(btext) > 0) then
begin
fname := outputPath + GetElementEditValues(book, 'EDID') + '.txt';
AddMessage('Outputting to: ' + fname);
if not DRY_RUN then
begin
output := TStringList.Create;
try
try
output.Add(btext);
output.SaveToFile(fname);
//AddMessage('Successfully saved!');
//AddMessage(#9 + fname);
//AddMessage(#20);
except
AddMessage('===ERROR=== Unable to save ' + fname + '!');
if STOP_ON_ERROR then
begin
raise;
end;
end;
finally
output.Free;
end;
end;
end;
end;
end;
//AddMessage('----------')
end;
end;
//AddMessage(btext)
finally
blacklist.Free;
end;
end;
end.