summaryrefslogtreecommitdiff
path: root/doc/language_v2.htm
diff options
context:
space:
mode:
Diffstat (limited to 'doc/language_v2.htm')
-rw-r--r--doc/language_v2.htm359
1 files changed, 359 insertions, 0 deletions
diff --git a/doc/language_v2.htm b/doc/language_v2.htm
new file mode 100644
index 0000000..9e20493
--- /dev/null
+++ b/doc/language_v2.htm
@@ -0,0 +1,359 @@
+<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<title> The rep language </title>
+<style>
+ pre
+ {
+ margin-left: 3em;
+ }
+ h2
+ {
+ margin-top: 3em;
+ }
+ h3
+ {
+ margin-top: 2em;
+ font-weight: normal;
+ border-top: 1px solid black;
+ padding-left: 5px;
+ }
+ p
+ {
+ margin-left: 1em;
+ font-family: tahoma, verdana, arial, helvetica;
+ font-size: 9pt;
+ line-height: 12pt;
+ }
+</style>
+</head>
+
+<body bgcolor="#FFFFFF">
+<h1>The rep Language</h1>
+
+<p><a href="#syntax">Syntax</a><br>
+<a href="#comments">Comments</a><br>
+<a href="#commands">Commands</a><br>
+<a href="#notes">Script Notes</a></p>
+
+<h2><a name="syntax">Syntax</a></h2>
+<p>A rep script is made of various commands. The commands are detailed below, but here's a few basics:</p>
+<p><strong>Options:</strong>Certain command can take various options. These are wrapped in parentheses, and separated by commas when multiple options are present.</p>
+<p><strong>Text:</strong> Certain commands need a bit of text in order to do their thing. This could be a regular expresson, or perhaps replacement text. This text follows any options if present. The first character of the text is the quote character and is used to detect the end of the data block. If the quote character is used inside the text it must be escaped with a backslash. You can use any of these characters as a quote character:</p>
+
+<pre>"~`!@#$%^&*[]|'&gt;&lt;./?+=-;:</pre>
+
+<p>The examples in this document will use a double quote <tt>(")</tt> as the quote character</p>
+
+<p>A general example of a rep command format would go something like this:</p>
+
+<pre>command (option, option) "data"</pre>
+
+<p>A command can extend to multiple lines. The following is valid:</p>
+
+<pre>command (options,
+options)
+"multiline
+data"</pre>
+
+<p>A command can be followed by curly brackets. Generally this means that the result of the command applies to whatever commands are inside the curly brackets. If the command fails (for example a match that doesn't match) then the stuff inside the curly brackets isn't executed:</p>
+
+<pre>command
+{
+ more commands
+}</pre>
+
+<h2><a name="comments">Comments</a></h2>
+
+<p>A comment starts in a # sign and extends to the end of the line. Comments are not valid inside data. For example:</p>
+
+<pre># Is a comment</pre>
+
+<h2><a name="commands">Commands</a></h2>
+
+<h3>match</h3>
+<pre><b>syntax:</b> match (<i>not, once, find, tag, 0-9</i>) "<i>regexp</i>"</pre>
+<p>Matches regular expression. A full study of regular expressions is outside the scope of this document. You can also match simple text, but you'll need to escape (with a backslash) any characters used by regular expressions. Those are: </p>
+
+<pre>.$%^*+?{}[]|()</pre>
+
+<p>Matches are not case sensitive unless specified with the 'case' option (see below).</p>
+
+<p>The statements inside the match are only executed if the match is successful. In addition the statements inside the match can only operate on the text that was matched. The following matches the word 'Hi There!' in a document and then matches the 'Hi' part.</p>
+
+<pre>match "Hi There!"
+{
+ # This only matches the above 'Hi'
+ match "Hi"
+ {
+ # Do something with 'Hi'
+ }
+}</pre>
+
+<p>The match command can have several options:</p>
+
+<p><b>not</b>: Executes the contained statements if it doesn't match.</p>
+
+<pre>match (not) "can't find me"</pre>
+
+<p><b>once</b>: Makes sure this match only matches once in a document.</p>
+
+<pre>match (once) "&lt;title&gt;"</pre>
+
+<p><b>find</b>: Don't restrict statements inside the match to the text that was matched. This is useful for just verifying if something is there.</p>
+
+<pre>match (find) "check"</pre>
+
+<p><b>tag</b>: Makes a tag match. This is explained further below.
+
+<p><b>0-9</b>: Restricts the statements inside the match to the specified group (wrapped with paretheses) in the regular expression. 0 is the entire statement and 1 through 9 are numbered groups.</p>
+
+<pre>match (1) "Johnny (Smith)"
+{
+ # Now we can do something with 'Smith'
+}</pre>
+
+<h3>replace</h3>
+
+<pre><b>syntax:</b> replace "<i>replace text</i>"</pre>
+
+<p>Replaces the matched text with new text. For example the following replaces 'Hello' with 'Yo' anywhere in the document:</p>
+
+<pre>match "Hello"
+{
+ replace "Yo"
+}</pre>
+
+<p>You can include text groups (which were wrapped in parentheses) that were matched in the previous regular expression. These are specified by using a percent and the group number. %0 specifies all the matched text, and %1 - %9 are the numbered groups.</p>
+
+<p>For example the following replaces all &lt;img&gt; tags with &lt;image&gt; tags:</p>
+
+<pre>match "&lt;img(.*?)&gt;"
+{
+ replace "&lt;image%1&gt;"
+}</pre>
+
+<p>After text has been replaced it is locked. It cannot be matched again.</p>
+
+<h3>else</h3>
+
+<pre><b>syntax:</b> else</pre>
+
+<p>Executes the contained statements if the above statements failed. For example the following executes if the match fails</p>
+
+<pre>match "Yo"
+{
+ # Do whatever we do with "Yo"
+}
+else
+{
+ # Didn't match. Do something else
+}</pre>
+
+<h3>lock</h3>
+
+<pre><b>syntax:</b> lock</pre>
+
+<p>Locks text so it cannot be matched again. Useful to exclude portions of the document from replacements later on. The folling would lock all paragraphs in an HTML document.</p>
+
+<pre>match "&lt;p&gt;.*?&lt;/p&gt;"
+{
+ lock
+}</pre>
+
+<h3>loop</h3>
+
+<pre><b>syntax:</b> loop</pre>
+
+<p>Repeats the contained code until no more matches can be found. The following (dumb) example replaces all a's inside 'aardvark' with e's:</p>
+
+<pre>match "aardvark"
+{
+ loop
+ {
+ match "a"
+ {
+ replace "e"
+ }
+ }
+}</pre>
+
+<p>Note that the entire document is actually wrapped in an invisible loop command. The entire document loops until no more matches can be found. However because of locking, the same text will generally not match more than once. In the above example that specific instance of 'aardvark' wouldn't match again after a single 'a' inside had been replaced or locked. Because of this the loop command comes in quite handy.</p>
+
+<h3>function</h3>
+
+<pre><b>syntax:</b> function <i>function_name</i></pre>
+
+<p>Defines a function which can be called with the call command. Function names are case sensitive, can be up to 40 characters long, and can consist of letters and the underscore.</p>
+
+<pre>function test
+{
+ # do whatever here
+}</pre>
+
+<h3>call</h3>
+
+<pre><b>syntax:</b> call <i>function_name</i></pre>
+
+<p>Calls a function. The function must have been defined earlier in the document.</p>
+
+<pre>call test </pre>
+
+<p>The 'call' bit of the statement can be omitted, so the above can be shortened to:</p>
+
+<pre>test</pre>
+
+<p>For example the following function is used for multiple cases:</p>
+
+<pre>function(atoe)
+{
+ loop
+ {
+ match "a"
+ {
+ replace "e"
+ }
+ }
+}
+
+match "aaron"
+{
+ atoe
+}
+
+match "aardvark"
+{
+ atoe
+}</pre>
+
+<h3>return</h3>
+
+<pre><b>syntax:</b>return (<i>number</i>)</pre>
+
+<p>When inside a function returns from that function to the code which called it. A function will normally return when it's end is reached, but <b>return</b> can be used to return earlier.</p>
+
+<p>You can also return a success code. This must be either 0 (for fail) or 1 (for success). In the code that called the function you can use <b>else</b> to take action on failure. </p>
+
+<h3>end</h3>
+
+<pre><b>syntax:</b> end</pre>
+
+<p>Stops the script at the current location. No more matches are done.</p>
+
+<h3>stop</h3>
+
+<pre><b>syntax:</b> stop "optional error message"</pre>
+
+<p>Stops the script as if an error had occurred. You can include an error message.</p>
+
+<h3>set</h3>
+
+<pre><b>syntax:</b> set <i>variable_name</i> "<i>value</i>"</pre>
+
+<p>Assigns the a value to a variable. The value can include backslash references to matched groups just like replace text can. Variables can be used both in later match statements, replaces or any text portion of a command. Variable names can consist of letters and the underscore. The name should alse be less than 40 characters long. Variables are used like so:</p>
+
+<pre>%<i>variable_name</i></pre>
+
+<p>The following example gets a heading from an HTML document and sets the title to it:</p>
+
+<pre>match "&lt;h1&gt;(.*?)&lt;h1&gt;"
+{
+ setv heading "%1"
+}
+
+match "&lt;head&gt;"
+{
+ replace "&lt;head&gt;&lt;title&gt;%heading&lt;/title&gt;"
+}</pre>
+
+<p>An example of using a variable as a match would be the following. The title is matched, and then searched for in the document. If it's found it's made bold:</p>
+
+<pre>match (once) "&lt;title&gt;(.*?)&lt;/title&gt;"
+{
+ set title "%1"
+}
+
+match "%title"
+{
+ replace "&lt;b&gt;%0&lt;/b&gt;
+}</pre>
+
+<p>If a variable is used whose value hasn't been set yet, it's value is blank. You may also use environment variables in your document. This is how you'd pass values to your script from outside.</p>
+
+<h3>add</h3>
+
+<pre><b>syntax:</b> add <i>variable_name</i> "<i>value</i>"</pre>
+
+<p>Similar to <b>set</b> but insteads makes a variable array and adds the value to it. That means multiple values can be set to a variable. This is only useful during matches where any one of the variable values will match. If a multiple variable is used anywhere else an error will result.</p>
+
+<p>The syntax for using a multiple variable is:</p>
+
+<pre>%(<i>variable_name</i>)</pre>
+
+<p>If used without the parentheses the variable will act like a normal variable and the first of it's values will be used.</p>
+
+<p>The following example matches any HTML table element:</p>
+
+<pre>set telement "table"
+add telement "td"
+add telement "tr"
+add telement "tbody"
+add telement "thead"
+
+match "%(telement)"
+{
+ # Do whatever
+}</pre>
+
+<h3>clr</h3>
+
+<pre><b>syntax:</b> clr <i>variable_name</i></pre>
+
+<p>Clears a variable of it's value.</p>
+
+<h3>options</h3>
+
+<pre><b>syntax:</b> options(case, line)</pre>
+
+<p>Sets various options for your script. These options will apply only inside the set of curly braces that they are set. To set global options put the <b>options</b> command at the top of your file. The options are:</p>
+
+<p><b>case:</b> Makes the matches case sensitive.</p>
+
+<p><b>line:</b> Restricts matches to one line.</p>
+
+<p><i>delimiter:</i> Sets the delimiter for the data portions of commands. By default the double-quote is used, but if you need to match this often, then you can change the delimiter to something else.</p>
+
+<p>The following makes matches case sensitive:</p>
+
+<pre>options(case)</pre>
+
+<h2><a name="notes">Script Notes</a></h2>
+
+<p>First of all you'll need to know regular expressions to get anything useful out of rep scripting. The regular expressions used in rep are PCRE (Perl Compatible Regular Expressions). They're not explained here but you can get tons of info online for them.</p>
+
+<p>Once your script gets a little more than just two or three commands, it's important to understand how it gets run:</p>
+
+<p>The entire script is run over and over again in a loop until no more matches are made. Although it's difficult, it is possible to throw your script in an endless loop. If this is the case then execution stops after a million loops.</p>
+
+<p>Portions of the document that have been locked or replaced cannot be matched again. Also if a portion of text to be matched has been locked it cannot be matched. Keep this in mind when making your scripts. If you wish to match and replace multiple items inside another match, you'll need to use a loop command to do so.</p>
+
+<p>The rep processor can be used in a buffered mode where only a portion of the document is operated on at one time. This greatly increases the speed of the processor. But you have to be careful that any matches you make will fit inside that buffer. In many cases (for example matching the entire &lt;body&gt; tag of an HTML document, you won't be able to use buffered mode reliably.)</p>
+
+<h3>Tag Matches</h3>
+<p>Tag matches match a starting and closing tag of your choice. They also take into consideration that there may be other tags inside that could match. The opening and closing tag are separated by an equal sign ('<tt>=</tt>').</p>
+
+<p>For example the following would match a set of <tt>&lt;div&gt;</tt> tags in an HTML document. It would pair up the correct set of <tt>&lt;div&gt;</tt> tags even if there were other contained tags that could match:</p>
+
+<pre>match (tag) "&lt;div&gt;=&lt;/div&gt;"</pre>
+
+<p>The regular expression groups are handled differently when using tag matching:</p>
+
+<p><b>0</b>: This is the entire match as usual.<br>
+<b>1</b>: The text of the opening tag.<br>
+<b>2</b>: The contained text.<br>
+<b>3</b>: The text of the closing tag.</p>
+
+
+
+</body>
+</html>