-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinclude.html
More file actions
108 lines (108 loc) · 45.9 KB
/
include.html
File metadata and controls
108 lines (108 loc) · 45.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<style type="text/css">@media screen { h1,h2,h3,h4,h5,p,a,br,li,td,.underline {font-family:sans-serif;text-align:justify} h1,h2,h3,h4,h5 {padding-bottom:.3em;border-bottom:#DDDDDD 1px solid} body {font-size:11pt;line-height:1.4em;max-width:1600px;padding:0em 2em 0em 2em;margin: 0 auto;} h1 {font-size:18pt;margin-left:0em} h2 {font-size:16pt;margin-left:0em} h3 {font-size:14pt;margin-left:0.5em} h4 {font-size:13pt;margin-left:1em} h5 {font-size:12pt;margin-left:2em} hr {text-align:center;height:1px;border:none;background:#CCCCCC} ol,ul,p,table {margin-left:3em;margin-right:3em;line-height:1.4em} a {text-decoration:none} a:hover {text-decoration:underline} img {display:block;max-width:100%;margin: 0 auto;} dl {border-left:1em solid #EEEEEE;padding-right:2em;font-family:sans-serif;display:grid;width: 80%;margin:1em auto 1em auto;grid-template-columns: max-content auto;column-gap: 1em;row-gap: 1em;} dt {white-space:nowrap;margin-left:1em;font-weight:bold;width:10em;} dd {text-align:justify;} .defword {width:25%} .defexplain {} .defexplain p {padding:0em;margin:0em} .deftablepara {} .deftable {width:85%;padding-left:1em;border:1px solid black;vertical-align:top} .deftable td {text-align:left;vertical-align:top} .deftablefaq {border-style:solid;border-width:thin} .stdtable {max-width:calc(100% - 6em);margin: 0 auto;border:1px solid;background:#CCCCCC} .stdtable th {padding:0.3em;background:#EEEEEE;font-family:sans-serif;font-weight:bold;text-align:center} .stdtable td {padding:0.3em;background:white;text-align:left;vertical-align:top} .end {font-size:8pt} .example {margin-left:3em;margin-right:3em;overflow-x:hidden;background-color:#F8F8F8;border:1px solid hsl(0, 0%, 90%);padding:1em} .header {margin-left:3em;margin-right:3em;background-color:#FFFFEE;border:1px solid hsl(0, 0%, 60%);padding:1em} .indented {margin-left:3em} .litable {text-align:left} .new {border-right:10px solid;padding-right:10px;font-family:sans-serif} .note {margin:0.5em 3em 0.5em 3em;background-color:#F0F0A0;border:1px solid hsl(60, 100%, 30%);padding:0em} .note .title {font-family:sans-serif;font-weight:bold;margin:0.5em} .note .message {margin:0.5em 1.5em 0.5em 1.5em;padding:0em} .note .message p {padding:0em;margin:1em 0em 1em 0em} .nobreak {white-space:nowrap;} .reference {} .inlinereference a {font-weight: bold;color:#448844;white-space:nowrap} .inlinesvg {width:1em;height:1em;vertical-align:middle;} .inlinedatatype {padding:0.1em 0.5em 0.1em 0.5em;border-radius:5px;border:solid 1px hsl(0, 100%, 75%);background:#FFCCCC;color:black} .caption {font-size:10pt;text-align:center;font-style:italic} .buttonpanel {margin:0em} .button {padding:0.5em;margin:0em} .buttoninactive {padding:0.5em;margin:0em;color:#AAAAAA} .inlinebutton {white-space:nowrap;padding:0.1em 0.5em 0.1em 0.5em;border-radius:5px;border:solid 1px hsl(120, 50%, 60%);background:#CCFFCC;color:black} .inlinekeyshortcut {white-space:nowrap;padding:0.1em 0.5em 0.1em 0.5em;border-radius:5px;border:solid 1px hsl(210, 50%, 30%);background:#0088CC;color:white} .inlinevalue {white-space:nowrap;font-family:monospace;white-space:pre;padding:0.1em 0.5em 0.1em 0.5em;border-radius:5px;border:solid 1px hsl(60, 100%, 40%);background:#FFFF66;color:black} .todolist {padding:0.5em;font-size:10pt} .todolist p {margin:0em 3em 0em 3em} .reviewlist {padding:0.5em;font-size:10pt} .reviewlist p {margin:0em 3em 0em 3em} .commentlist {padding:0.5em;font-size:10pt} .commentlist p {margin:0em 3em 0em 3em} .todo {margin:1em 3em 1em 3em;padding:0.5em;background:#FFAAAA;border:solid 2px hsl(0, 100%, 40%);font-size:10pt} .todo p {margin:0.2em 1em 0.2em 1em} .review {margin:1em 3em 1em 3em;padding:0.5em;background:#AACCFF;border:solid 2px hsl(210, 100%, 40%);font-size:10pt} .review p {margin:0.2em 1em 0.2em 1em} .comment {margin:1em 3em 1em 3em;padding:0.5em;background:#FFFF22;border:solid 2px hsl(60, 100%, 40%);font-size:10pt} .comment p {margin:0.2em 1em 0.2em 1em} .inline {margin:0.5em 3em 0.5em 3em;background-color:#EEEEEE;border:solid 1px hsl(0, 0%, 60%);padding:0em} .inline .title {font-family:sans-serif;font-weight:bold;margin:0.5em} .inline .elements {font-size:10pt;margin:0em 0em 0.5em 0em;padding:0em 1em 0em 1em} .inline .elements p {display:inline-table;margin:0.25em 0.5em 0.25em 0.5em} .tocindent {margin-left: 2em} .top {font-size:10pt;text-align:right} .topbutton {padding:0.5em 0em 0.5em 0em;} .underline {text-decoration:underline} #draft {font-family:sans-serif;position:fixed;bottom:0;max-width:1600px;width:100%;padding:.2em;background-color:#ff0000;color:#ffffff;font-weight:bold;text-align:center;z-index:9999;} } @media print { h1,h2,h3,h4,h5,p,a,br,li, #underline {font-family:sans-serif;text-align:justify;orphans:5;widows:5} p,li,td {font-size:10pt} ul,ol {page-break-after:avoid;orphans:5;widows:5} }</style><title>Include documentation</title><script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script><script>$(document).ready();</script><script type="text/javascript">window.MathJax = {AsciiMath: {decimal: ','}, asciimath2jax: {delimiters: [['`','`']]}};</script><script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=AM_HTMLorMML"></script></head><body><a id="top" name="top"></a><h2>Include documentation</h2><pre class="header"><strong>Author: Ladislav Mecir</strong></pre><hr /><h2>Contents</h2><div class="tocindent"><a href="#sect1"><strong>1. Introduction</strong></a><br /><a href="#sect2"><strong>2. Design features</strong></a><br /><div class="tocindent"><a href="#sect2.1"><strong>2.1 A comfortable script evaluator:</strong></a><br /><a href="#sect2.2"><strong>2.2 An improved script loader:</strong></a><br /><a href="#sect2.3"><strong>2.3 An improved preprocessor:</strong></a><br /></div><a href="#sect3"><strong>3. License</strong></a><br /><a href="#sect4"><strong>4. Description</strong></a><br /><div class="tocindent"><a href="#sect4.1"><strong>4.1 Standard preprocessing directives</strong></a><br /><div class="tocindent"><a href="#sect4.1.1">4.1.1 #include script</a><br /><a href="#sect4.1.2">4.1.2 #include-check script</a><br /><a href="#sect4.1.3">4.1.3 #do block</a><br /><a href="#sect4.1.4">4.1.4 #paren paren</a><br /><a href="#sect4.1.5">4.1.5 #include-string text-file</a><br /><a href="#sect4.1.6">4.1.6 #include-binary binary-file</a><br /><a href="#sect4.1.7">4.1.7 #include-files dir file-list</a><br /><a href="#sect4.1.8">4.1.8 comment</a><br /></div><a href="#sect4.2"><strong>4.2 Conditional preprocessing directives</strong></a><br /><div class="tocindent"><a href="#sect4.2.1">4.2.1 #if cond-block true-block</a><br /><a href="#sect4.2.2">4.2.2 #either cond-block true-block false-block</a><br /></div><a href="#sect4.3"><strong>4.3 Global words used</strong></a><br /><div class="tocindent"><a href="#sect4.3.1">4.3.1 include</a><br /><a href="#sect4.3.2">4.3.2 include-ctx</a><br /><a href="#sect4.3.3">4.3.3 script?</a><br /></div><a href="#sect4.4"><strong>4.4 include-ctx variables</strong></a><br /><div class="tocindent"><a href="#sect4.4.1">4.4.1 path</a><br /><div class="tocindent"><a href="#sect4.4.1.1">4.4.1.1 Prioritization</a><br /></div><a href="#sect4.4.2">4.4.2 log</a><br /><a href="#sect4.4.3">4.4.3 stack</a><br /><a href="#sect4.4.4">4.4.4 block-directive</a><br /><a href="#sect4.4.5">4.4.5 conditional-directives</a><br /><a href="#sect4.4.6">4.4.6 standard-directives</a><br /><a href="#sect4.4.7">4.4.7 special-includes</a><br /><a href="#sect4.4.8">4.4.8 directives</a><br /><a href="#sect4.4.9">4.4.9 standard-header</a><br /><a href="#sect4.4.10">4.4.10 file</a><br /></div><a href="#sect4.5"><strong>4.5 include-ctx functions</strong></a><br /><div class="tocindent"><a href="#sect4.5.1">4.5.1 include-script</a><br /><a href="#sect4.5.2">4.5.2 include-block</a><br /><a href="#sect4.5.3">4.5.3 get-directives</a><br /><a href="#sect4.5.4">4.5.4 set-directives</a><br /><a href="#sect4.5.5">4.5.5 update-directives</a><br /><a href="#sect4.5.6">4.5.6 push</a><br /><a href="#sect4.5.7">4.5.7 pop</a><br /><a href="#sect4.5.8">4.5.8 do-next</a><br /><a href="#sect4.5.9">4.5.9 load-next</a><br /><a href="#sect4.5.10">4.5.10 read-binary</a><br /><a href="#sect4.5.11">4.5.11 make-error</a><br /><a href="#sect4.5.12">4.5.12 disarm-error</a><br /><a href="#sect4.5.13">4.5.13 redo-error</a><br /><a href="#sect4.5.14">4.5.14 include-error</a><br /><a href="#sect4.5.15">4.5.15 split-path</a><br /><a href="#sect4.5.16">4.5.16 findpfile</a><br /><a href="#sect4.5.17">4.5.17 find-file</a><br /></div><a href="#sect4.6"><strong>4.6 The include error type</strong></a><br /><div class="tocindent"><a href="#sect4.6.1">4.6.1 enhanced</a><br /><a href="#sect4.6.2">4.6.2 file-or-url-in-path</a><br /><a href="#sect4.6.3">4.6.3 stack-empty</a><br /><a href="#sect4.6.4">4.6.4 file-not-found</a><br /><a href="#sect4.6.5">4.6.5 expected</a><br /><a href="#sect4.6.6">4.6.6 invalid-directive</a><br /><a href="#sect4.6.7">4.6.7 script-bug</a><br /></div></div><a href="#sect5"><strong>5. Usage examples</strong></a><br /><div class="tocindent"><a href="#sect5.1"><strong>5.1 Context encapsulation</strong></a><br /><a href="#sect5.2"><strong>5.2 User-defined directives</strong></a><br /><a href="#sect5.3"><strong>5.3 pos1</strong></a><br /><a href="#sect5.4"><strong>5.4 pos2</strong></a><br /><a href="#sect5.5"><strong>5.5 value1</strong></a><br /><a href="#sect5.6"><strong>5.6 value2</strong></a><br /><a href="#sect5.7"><strong>5.7 value3</strong></a><br /></div><a href="#sect6"><strong>6. The #print directive example</strong></a><br /><div class="tocindent"><a href="#sect6.1"><strong>6.1 A definition of a #print directive</strong></a><br /></div><a href="#sect7"><strong>7. How to's</strong></a><br /><div class="tocindent"><a href="#sect7.1"><strong>7.1 Include and relative paths</strong></a><br /><a href="#sect7.2"><strong>7.2 How to evaluate an expression using a #do directive without including a value into the script</strong></a><br /><a href="#sect7.3"><strong>7.3 How to write code detecting whether it has been preprocessed</strong></a><br /><a href="#sect7.4"><strong>7.4 How to guard code containing preprocessor directives</strong></a><br /><a href="#sect7.5"><strong>7.5 How to run your scripts from Windows Explorer using include</strong></a><br /><div class="tocindent"><a href="#sect7.5.1">7.5.1 Scripts for Windows Explorer associations</a><br /><a href="#sect7.5.2">7.5.2 How to define associations for Windows Explorer</a><br /><a href="#sect7.5.3">7.5.3 Possible interferences</a><br /></div></div><a href="#sect8"><strong>8. Availability</strong></a><br /><a href="#sect9"><strong>9. Changelog</strong></a><br /><a href="#sect10"><strong>10 See also</strong></a><br /></div><h2><a id="sect1" name="sect1">1. Introduction</a></h2><p><strong>Include</strong> is a Rebol script processor. It is implemented as a function and works as a Rebol script loader, preprocessor and evaluator. It is not an alternative module system. In fact, it is orthogonal to such systems, meaning that it can work together with such a system.</p><div class="top"><span class="topbutton"><a href="#top">Back to Top</a></span></div><h2><a id="sect2" name="sect2">2. Design features</a></h2><h3><a id="sect2.1" name="sect2.1">2.1 A comfortable script evaluator:</a></h3><ul><li>Can preprocess and evaluate any Rebol script (the script does not have to contain <strong>prebol</strong> directives).</li><li>Processes <strong>prebol</strong> directives, facilitating SDK debugging.</li><li>Preprocessing errors are enhanced to inform in which file the error occurred to make debugging more comfortable.</li><li>Uses <strong>include-ctx/path</strong> which resembles paths of many operating systems to search for scripts.</li><li><strong>include-ctx/path</strong> can contain URLs, not just local directories.</li><li><strong>include/check</strong> prevents scripts from being re-included (included more than once).</li><li>Processes ordinary scripts with Rebol header.</li><li>Processes prefaced Rebol scripts, i.e., Rebol scripts with preface preceding Rebol header and embedded Rebol scripts, see</li></ul><pre class="example">http://www.rebol.com/docs/core23/rebolcore-5.html#section-1.2</pre><ul><li><strong>include/args</strong> sets arguments for the script</li></ul><h3><a id="sect2.2" name="sect2.2">2.2 An improved script loader:</a></h3><ul><li><strong>include/only</strong> loads and preprocesses a script, yielding a Rebol block.</li><li><strong>include/link</strong> loads a script, preprocesses it and saves the result to the specified file.</li></ul><h3><a id="sect2.3" name="sect2.3">2.3 An improved preprocessor:</a></h3><ul><li>Processes all <strong>prebol</strong> directives for basic compatibility with SDK.</li><li>The <em>#include-check</em> directive is available as a "don't re-include" variant of the <em>#include</em> directive.</li><li>The <em>#paren</em> directive is available if the user wants to preprocess a paren.</li><li>The <em>comment</em> directive is available if the user wants the preprocessor to strip the comments from the script.</li><li>Users can reliably guard parts of their code against preprocessing.</li><li>It is possible to include small parts of scripts like binary data, images or strings.</li><li>Context encapsulation is available using the <strong>make object!</strong> or the <strong>make module!</strong> method.</li><li>Users can define new directives.</li></ul><div class="top"><span class="topbutton"><a href="#top">Back to Top</a></span></div><h2><a id="sect3" name="sect3">3. License</a></h2><p>Licensed under the Apache License, Version 2.0 (the "License"). You may obtain a copy of the License at</p><pre class="example">http://www.apache.org/licenses/LICENSE-2.0</pre><div class="top"><span class="topbutton"><a href="#top">Back to Top</a></span></div><h2><a id="sect4" name="sect4">4. Description</a></h2><p>The preprocessing phase is used to build the script, i.e., to include the necessary parts. Moreover, it enables the user to evaluate any Rebol expression(s).</p><h3><a id="sect4.1" name="sect4.1">4.1 Standard preprocessing directives</a></h3><h4><a id="sect4.1.1" name="sect4.1.1">4.1.1 #include script</a></h4><p>Include a script (a file or URL) here. The script is preprocessed by <strong>include</strong>.</p><h4><a id="sect4.1.2" name="sect4.1.2">4.1.2 #include-check script</a></h4><p>The same as above, except that the script is not included if present in the <strong>include-ctx/log</strong>.</p><h4><a id="sect4.1.3" name="sect4.1.3">4.1.3 #do block</a></h4><p>Do the given code block during preprocessing including the result here without preprocessing it further.</p><h4><a id="sect4.1.4" name="sect4.1.4">4.1.4 #paren paren</a></h4><p>Preprocess the given paren.</p><h4><a id="sect4.1.5" name="sect4.1.5">4.1.5 #include-string text-file</a></h4><p>Include the given <strong>text-file</strong> as a string.</p><h4><a id="sect4.1.6" name="sect4.1.6">4.1.6 #include-binary binary-file</a></h4><p>Include the given <strong>binary-file</strong> as a binary.</p><h4><a id="sect4.1.7" name="sect4.1.7">4.1.7 #include-files dir file-list</a></h4><p>Include the files from the <strong>file-list</strong> looking for them in the given <strong>dir</strong> directory. The files are included as a block containing the name and the binary contents of all files.</p><h4><a id="sect4.1.8" name="sect4.1.8">4.1.8 comment</a></h4><p>Leave out the <em>comment</em> directive and its argument from the code. The comment is not left out if the <em>keep-comments</em> global variable is defined when the directive is processed.</p><h3><a id="sect4.2" name="sect4.2">4.2 Conditional preprocessing directives</a></h3><h4><a id="sect4.2.1" name="sect4.2.1">4.2.1 #if cond-block true-block</a></h4><p>Conditionally include the given <strong>then-block</strong> if the <strong>cond-block</strong> evaluates <strong>true</strong>. The <strong>then-block</strong> is preprocessed when included.</p><h4><a id="sect4.2.2" name="sect4.2.2">4.2.2 #either cond-block true-block false-block</a></h4><p>Conditionally include one of the two blocks depending on the result of evaluation of the given <strong>cond-block</strong>. The block being included is preprocessed.</p><h3><a id="sect4.3" name="sect4.3">4.3 Global words used</a></h3><h4><a id="sect4.3.1" name="sect4.3.1">4.3.1 include</a></h4><p>The <em>include</em> word refers to the <strong>include</strong> function.</p><h4><a id="sect4.3.2" name="sect4.3.2">4.3.2 include-ctx</a></h4><p>The <em>include-ctx</em> word refers to the object containing important <strong>include</strong>-related variables and helper functions.</p><h4><a id="sect4.3.3" name="sect4.3.3">4.3.3 script?</a></h4><p>The implementation patches the <strong>script?</strong> function if needed.</p><h3><a id="sect4.4" name="sect4.4">4.4 include-ctx variables</a></h3><h4><a id="sect4.4.1" name="sect4.4.1">4.4.1 path</a></h4><p>The <em>path</em> word refers to a block containing the paths where the <strong>include</strong> function shall look for the files.</p><p>If the script file to include is specified with a non-empty path the script file is looked up only at its path. As opposed to that when the script file is specified without any path using only a file name, <strong>include</strong> will use <strong>include-ctx/path</strong> to look for the file.</p><p><strong>include-ctx/path</strong> can be modified/set by users. See also the <strong>include-ctx/push</strong> and <strong>include-ctx/pop</strong> helper functions.</p><h5><a id="sect4.4.1.1" name="sect4.4.1.1">4.4.1.1 Prioritization</a></h5><p>The directories (or URLs) that are first in <strong>include-ctx/path</strong> are searched first. Consequently they are having priority during the file search.</p><h4><a id="sect4.4.2" name="sect4.4.2">4.4.2 log</a></h4><p>The <em>log</em> variable refers to a block containing the files (with complete paths) <strong>include</strong> function processed. It is used by the <em>/check</em> refinement and by the <em>#include-check</em> directive to check whether a specific file was already included. The default Rebol comparison (which is case-insensitive) is used and the paths are converted to lowercase.</p><p>The user can save the <strong>log</strong> to a file to create a log file. The user can influence what will be considered as "already included", typically by clearing the contents of the <strong>log</strong> block when starting to link a new file. The files are appended to the <strong>log</strong> block as they are found by <strong>include</strong>, which means that the file found last will be the last one in the log.</p><h4><a id="sect4.4.3" name="sect4.4.3">4.4.3 stack</a></h4><p>The stack used by the <strong>push</strong> and <strong>pop</strong> helper functions (see below). There is no need to use the variable directly.</p><h4><a id="sect4.4.4" name="sect4.4.4">4.4.4 block-directive</a></h4><p>Handling a subblock or paren.</p><h4><a id="sect4.4.5" name="sect4.4.5">4.4.5 conditional-directives</a></h4><p>The definitions of <em>#if</em> and <em>#either</em> conditional directives.</p><h4><a id="sect4.4.6" name="sect4.4.6">4.4.6 standard-directives</a></h4><p>The definitions of the standard directives (all except the block directive, conditional directives and special includes).</p><h4><a id="sect4.4.7" name="sect4.4.7">4.4.7 special-includes</a></h4><p>The definitions of <em>#include-binary</em>, <em>#include-string</em> and <em>#include-files</em> directives.</p><h4><a id="sect4.4.8" name="sect4.4.8">4.4.8 directives</a></h4><p>The <em>directives</em> variable refers to the block containing the definitions of directives that are currently used by <strong>include</strong>. There is usually no need to handle this variable directly since <strong>include-ctx/get-directives</strong>, <strong>include-ctx/set-directives</strong> and <strong>include-ctx/update-directives</strong> take care of it.</p><h4><a id="sect4.4.9" name="sect4.4.9">4.4.9 standard-header</a></h4><p>The <em>standard-header</em> variable refers to the script header prototype object. Defined for compatibility with R2 and R3.</p><h4><a id="sect4.4.10" name="sect4.4.10">4.4.10 file</a></h4><p>The <em>file</em> variable refers to the file processed by <strong>include</strong>.</p><h3><a id="sect4.5" name="sect4.5">4.5 include-ctx functions</a></h3><h4><a id="sect4.5.1" name="sect4.5.1">4.5.1 include-script</a></h4><p>The function used by <strong>include</strong> and by directives to preprocess a script.</p><h4><a id="sect4.5.2" name="sect4.5.2">4.5.2 include-block</a></h4><p>The function used by <strong>include-script</strong> and by directives to preprocess a block or a paren. Generated by the <strong>set-directives</strong> function.</p><h4><a id="sect4.5.3" name="sect4.5.3">4.5.3 get-directives</a></h4><p>Refers to a function returning the directives block used by <strong>include</strong>. The directives block is the block containing the definitions of all <strong>include</strong> directives.</p><h4><a id="sect4.5.4" name="sect4.5.4">4.5.4 set-directives</a></h4><p>Refers to a function setting the directives block used by <strong>include</strong>.</p><h4><a id="sect4.5.5" name="sect4.5.5">4.5.5 update-directives</a></h4><p>Refers to a function updating the <strong>directives</strong> (not modifying the block, though) using the given <strong>directives-to-update</strong> block. If a directive contained in the <strong>directives-to-update</strong> block is already present in the <strong>directives</strong> block it is updated. Otherwise it is appended as a new directive.</p><p>The usage of the <strong>set-directives</strong> function to update/add new <strong>include directives</strong> is not particularly comfortable. This function should be used as a more comfortable helper.</p><h4><a id="sect4.5.6" name="sect4.5.6">4.5.6 push</a></h4><p>Sometimes it is desirable to be able to temporarily redefine <strong>include-ctx/path</strong> while being able to restore its previous value after some time. The <strong>push</strong> function takes a <strong>new-path</strong> argument storing the current <strong>path</strong> contents to the <strong>stack</strong> and using the given <strong>new-path</strong> instead.</p><h4><a id="sect4.5.7" name="sect4.5.7">4.5.7 pop</a></h4><p>Restores the previous <strong>path</strong> value from the <strong>stack</strong>. It is the counterpart of the <strong>push</strong> function. If the <strong>stack</strong> is empty, an error is triggered.</p><h4><a id="sect4.5.8" name="sect4.5.8">4.5.8 do-next</a></h4><p>Do next expression using the "R3 convention", compatible with R2 and R3.</p><h4><a id="sect4.5.9" name="sect4.5.9">4.5.9 load-next</a></h4><p>Load the next value, compatible with R2 and R3.</p><h4><a id="sect4.5.10" name="sect4.5.10">4.5.10 read-binary</a></h4><p>Read a binary value from a source, compatible with R2 and R3.</p><h4><a id="sect4.5.11" name="sect4.5.11">4.5.11 make-error</a></h4><p>Make the error according to the given specifications, compatible with R2 and R3, allows setting the <em>near</em> and <em>where</em> attributes even in R2.</p><h4><a id="sect4.5.12" name="sect4.5.12">4.5.12 disarm-error</a></h4><p>Disarm the error, compatible with R2 and R3.</p><h4><a id="sect4.5.13" name="sect4.5.13">4.5.13 redo-error</a></h4><p>"enhance" (if needed) and redo the given error.</p><h4><a id="sect4.5.14" name="sect4.5.14">4.5.14 include-error</a></h4><p>Create and trigger a new include-type error.</p><h4><a id="sect4.5.15" name="sect4.5.15">4.5.15 split-path</a></h4><p>Splits the given path.</p><h4><a id="sect4.5.16" name="sect4.5.16">4.5.16 findpfile</a></h4><p>Find the given file using the given search path.</p><h4><a id="sect4.5.17" name="sect4.5.17">4.5.17 find-file</a></h4><p>Find a file (using <strong>include-ctx/path</strong> if desired).</p><h3><a id="sect4.6" name="sect4.6">4.6 The include error type</a></h3><p>A new <strong>include</strong> error type is defined, with the following ids:</p><h4><a id="sect4.6.1" name="sect4.6.1">4.6.1 enhanced</a></h4><p>This error represents an, otherwise "normal" error that occurred during code preprocessing. The error is "enhanced" to "know" the file in which it occurred.</p><h4><a id="sect4.6.2" name="sect4.6.2">4.6.2 file-or-url-in-path</a></h4><p>A file or a URL was expected in <strong>path</strong>.</p><h4><a id="sect4.6.3" name="sect4.6.3">4.6.3 stack-empty</a></h4><p>The <strong>pop</strong> function found the <strong>stack</strong> to be empty.</p><h4><a id="sect4.6.4" name="sect4.6.4">4.6.4 file-not-found</a></h4><p>The file to be included was not found.</p><h4><a id="sect4.6.5" name="sect4.6.5">4.6.5 expected</a></h4><p>The directive expected an argument.</p><h4><a id="sect4.6.6" name="sect4.6.6">4.6.6 invalid-directive</a></h4><p>The <strong>update-directives</strong> function obtained an invalid directive specification in the <strong>directives-to-update</strong> block.</p><h4><a id="sect4.6.7" name="sect4.6.7">4.6.7 script-bug</a></h4><p>The <strong>script?</strong> function has a bug in R2. The bug disallows R2 to skip script preface if the <strong>Rebol []</strong> header does not start with capital "R". This error signals that the problem occurred and the script was not loaded correctly.</p><div class="top"><span class="topbutton"><a href="#top">Back to Top</a></span></div><h2><a id="sect5" name="sect5">5. Usage examples</a></h2><p>A call corresponding to <strong>prebol</strong> processing <strong>%somefile.r</strong> and storing the result of the preprocessing to <strong>%outfile.r</strong> would look like:</p><pre class="example">include/link %somefile.r %outfile.r</pre><p>To change the <strong>include-ctx/path</strong>:</p><pre class="example">append include-ctx/path url-or-directory</pre><p>The <strong>include</strong> call corresponding to the <em>#include-check</em> directive is <strong>include/check</strong>, which preprocesses and runs the script only if it hasn't done so before:</p><pre class="example">include/check %somefile.r</pre><p>The <strong>include</strong> call using script arguments:</p><pre class="example">include/args %somefile.r "my-argument-string"</pre><p>The distinction between preprocessing directives and "normal" <strong>include</strong> usage is best described on simple examples:</p><p>The first example uses <strong>include</strong>, but not the preprocessing directives:</p><pre class="example">REBOL [
File: %script-builder.r
]
; create a new "standard" script from the script base
verbose: false
;
; use a clean LOG
clear include-ctx/log
include/link %script-base.r %standard-script.r
;
; now create a verbose version
verbose: true
clear include-ctx/log
include/link %script-base.r %verbose-script.r</pre><p>To create the two versions of the script containing everything they need to run it is sufficient to do:</p><pre class="example">include %script-builder.r</pre><p>which takes care of creating both script versions.</p><p>The <strong>%script-base.r</strong> file can look, e.g. as follows:</p><pre class="example">REBOL [
File: %script-base.r
]
#either [verbose] [debug: :print] [debug: none]
#include-check %part1.r
#include-check %part2.r
...</pre><h3><a id="sect5.1" name="sect5.1">5.1 Context encapsulation</a></h3><p>It is possible to encapsulate contexts as follows:</p><pre class="example">REBOL [
Title: "my script"
]
make object! [#include %your-script.r]
make module! [[module spec goes here] [#include %his-script.r]]</pre><h3><a id="sect5.2" name="sect5.2">5.2 User-defined directives</a></h3><p>New directives are defined using <strong>set-directives</strong> function or, more comfortably, using the <strong>update-directives</strong> function, which allows selective updating of <strong>include directives</strong>. The directives are written in the parse dialect. Even the standard directives are defined this way; it is possible to take their definition as an example.</p><p>The <strong>directives</strong> block is bound to the <strong>include-block</strong> function context by the <strong>set-directives</strong> function. Furthermore, the user can bind his <strong>directives</strong> block to <strong>include-ctx</strong> context if his directives use some of the <strong>include-ctx</strong> functions or variables.</p><p>The locals of the <strong>include-block</strong> function are:</p><h3><a id="sect5.3" name="sect5.3">5.3 pos1</a></h3><p>It is used in the definitions of the standard directives to hold the current position in the block (or paren) being included.</p><p>This variable can be and frequently is redefined.</p><h3><a id="sect5.4" name="sect5.4">5.4 pos2</a></h3><p>It is used in the definitions of the standard directives to hold the next position (the position following the currently processed directive part) in the block (or paren) being included.</p><p>This variable can be and frequently is redefined.</p><h3><a id="sect5.5" name="sect5.5">5.5 value1</a></h3><p>In the definitions of the standard directives it is being used to hold the first argument value of the currently processed directive.</p><p>This variable can be and frequently is redefined.</p><h3><a id="sect5.6" name="sect5.6">5.6 value2</a></h3><p>In the definitions of the standard directives it is being used to hold the second argument value of the currently processed directive.</p><p>This variable can be and frequently is redefined.</p><h3><a id="sect5.7" name="sect5.7">5.7 value3</a></h3><p>In the definitions of the standard directives it is being used to hold the third argument value of the currently processed directive.</p><p>This variable can be and frequently is redefined.</p><div class="top"><span class="topbutton"><a href="#top">Back to Top</a></span></div><h2><a id="sect6" name="sect6">6. The #print directive example</a></h2><p>The <em>#print</em> directive is meant as the debug-print directive. It uses the <em>debug</em> flag to find out whether to turn the directive into a <strong>print</strong> call, or simply leave it out from the code together with its argument.</p><p>Usage:</p><pre class="example">#print argument</pre><p>If the <em>debug</em> flag (global) is defined (set) when the <em>#print</em> directive is being processed, the directive is turned into a <strong>print</strong> call; otherwise it is left out from the code.</p><h3><a id="sect6.1" name="sect6.1">6.1 A definition of a #print directive</a></h3><pre class="example">Rebol [
Title: "Debug-print"
File: %debug-print.r
Author: "Ladislav Mecir"
Date: 21-Oct-2011/15:31:41+2:00
Purpose: {Defines the #print directive}
Notes: {
uses the debug flag (global)
if the debug flag is set, #print becomes print
otherwise, #print and its argument are left out
}
]
include-ctx/update-directives [
#print set value1 skip (
if value? 'debug [
append linked 'print
append/only linked get/any 'value1
]
)
]</pre><div class="top"><span class="topbutton"><a href="#top">Back to Top</a></span></div><h2><a id="sect7" name="sect7">7. How to's</a></h2><h3><a id="sect7.1" name="sect7.1">7.1 Include and relative paths</a></h3><p>To be compatible with <strong>do</strong>, <strong>include</strong> changes the working directory to that of the script it is processing. Note that relative paths are relative to the actual working directory, not to the directory that was actual when such paths were put into the <strong>include-ctx/path</strong> block.</p><p>For example, if we define:</p><pre class="example">include-ctx/path: reduce [%. clean-path %.]</pre><p>at the first sight it seems that the two elements in the above <strong>include-ctx/path</strong> are equivalent, but that is not true. The first one is a relative path always referring to the current working directory while the second one refers to the directory that was current when the <strong>include-ctx/path</strong> was defined.</p><h3><a id="sect7.2" name="sect7.2">7.2 How to evaluate an expression using a #do directive without including a value into the script</a></h3><p>This directive evaluates an expression and includes its result 2 into the script:</p><pre class="example">#do [1 + 1]</pre><p>while this one evaluates the expression as well, including nothing:</p><pre class="example">#do [1 + 1 []]</pre><h3><a id="sect7.3" name="sect7.3">7.3 How to write code detecting whether it has been preprocessed</a></h3><p>When a script is running, you may need to find out whether it has been preprocessed or not. Here is how:</p><pre class="example">; detect preprocessing
print case [
paren? first [#paren ()] [
"this code was preprocessed by Include"
]
integer? first [#do [1]] [
"this code was preprocessed by prebol"
]
'else [
"this code was not preprocessed"
]
]</pre><h3><a id="sect7.4" name="sect7.4">7.4 How to guard code containing preprocessor directives</a></h3><p>The <strong>%include.r</strong> script is an example of a script containing the preprocessor directives that we do not want to be preprocessed.</p><p>You may need to handle such situations yourself and write a script so that its behaviour is not influenced by the preprocessor.</p><pre class="example">do ([
; here we can put any code with preprocessor directives
; without worrying whether the user ran the script using DO or INCLUDE
; or how many times it was preprocessed
;
; this would catch unguarded preprocessing
#do [do make error! "Unguarded preprocessing."]
;
none
])</pre><h3><a id="sect7.5" name="sect7.5">7.5 How to run your scripts from Windows Explorer using include</a></h3><p>To run your scripts from Windows Explorer using <strong>include</strong> you:</p><ul><li>Download the <strong>%include.r</strong> script.</li><li>Create script files that perform the actions for the Windows Explorer associations.</li><li>Define associations for Windows Explorer context menu.</li></ul><h4><a id="sect7.5.1" name="sect7.5.1">7.5.1 Scripts for Windows Explorer associations</a></h4><p>The scripts below implement the actions for the Windows Explorer associations. Do not forget to use your own directory paths and file names.</p><pre class="example">Rebol [
Title: "Halt"
File: %halt.r
Author: "Ladislav Mecir"
Purpose: {
Includes the first argument file.
Halts after doint it.
Works with R2.
}
]
; define the INCLUDE function
do %include.r
; include the argument script
include to-rebol-file system/script/args
halt</pre><pre class="example">Rebol [
Title: "Incl"
File: %incl.r
Author: "Ladislav Mecir"
Purpose: {Includes the first argument file, works with R2}
]
; define the INCLUDE function
do %include.r
; include the argument script
include to-rebol-file system/script/args</pre><pre class="example">Rebol [
Title: "Incl.r3"
File: %incl.r3
Author: "Ladislav Mecir"
Date: 30-Sep-2011/10:23:03+2:00
Purpose: {Includes the first argument file, works with R3}
]
; define the INCLUDE function
do %include.r
;---- R3 GUI
include %/c/Develop/Rebol/codebase/trunk/r3-gui/loader/loader.r3
; include the argument script
include to-rebol-file system/script/args</pre><h4><a id="sect7.5.2" name="sect7.5.2">7.5.2 How to define associations for Windows Explorer</a></h4><p>You can use an <strong>r_auto_file.reg</strong> file to define the associations I am using. Having added the associations for the <strong>.r</strong> files, left-clicking a <strong>.r</strong> file in the Windows Explorer you will see the new <strong>open</strong>, <strong>halt</strong> and <strong>r3</strong> options, being able to choose which interpreter you want to start. See the example below. Do not forget to edit the source to use your own directory paths and file names.</p><pre class="example">Windows Registry Editor Version 5.00</pre><pre class="example">[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.r]
@="r_auto_file"</pre><pre class="example">[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\r_auto_file]</pre><pre class="example">[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\r_auto_file\shell]</pre><pre class="example">[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\r_auto_file\shell\open]</pre><pre class="example">[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\r_auto_file\shell\open\command]
@="\"C:\\Program Files\\Notepad++\\Notepad++.exe\" \"%1\""</pre><pre class="example">[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\r_auto_file\shell\halt.r2]</pre><pre class="example">[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\r_auto_file\shell\halt.r2\command]
@="\"C:\\Develop\\Rebol\\rebview.exe\" -s C:\\Develop\\Rebol\\halt.r \"%1\""</pre><pre class="example">[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\r_auto_file\shell\incl.r2]</pre><pre class="example">[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\r_auto_file\shell\incl.r2\command]
@="\"C:\\Develop\\Rebol\\rebview.exe\" -s C:\\Develop\\Rebol\\incl.r \"%1\""</pre><pre class="example">[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\r_auto_file\shell\incl.r3]</pre><pre class="example">[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\r_auto_file\shell\incl.r3\command]
@="\"C:\\Develop\\Rebol\\r3-view.exe\" -s C:\\Develop\\Rebol\\incl.r3 \"%1\""</pre><h4><a id="sect7.5.3" name="sect7.5.3">7.5.3 Possible interferences</a></h4><p>After using the Windows 7, Windows 8 or Windows 10 built-in "Choose default program..." action (found under the file-right-click context menu under "Open with") it re-associates the extension with whatever new program you choose. What happens at this point is that <strong>HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.r\UserChoice</strong> and possibly <strong>HKEY_CURRENT_USER\Software\Microsoft\Windows\Roaming\OpenWith\FileExts\.r\UserChoice</strong> are created/changed by the system and so the newly selected program takes over. To regain control over the extension you can delete the above <strong>UserChoice</strong> key/keys.</p><div class="top"><span class="topbutton"><a href="#top">Back to Top</a></span></div><h2><a id="sect8" name="sect8">8. Availability</a></h2><p><strong>Include</strong> is available from <strong>https://github.com/saphirion/include</strong>.</p><div class="top"><span class="topbutton"><a href="#top">Back to Top</a></span></div><h2><a id="sect9" name="sect9">9. Changelog</a></h2><p>26-Apr-2024/15:25:21+2:00</p><ul><li>update the documentation</li></ul><p>20-Apr-2024/9:00:35+2:00</p><ul><li>update the documentation</li></ul><p>5-Dec-2020/12:32:03+1:00</p><ul><li>update the documentation</li></ul><p>12-Nov-2020/10:54:32+1:00</p><ul><li>add a <em>#paren</em> directive to allow paren preprocessing when needed</li><li>update the documentation</li></ul><p>11-Nov-2020/11:44:26+1:00</p><ul><li>do not allow the preprocessor to process paren contents. Sorry for any discomfort this update may cause to the users, but it has got these advantages:<ul><li>makes the behaviour of <strong>include</strong> compatible with <strong>prebol</strong> in this respect</li></ul><ul><li>in contrast to the older versions, this gives the user a reliable tool allowing him to protect code containing preprocessor directives against preprocessing; see the how to</li></ul></li><li>circumvent a (most likely routine call-related) interpreter bug</li><li>update the documentation</li></ul><p>26-Apr-2017/12:47:36+2:00</p><ul><li>add script arguments to <strong>include</strong></li><li>update the documentation</li></ul><p>26-Jul-2015/11:20:13+2:00</p><ul><li>enhance the doc to inform how to revert the "Choose default program..." action effect</li></ul><p>5-Dec-2014/9:40:37+1:00</p><ul><li>define the <strong>script-bug</strong> error</li><li>handle the <strong>script?</strong> bug not skipping the script preface when the <strong>Rebol []</strong> header does not start with capital "R"</li></ul><p>21-Jun-2013/15:06:50+2:00</p><ul><li><strong>%include.r</strong> made encappable</li><li>the script and doc moved to Saphirion GitHub</li></ul><p>8-Apr-2013/13:00:27+2:00</p><ul><li><strong>include/link</strong> now using <strong>mold/flat</strong></li></ul><p>15-Mar-2013/12:17:52+1:00</p><ul><li><strong>include/only</strong> update<ul><li>to help Cyphre use it for encapping purposes</li></ul><ul><li>returns the Rebol header spec part in the result block if available</li></ul></li></ul><p>26-Dec-2012/15:00:27+1:00</p><ul><li>license updated to Apache 2.0</li></ul><p>14-Nov-2012/15:18:01+1:00</p><ul><li>the <em>file</em> variable moved from the <strong>include-block</strong> context to <strong>include-ctx</strong><ul><li>scripts can read the variable now,</li></ul><ul><li>"knowing" what is being processed (before, only directives "knew" the variable)</li></ul></li><li><strong>include-ctx/load-next</strong> function defined<ul><li>for compatibility with R2 and R3</li></ul></li><li><strong>script?</strong> function patched</li><li><strong>include</strong> function:<ul><li>header processing reimplemented to really work</li></ul><ul><li>header handling changed</li></ul><ul><ul><li>it is not a requirement to have a script header now in a manner compatible with R3 <strong>do</strong></li></ul></li></ul><ul><li>result corrected in a couple of special cases</li></ul><ul><li>help strings improved</li></ul></li><li>source punctuation improved</li><li>documentation updated</li></ul><p>21-Sep-2012/15:02:28+2:00</p><ul><li>addition of the <em>standard-header</em> variable to <strong>include-ctx</strong></li><li>script header processing added</li><li>doc update</li><li>the complete file made available from the rebol.org site</li></ul><p>10-Feb-2012/6:55:55+1:00</p><ul><li>adding the <strong>read-binary</strong> function to <strong>include-ctx</strong></li><li>updating the <em>#include-binary</em> and <em>#include-files</em> directives to work in R3</li></ul><p>17-Jan-2012/17:57:49+1:00</p><ul><li>circumventing the <strong>append</strong> bug in R2</li></ul><p>12-Jan-2012/14:35:27+1:00</p><ul><li><em>/only</em> refinement defined for the <strong>update-directives</strong> function</li><li><strong>special-includes</strong> defined</li></ul><p>9-Jan-2012/14:58:59+1:00</p><ul><li>the <em>in-file</em> bug in standard directives corrected</li><li>simple "pointer" file posted to <strong>http://www.rebol.org/view-script.r?script=ladislav-include.r rebol.org</strong></li></ul><p>10-Nov-2011/10:59:35+1:00</p><ul><li><strong>include-ctx/standard-directives</strong> subdivided (<strong>block-directive</strong> defined)</li><li>the block directive corrected (the correct <em>value1</em> variable used)</li><li>a new <strong>invalid-directive</strong> include error defined</li><li>the <strong>update-directives</strong> function updated to trigger the <strong>invalid-directive</strong> error</li><li><strong>include</strong> type errors documented</li><li>changes documented</li><li>directive identification adjusted</li><li>block-directive adjusted to be identifiable</li><li><em>#if</em>, <em>#either</em>, <em>#do</em>, <em>#include-files</em> directives adjusted</li></ul><p>8-Nov-2011/15:04:20+1:00</p><ul><li><strong>include-ctx/conditional-directives</strong> defined (improving the support for localization or other user-defined sets of directives)</li><li><strong>include-ctx/standard-directives</strong> defined (all standard directives except for the conditional ones)</li><li>comments in the code updated</li><li>no incompatibilities with the previous version expected</li></ul><p>21-Oct-2011/23:35:31+2:00</p><ul><li><strong>update-directives</strong> function adjusted to not modify the <strong>directives</strong> block, replacing it instead (safer)</li><li><strong>update-directives</strong> function defined</li><li>the <strong>debug-print</strong> example changed to use <strong>update-directives</strong></li><li>comments added to the code</li><li>the <em>#include-binary</em> and <em>#include-string</em> directives adjusted<ul><li>handling the situations when the <strong>find-file</strong> function doesn't find the given file</li></ul></li><li>doc changes</li></ul><p>13-Oct-2011/01:58:00+2:00</p><ul><li>RebGUI create-distribution problem solved</li><li>the <em>comment</em> directive made standard</li><li>the <strong>include-ctx</strong> context defined</li><li><strong>include</strong> variables (see above) moved to the <strong>include-ctx</strong> context<ul><li>(watch out for the obsolete use of <em>include-path</em>, <em>include-log</em>, <em>include-push</em> and <em>include-pop</em>)</li></ul></li><li>all helper functions moved to the <strong>include-ctx</strong> context (see above)<ul><li>which makes it easier for the user to use any of the helper functions in his own directives</li></ul></li><li><strong>include-parser</strong> function does not exist anymore</li><li><strong>set-directives</strong> function now generates the <strong>include-block</strong> function</li><li><em>localize-block</em> removed from the standard code<ul><li>(localization code now more complex, but more separate from the "standard code")</li></ul></li><li>error handling changed<ul><li><em>include</em> error type defined</li></ul><ul><li><strong>make-error</strong> function can define the <em>near</em> and <em>where</em> error attributes even in R2</li></ul></li><li>the definition of the <em>#print</em> directive reflects <strong>include</strong> changes</li><li>documentation updated</li><li>more comments in the <strong>%include.r</strong> file</li><li><strong>%include.r</strong> code cleaned up</li></ul><div class="top"><span class="topbutton"><a href="#top">Back to Top</a></span></div><h2><a id="sect10" name="sect10">10 See also</a></h2><p>The article</p><p><a href="http://www.rebol.org/art-display-article.r?article=w24v">http://www.rebol.org/art-display-article.r?article=w24v</a></p><p>describes how <strong>include</strong> was ported to Rebol 3.</p><div class="top"><span class="topbutton"><a href="#top">Back to Top</a></span></div><hr /><p class="end">Document formatter copyright <a href="http://www.robertmuench.de">Robert M. Münch</a>. All Rights Reserved.<br />XHTML 1.0 Transitional formatted with Make-Doc-Pro Version:1.3.0 on 26-Apr-2024 at 15:25:54</p></body></html>