{ Dump book text Dumps "book text" property of every book in loaded plugins Source for most copypasta: https://github.com/AngryAndConflict/skyrim-utils/ Revisions by Pragasette: https://stackoverflow.com/questions/70357811/pascal-scripting-for-xedit-how-do-i-check-whether-a-substring-is-present-in-a/70361312#70361312 } unit UserScript; interface const // change this to False to actually write the text files DRY_RUN = False; // change this to False if you want to continue after the first error STOP_ON_ERROR = True; implementation uses 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('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.