mirror of
https://github.com/ganelson/inform.git
synced 2024-07-08 01:54:21 +03:00
302 lines
45 KiB
HTML
302 lines
45 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Paste Buttons</title>
|
|
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<meta name="viewport" content="width=device-width initial-scale=1">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
|
|
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<script>
|
|
function togglePopup(material_id) {
|
|
var popup = document.getElementById(material_id);
|
|
popup.classList.toggle("show");
|
|
}
|
|
</script>
|
|
|
|
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
|
|
</head>
|
|
<body class="commentary-font">
|
|
<nav role="navigation">
|
|
<h1><a href="../index.html">
|
|
<img src="../docs-assets/Inform.png" height=72">
|
|
</a></h1>
|
|
<ul><li><a href="../index.html">home</a></li>
|
|
</ul><h2>Compiler</h2><ul>
|
|
<li><a href="../structure.html">structure</a></li>
|
|
<li><a href="../inbuildn.html">inbuild</a></li>
|
|
<li><a href="../inform7n.html">inform7</a></li>
|
|
<li><a href="../intern.html">inter</a></li>
|
|
<li><a href="../services.html">services</a></li>
|
|
<li><a href="../secrets.html">secrets</a></li>
|
|
</ul><h2>Other Tools</h2><ul>
|
|
<li><a href="../inblorbn.html">inblorb</a></li>
|
|
<li><a href="../indocn.html">indoc</a></li>
|
|
<li><a href="../inform6.html">inform6</a></li>
|
|
<li><a href="../inpolicyn.html">inpolicy</a></li>
|
|
<li><a href="../inrtpsn.html">inrtps</a></li>
|
|
</ul><h2>Resources</h2><ul>
|
|
<li><a href="../extensions.html">extensions</a></li>
|
|
<li><a href="../kits.html">kits</a></li>
|
|
</ul><h2>Repository</h2><ul>
|
|
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
|
|
</ul><h2>Related Projects</h2><ul>
|
|
<li><a href="../../../inweb/index.html">inweb</a></li>
|
|
<li><a href="../../../intest/index.html">intest</a></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
<main role="main">
|
|
<!--Weave of 'Paste Buttons' generated by Inweb-->
|
|
<div class="breadcrumbs">
|
|
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../services.html">Services</a></li><li><a href="index.html">html</a></li><li><a href="index.html#2">Chapter 2: Intranet</a></li><li><b>Paste Buttons</b></li></ul></div>
|
|
<p class="purpose">HTML for a button which, when clicked, pastes Inform source text into the Source panel of the application, or opens a file or folder on the host computer.</p>
|
|
|
|
<ul class="toc"><li><a href="2-pb.html#SP1">§1. Pastes and their notation</a></li><li><a href="2-pb.html#SP3">§3. Buttons</a></li><li><a href="2-pb.html#SP5">§5. File-opener buttons</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§1. Pastes and their notation. </b>A paste button is intended to be such that the user clicks it, and some
|
|
text is inserted at the current cursor position in the Source panel of the
|
|
Inform application.
|
|
</p>
|
|
|
|
<p class="commentary">This is done with Javascript which looks something like this:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> var myProject = window.Project;</span>
|
|
<span class="plain-syntax"> myProject.selectView('source');</span>
|
|
<span class="plain-syntax"> myProject.pasteCode('Trying Taking Manhattan');</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>§2. </b>The challenges here are that (a) the code to be pasted may be, say, as much
|
|
as 5K in size, and that (b) it needs to include some special characters,
|
|
escaped in a way which the app has to deal with correctly. This has proved
|
|
a challenge because, historically, different Javascript implementations
|
|
have handled escape characters in quoted text differently. (For instance, some
|
|
allowing a double-quote <span class="extract"><span class="extract-syntax">"</span></span> to appear as a literal in single-quoted text, others
|
|
requiring <span class="extract"><span class="extract-syntax">&quot;</span></span> to be used, and others not recognising HTML entities such as
|
|
<span class="extract"><span class="extract-syntax">&quot;</span></span> at all.)
|
|
</p>
|
|
|
|
<p class="commentary">To avoid this issue, Inform adopted a notation of its own in 2007. All
|
|
Inform GUI apps have to follow this rule when reading the argument to
|
|
<span class="extract"><span class="extract-syntax">pasteCode</span></span>:
|
|
</p>
|
|
|
|
<p class="commentary">Each instance of <span class="extract"><span class="extract-syntax">[=0xHHHH=]</span></span> is replaced with the Unicode character whose
|
|
hexadecimal code is <span class="extract"><span class="extract-syntax">HHHH</span></span>; there will always be four digits, with leading
|
|
zeros as needed, and <span class="extract"><span class="extract-syntax">A</span></span> to <span class="extract"><span class="extract-syntax">F</span></span> will be written in upper case. The only
|
|
Unicode characters with codes below <span class="extract"><span class="extract-syntax">0x0020</span></span> which must be handled are
|
|
newline, <span class="extract"><span class="extract-syntax">0x000A</span></span>, and tab, <span class="extract"><span class="extract-syntax">0x0009</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary">And any Inform tool generating such an argument — either the renderer below,
|
|
or the one in <a href="../indoc/index.html" class="internal">indoc</a>, which also generates pastes — must use this notation
|
|
to escape every instance of the following problematic characters:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) every tab is escaped to <span class="extract"><span class="extract-syntax">[=0x0009=]</span></span>;
|
|
</li><li>(b) every newline is escaped to <span class="extract"><span class="extract-syntax">[=0x000A=]</span></span>;
|
|
</li><li>(c) every double quotation mark is escaped to <span class="extract"><span class="extract-syntax">[=0x0022=]</span></span>;
|
|
</li><li>(d) every ampersand is escaped to <span class="extract"><span class="extract-syntax">[=0x0026=]</span></span>;
|
|
</li><li>(e) every single quotation mark is escaped to <span class="extract"><span class="extract-syntax">[=0x0027=]</span></span>;
|
|
</li><li>(f) every less than sign is escaped to <span class="extract"><span class="extract-syntax">[=0x003C=]</span></span>;
|
|
</li><li>(g) every greater than sign is escaped to <span class="extract"><span class="extract-syntax">[=0x003E=]</span></span>;
|
|
</li><li>(h) every backslash is escaped to <span class="extract"><span class="extract-syntax">[=0x005C=]</span></span>.
|
|
</li></ul>
|
|
<p class="commentary">It may also choose to escape other character codes, as it prefers, but will
|
|
never generate any codes below <span class="extract"><span class="extract-syntax">0x0020</span></span> other than newline, <span class="extract"><span class="extract-syntax">0x000A</span></span>, and tab,
|
|
<span class="extract"><span class="extract-syntax">0x0009</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary">The app can therefore assume that none of these problematic characters occur
|
|
in raw form in the argument to <span class="extract"><span class="extract-syntax">pasteCode</span></span>.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">PasteButtons::put_code_char</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">PasteButtons::put_code_char</span></span>:<br/><a href="2-pb.html#SP4">§4</a>, <a href="2-pb.html#SP4_1">§4.1</a>, <a href="2-pb.html#SP4_1_1">§4.1.1</a>, <a href="2-pb.html#SP4_1_2">§4.1.2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'\t'</span><span class="plain-syntax">: </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[=0x0009=]"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'\n'</span><span class="plain-syntax">: </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEWLINE_IN_STRING:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[=0x000A=]"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'"'</span><span class="plain-syntax">: </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[=0x0022=]"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'&'</span><span class="plain-syntax">: </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[=0x0026=]"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'\''</span><span class="plain-syntax">: </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[=0x0027=]"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'<'</span><span class="plain-syntax">: </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[=0x003C=]"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'>'</span><span class="plain-syntax">: </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[=0x003E=]"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'\\'</span><span class="plain-syntax">: </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[=0x005C=]"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="identifier-syntax">PUT</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§3. Buttons. </b>The button is simply an image with a link using the <span class="extract"><span class="extract-syntax">javascript:</span></span> protocol
|
|
to call a suitable function.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">PasteButtons::paste_W</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">PasteButtons::paste_W</span></span>:<br/>Documentation Renderer - <a href="2-dr.html#SP9_3_1">§9.3.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><a href="2-pb.html#SP3" class="function-link"><span class="function-syntax">PasteButtons::paste_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">), </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">), </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">PasteButtons::paste_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt_stream</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><a href="2-pb.html#SP3" class="function-link"><span class="function-syntax">PasteButtons::paste_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, -1, -1, </span><span class="identifier-syntax">alt_stream</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">PasteButtons::paste_inner</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">to</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt_stream</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">link</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">link</span><span class="plain-syntax">, </span><span class="string-syntax">"href=\"javascript:pasteCode("</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="2-pb.html#SP4" class="function-link"><span class="function-syntax">PasteButtons::argument</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">link</span><span class="plain-syntax">, </span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="identifier-syntax">to</span><span class="plain-syntax">, </span><span class="identifier-syntax">alt_stream</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">link</span><span class="plain-syntax">, </span><span class="string-syntax">")\""</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_OPEN_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"a"</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">link</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">link</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_TAG_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"img"</span><span class="plain-syntax">, </span><span class="string-syntax">"border=0 src=inform:/doc_images/paste.png"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"a"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>§4. </b>In the following, the source of the text can be either a range of words
|
|
from the lexer (as for instance when a portion of an extension is being
|
|
typeset as documentation, with an example that can be pasted), or can
|
|
be a C string: if the latter, then its encoding must be ISO Latin-1.
|
|
The conversion to UTF-8 is performed in <span class="extract"><span class="extract-syntax">PasteButtons::put_code_char</span></span> below.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">PasteButtons::argument</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">PasteButtons::argument</span></span>:<br/><a href="2-pb.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">to</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt_stream</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"'"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">alt_stream</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">alt_stream</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="2-pb.html#SP2" class="function-link"><span class="function-syntax">PasteButtons::put_code_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">from</span><span class="plain-syntax"> >= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-pb.html#SP4_1" class="named-paragraph-link"><span class="named-paragraph">Write word range as Javascript string</span><span class="named-paragraph-number">4.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"'"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP4_1" class="paragraph-anchor"></a><b>§4.1. </b>Writing a word range is much harder. In effect, we have to provide an
|
|
inverse function for the lexer, which converted raw source text to nicely
|
|
packaged up words.
|
|
</p>
|
|
|
|
<p class="commentary">See Lexer for details of how words are stored, and in particular for the
|
|
<span class="extract"><span class="extract-syntax">lw_break</span></span> character, which is <span class="extract"><span class="extract-syntax">'\t'</span></span> when the word followed a tab, but is
|
|
<span class="extract"><span class="extract-syntax">'1'</span></span> to <span class="extract"><span class="extract-syntax">'9'</span></span> when it followed a newline plus that many tabs. We need
|
|
this because lexing has otherwise removed whitespace from the source, and
|
|
we need it back again if we're to paste a faithful Javascript representation:
|
|
otherwise the tabs used as column-dividers in tables will not come through,
|
|
for instance. Moreover, indentation from the left margin is used to make
|
|
prettier pastes (which respect the layout of the original examples from
|
|
which the paste has been made), and for that we need the <span class="extract"><span class="extract-syntax">'1'</span></span> to <span class="extract"><span class="extract-syntax">'9'</span></span>
|
|
possibilities.
|
|
</p>
|
|
|
|
<p class="commentary">Note that we expect the material pasted to be indented at 1 tab stop from
|
|
the margin already, because it will almost always be a source text within
|
|
an example, where any matter unindented will be commentary rather than
|
|
source text. Thus a single tab after a newline is not significant, and we
|
|
only need to supply extra Javascript tabs when the indentation is 2 tab
|
|
stops or more.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Write word range as Javascript string</span><span class="named-paragraph-number">4.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">suppress_space</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">follows_paragraph_break</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">close_I6_position</span><span class="plain-syntax"> = -1;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=</span><span class="identifier-syntax">from</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax"><=</span><span class="identifier-syntax">to</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::word_raw_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">PARBREAK_V</span><span class="plain-syntax">) { </span><span class="comment-syntax"> marker for a paragraph break</span>
|
|
<span class="plain-syntax"> </span><a href="2-pb.html#SP2" class="function-link"><span class="function-syntax">PasteButtons::put_code_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="character-syntax">'\n'</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="2-pb.html#SP2" class="function-link"><span class="function-syntax">PasteButtons::put_code_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="character-syntax">'\n'</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">suppress_space</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">follows_paragraph_break</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">PARBREAK_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">i</span><span class="plain-syntax">++; </span><span class="identifier-syntax">i</span><span class="plain-syntax">--; </span><span class="comment-syntax"> elide multiple breaks</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">indentation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::indentation_level</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">indentation</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="comment-syntax"> number of tab stops of indentation on this para</span>
|
|
<span class="plain-syntax"> </span><a href="2-pb.html#SP2" class="function-link"><span class="function-syntax">PasteButtons::put_code_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="character-syntax">'\n'</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">j</span><span class="plain-syntax"><</span><span class="identifier-syntax">indentation</span><span class="plain-syntax">-1; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++) </span><a href="2-pb.html#SP2" class="function-link"><span class="function-syntax">PasteButtons::put_code_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="character-syntax">'\t'</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">suppress_space</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Lexer::break_before</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="character-syntax">'\t'</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">follows_paragraph_break</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><a href="2-pb.html#SP2" class="function-link"><span class="function-syntax">PasteButtons::put_code_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="character-syntax">'\t'</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">suppress_space</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">follows_paragraph_break</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">suppress_space</span><span class="plain-syntax">==</span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pb.html#SP4_1_1" class="named-paragraph-link"><span class="named-paragraph">Restore inter-word spaces unless this would be unnatural</span><span class="named-paragraph-number">4.1.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">suppress_space</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">]; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++) </span><a href="2-pb.html#SP2" class="function-link"><span class="function-syntax">PasteButtons::put_code_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">]);</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pb.html#SP4_1_2" class="named-paragraph-link"><span class="named-paragraph">Insert a close-literal-I6 escape sequence if necessary</span><span class="named-paragraph-number">4.1.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><a href="2-pb.html#SP2" class="function-link"><span class="function-syntax">PasteButtons::put_code_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="character-syntax">'\n'</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="2-pb.html#SP2" class="function-link"><span class="function-syntax">PasteButtons::put_code_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="character-syntax">'\n'</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="2-pb.html#SP4">§4</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP4_1_1" class="paragraph-anchor"></a><b>§4.1.1. </b>The lexer also broke words around punctuation marks, so that, for instance,
|
|
"fish, finger" would have been lexed as <span class="extract"><span class="extract-syntax">fish , finger</span></span> — three words.
|
|
But we want to restore the more natural spacing.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Restore inter-word spaces unless this would be unnatural</span><span class="named-paragraph-number">4.1.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">i</span><span class="plain-syntax">></span><span class="identifier-syntax">from</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> && ((</span><span class="identifier-syntax">p</span><span class="plain-syntax">[1] != </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">Lexer::is_punctuation</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">[0]) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) ||</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[0] == </span><span class="character-syntax">'('</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[0] == </span><span class="character-syntax">'{'</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[0] == </span><span class="character-syntax">'}'</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> && (</span><span class="identifier-syntax">compare_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">-1, </span><span class="identifier-syntax">OPENBRACKET_V</span><span class="plain-syntax">)==</span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><a href="2-pb.html#SP2" class="function-link"><span class="function-syntax">PasteButtons::put_code_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="character-syntax">' '</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="2-pb.html#SP4_1">§4.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP4_1_2" class="paragraph-anchor"></a><b>§4.1.2. </b>Finally, the lexer rendered a literal I6 inclusion in the form <span class="extract"><span class="extract-syntax">(- self=2;</span></span>
|
|
as a sequence of two lexical words: <span class="extract"><span class="extract-syntax">(-</span></span> and then <span class="extract"><span class="extract-syntax">self=2;</span></span>. In order
|
|
to paste back safely, we must supplement this with the closure <span class="extract"><span class="extract-syntax">-)</span></span> once
|
|
again:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Insert a close-literal-I6 escape sequence if necessary</span><span class="named-paragraph-number">4.1.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">OPENI6_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">close_I6_position</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">+1;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">close_I6_position</span><span class="plain-syntax"> == </span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><a href="2-pb.html#SP2" class="function-link"><span class="function-syntax">PasteButtons::put_code_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="character-syntax">'-'</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="2-pb.html#SP2" class="function-link"><span class="function-syntax">PasteButtons::put_code_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="character-syntax">')'</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="2-pb.html#SP2" class="function-link"><span class="function-syntax">PasteButtons::put_code_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="character-syntax">' '</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="2-pb.html#SP4_1">§4.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. File-opener buttons. </b>Nothing to do with pastes: this is a completely different sort of button,
|
|
though also powered by Javascript. It opens a file or folder on the host
|
|
filing system.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">PasteButtons::open_file</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">leaf</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">contents</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">fn</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">leaf</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">fn</span><span class="plain-syntax">, </span><span class="string-syntax">"%f"</span><span class="plain-syntax">, </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">leaf</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">fn</span><span class="plain-syntax">, </span><span class="string-syntax">"%p"</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">WINDOWS_JAVASCRIPT</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">fn</span><span class="plain-syntax">) </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">) == </span><span class="character-syntax">'\\'</span><span class="plain-syntax">) </span><span class="identifier-syntax">Str::put</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="character-syntax">'/'</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_OPEN_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"a"</span><span class="plain-syntax">, </span><span class="string-syntax">"href='javascript:project().openFile(\"%S\")'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">fn</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_TAG_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"img"</span><span class="plain-syntax">, </span><span class="string-syntax">"%s"</span><span class="plain-syntax">, </span><span class="identifier-syntax">contents</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"a"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">fn</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<nav role="progress"><div class="progresscontainer">
|
|
<ul class="progressbar"><li class="progressprev"><a href="2-sl.html">❮</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-hm.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresssection"><a href="2-ip.html">ip</a></li><li class="progresssection"><a href="2-sl.html">sl</a></li><li class="progresscurrent">pb</li><li class="progresssection"><a href="2-dr.html">dr</a></li><li class="progresssection"><a href="2-if.html">if</a></li><li class="progresssection"><a href="2-dr2.html">dr2</a></li><li class="progresssection"><a href="2-lcl.html">lcl</a></li><li class="progressnext"><a href="2-dr.html">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|