ScriptReplaceSubstring
From 40tude Dialog Wiki
Replace arbitrary substrings in outgoing newsgroup articles
This script replaces strings in your outgoing articles in defined newsgroups, e.g every instance of »dialog« will be changed to »DIALOG« in the group "news.software.readers".
Install & Setup
Please note that this script is realized as an include-file! To make it work, you have to copy&paste the script into a new custom script (e.g. "INCLUDE_ReplaceSubstring"). The script is configured in the first parts, please adjust it there to fit your needs. Then safe it. Don't compile the custom script! After that, add the following lines to your OnBeforeSending-Script:
{$I INCLUDE_ReplaceSubstring.ds}
and
result := result AND ReplaceSubstringsInNewsgroupArticles(Message, Servername, IsEmail);
It could look like this:
program OnBeforeSendingMessage;
{$I INCLUDE_ReplaceSubstring.ds}
function OnBeforeSendingMessage(var Message: TStringlist; Servername: string; IsEmail: boolean):boolean;
begin
result:=true;
//possibly some calls to scripts
result := result AND ReplaceSubstringsInNewsgroupArticles(Message, Servername, IsEmail);
end;
begin
end.
Now compile this OnBeforeSending-Script to get your include-file to work. Please note that whenever you reconfigure the ReplaceSubstring custom script, you have to recompile the OnBeforeSending-Script to apply the changes.
Code
//----------- ReplaceSubstringsInNewsgroupArticles
// Version 1 (beta) - Date: 2005/02/26
// Check the source code or save your data before use.
// Replaces specific strings in your outgoing articles in defined newsgroups
// E.g replaces every instance of "dialog" with "*DIALOG*"
// You can adapt this script to your needs by modifying the three values
// below the notes. The rules are defined in the middle of the script.
// Ignore the warning when compiling the script.
// Note: This script has a couple of deficits:
// 1) Your text will not be reformatted. That means if you replace
// text with a much longer or shorter string, you can end up with
// weird looking text formatting like overly long lines that might
// provoke mocking comments from other neticens.
// If you feel the need for a reformatting option in this script,
// and can't do it yourself, please ask (very nicely) in your 40tude
// Dialog newsgroup for help.
// 2) You can provoke even weirder results when the result of pattern #1
// has the key of pattern #2 as a substring.
// ( In this case, I'd think the deficit at the user's side though. )
// 3) If you replace with non-ascii characters, unexpected things can happen.
// That might range from undeclared 8bit characters if the source was
// us-ascii to wrongly coded non-us-ascii characters if the used
// character encoding does not match the current Windows encoding.
// 4) Truth be told, I don't speak Object Pascal, so it's very likely
// that I wrote pretty strange or complicated code.
// If you notice anything, feel free to correct it.
// ***** --USER--> You can specify the maximum number of patterns here.
// ***** --USER--> If you get an error when sending a message (array out
// ***** --USER--> of bounds or some such), try to increase this number
// ***** --USER--> to at least equal the number of replacement rules you
// ***** --USER--> defined below.
// ***** --USER--> Leave it as it is for the moment
const RSINA_MAX_REPLACEMENT_PATTERNS = 20;
// ***** --USER--> Lines starting with any of the characters defined here
// ***** --USER--> (between the inverted commas) will not be processed.
const RSINA_QUOTE_CHARACTERS = '|>';
// ***** --USER--> false: text in the signature will not be processed
// ***** --USER--> true: text in the signature *will* be processed
const RSINA_PROCESS_SIG = false;
// ***** --USER--> Now scroll down about one page to finish the setup of the script
type RSINA_TPatterns = Array [1..RSINA_MAX_REPLACEMENT_PATTERNS] of record
key : string;
value : string;
newsgroup : string;
flags : TReplaceFlags;
end;
//For ease of use in the Init-method, we will keep these two variables global.
var RSINA_Patterns : RSINA_TPatterns;
RSINA_PatternCount : integer;
procedure RSINA_AddPattern(key, value, newsgroup : string; ignoreCase : boolean );
begin
RSINA_PatternCount := RSINA_PatternCount + 1;
if ignoreCase then begin
RSINA_Patterns[RSINA_PatternCount].flags := [rfReplaceAll, rfIgnoreCase];
end
else begin
RSINA_Patterns[RSINA_PatternCount].flags := [rfReplaceAll];
end;
RSINA_Patterns[RSINA_PatternCount].key := key;
RSINA_Patterns[RSINA_PatternCount].value := value;
RSINA_Patterns[RSINA_PatternCount].newsgroup := newsgroup;
end;
procedure RSINA_Init();
begin
// ***** --USER--> +-----------------------------------------------------------+
// ***** --USER--> | ***** Define your rules *HERE* ***** |
// ***** --USER--> | |
// ***** --USER--> | A call to RSINA_AddPattern defines a replacement rule. |
// ***** --USER--> | It takes four paramters (the first three of them have to |
// ***** --USER--> | be enclosed in inverted commas): |
// ***** --USER--> | 1) the substring to be replaced |
// ***** --USER--> | 2) the replacement. Use only US-ASCII characters here! |
// ***** --USER--> | 3) a string that needs to be part of the newsgroup |
// ***** --USER--> | name for the rule to apply |
// ***** --USER--> | 4) true for 'ignore case' |
// ***** --USER--> | false for 'match case' |
//make dialog uppercase in news.software.readers
RSINA_AddPattern('dialog', 'DIALOG', 'news.software.readers', true);
//make the goddess, HOSHI, uppercase in all newsgroups with 'startrek' in its name
RSINA_AddPattern('hoshi', '*HOSHI*', 'startrek', true);
// ***** --USER--> | ***** Nothing to see below this point ***** |
// ***** --USER--> +-----------------------------------------------------------+
end;
const RSINA_NEWSGROUP_HEADER = 'Newsgroups: ';
function ReplaceSubstringsInNewsgroupArticles(var Message: TStringlist; Servername: string; IsEmail: boolean):boolean;
var i, j : integer;
isHeader, isSig : boolean;
newsgroups : string;
begin
result:=true; //We cannot fail ;)
if IsEmail then exit;
//init
isHeader := true;
isSig := false;
RSINA_PatternCount := 0;
RSINA_Init();
//For all lines of the article
for i:=0 to Message.count-1 do begin
//look for the Newsgroups: header
if isHeader then begin
if AnsiPos(RSINA_NEWSGROUP_HEADER, message.strings[i])=1 then begin
newsgroups := Copy(message.strings[i], Length(RSINA_NEWSGROUP_HEADER)+1, Length(message.strings[i])-Length(RSINA_NEWSGROUP_HEADER));
//it might pay on some older computers to check here whether any further
//processing is neccesary, based on the newsgroup header.
end;
end;
isSig := isSig OR (message.strings[i]='-- ');
//do the replacing if this is an unquoted body line
if (Not isHeader) AND ((NOT isSig) OR RSINA_PROCESS_SIG) AND (Length(message.strings[i])>0) then begin
if AnsiPos(message.strings[i][1], RSINA_QUOTE_CHARACTERS)=0 then begin
//for all patterns
for j:=1 to RSINA_PatternCount do begin
if AnsiPos(RSINA_Patterns[j].newsgroup, newsgroups)>0 then begin
message.strings[i] := StringReplace( message.strings[i], RSINA_Patterns[j].key, RSINA_Patterns[j].value, RSINA_Patterns[j].flags);
end;
end;
end;
end;
isHeader := isHeader AND (message.strings[i]<>'');
end; //for
end;
--Korbinian