[e-cvs] cvs commit: e/src/jsrc/org/erights/e/meta/java/lang CharacterSugar.java

markm@eros.cs.jhu.edu markm@eros.cs.jhu.edu
Mon, 16 Jul 2001 06:42:48 -0400


markm       01/07/16 06:42:48

  Modified:    doc/elang/collect index.html tables.html
               doc/elang/io text-file-io.html
               src/esrc/scripts eBrowser.e
               src/jsrc/org/erights/e/elib/base TextWriter.java
               src/jsrc/org/erights/e/elib/tables Twine.java
               src/jsrc/org/erights/e/meta/java/io BufferedReaderSugar.java
               src/jsrc/org/erights/e/meta/java/lang CharacterSugar.java
  Log:
  updoc driven progress

Revision  Changes    Path
1.24      +2 -2      e/doc/elang/collect/index.html

Index: index.html
===================================================================
RCS file: /cvs/e/doc/elang/collect/index.html,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- index.html	2001/05/07 08:29:24	1.23
+++ index.html	2001/07/16 10:42:48	1.24
@@ -83,7 +83,7 @@
         <pre>? def erightsDir := &lt;file:/erights.org&gt;
 # value: &lt;file:/erights.org/&gt;
 
-? erightsDir["Setup.bat"] length
+? erightsDir["Setup.bat"] length()
 # value: 359
 </pre>
       </blockquote>
@@ -94,7 +94,7 @@
       <p> 
       <blockquote> 
         <pre>? for name => file in erightsDir {
->     println(`$name is ${file length} bytes`)
+>     println(`$name is ${file length()} bytes`)
 > }
 bin is 0 bytes
 Setup.bat is 359 bytes



1.31      +49 -48    e/doc/elang/collect/tables.html

Index: tables.html
===================================================================
RCS file: /cvs/e/doc/elang/collect/tables.html,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- tables.html	2001/05/07 08:29:24	1.30
+++ tables.html	2001/07/16 10:42:48	1.31
@@ -333,61 +333,60 @@
       <p>Here's the color spectrum according to a silly mnemonic many of us learned
         in grade school, represented as an ConstList:</p>
       <p>
-      <blockquote>
+      <blockquote> 
         <pre>? def spectrum := <b>[</b>"red", "orange", "yellow", "green",
 &gt;                     "blue", "indigo", "violet"<b>]</b>
-# value: [red, orange, yellow, green, blue, indigo, violet] </pre>
+# value: [&quot;red&quot;, &quot;orange&quot;, &quot;yellow&quot;, &quot;green&quot;, &quot;blue&quot;, &quot;indigo&quot;, &quot;violet&quot;] </pre>
       </blockquote>
       We can look up the value at a particular index using the familiar indexing
       notation:
-      <blockquote>
+      <blockquote> 
         <pre>
 ? spectrum<b>[</b>2<b>]
-</b># value: yellow </pre>
+</b># value: &quot;yellow&quot; </pre>
       </blockquote>
       <p>We can extract sub-lists, or <i>runs</i>, by using parens and providing
         a start position and a stop position:</p>
       <p>
-      <blockquote>
+      <blockquote> 
         <pre>? spectrum(1, 3)
-# value: [orange, yellow]
-</pre>
+# value: [&quot;orange&quot;, &quot;yellow&quot;]</pre>
       </blockquote>
       <p>This extracts the run from the start position, including the start position,
         up to <i>but not including</i> the stop position. The stop position is
         the first position after the run.</p>
       <p>We can loop through the spectrum using the <a href="../blocks/forExpr.html">for
         loop</a>: </p>
-      <blockquote>
+      <blockquote> 
         <pre>
-? def mnemonic := ""
-# value:
-
+? var mnemonic := ""
+# value: &quot;&quot;
+ 
 ? <b>for</b> color <b>in</b> spectrum {
 &gt;     mnemonic <b>+=</b> color[0]
 &gt; }
 
 ? mnemonic
-# value: roygbiv
+# value: &quot;roygbiv&quot;
 </pre>
       </blockquote>
       <p>What about the &quot;<code>+=</code>&quot; to accumulate the mnemonic?
         ELists can be concatenated with &quot;+&quot;. Here's the spectrum rotated:</p>
-      <blockquote>
-        <pre>? spectrum(3, spectrum size) <b>+</b> spectrum(0, 3)
-# value: [green, blue, indigo, violet, red, orange, yellow]</pre>
+      <blockquote> 
+        <pre>? spectrum(3, spectrum size()) <b>+</b> spectrum(0, 3)
+# value: [&quot;green&quot;, &quot;blue&quot;, &quot;indigo&quot;, &quot;violet&quot;, &quot;red&quot;, &quot;orange&quot;, &quot;yellow&quot;]</pre>
       </blockquote>
       <p><code>spectrum(0, 3)</code> requests the run from 0 inclusive to 3 exclusive.
         <code>spectrum(3, spectrum size)</code> requests the run from 3 inclusive
         to the end.</p>
       <p>The values in an EList can be any object, including itself:</p>
       <p>
-      <blockquote>
+      <blockquote> 
         <pre>? def infinitree := ["left", infinitree, "rt"]
-# value: [left, ***CYCLE***, rt]
+# value: [&quot;left&quot;, ***CYCLE***, &quot;rt&quot;]
 
 ? infinitree[1][1][1][0]
-# value: left </pre>
+# value: &quot;left&quot; </pre>
       </blockquote>
       <p>Although this is implemented as a cyclic data structure, it represents
         an infinite repeating data structure:</p>
@@ -403,35 +402,37 @@
         we modify this list, its state will <i>diverge</i> from spectrum's, so
         that's how we ask for it:</p>
       <p>
-      <blockquote>
-        <pre>? def flextrum := spectrum <b>diverge</b>
-# value: [red, orange, yellow, green, blue, indigo, violet] diverge
+      <blockquote> 
+        <pre>? def flextrum := spectrum <b>diverge</b>()
+# value: [&quot;red&quot;, &quot;orange&quot;, &quot;yellow&quot;, &quot;green&quot;, &quot;blue&quot;, &quot;indigo&quot;, &quot;violet&quot;] diverge
 </pre>
       </blockquote>
       <p>We can then assign to individual elements</p>
       <p>
-      <blockquote>
+      <blockquote> 
         <pre>? flextrum<b>[</b>1<b>] :=</b> "burnt-orange"
-
+# value: &quot;burnt-orange&quot;
+ 
 ? flextrum
-# value: [red, burnt-orange, yellow, green, blue, indigo, violet] diverge
+# value: [&quot;red&quot;, &quot;burnt-orange&quot;, &quot;yellow&quot;, &quot;green&quot;, &quot;blue&quot;, &quot;indigo&quot;, &quot;violet&quot;] diverge
 </pre>
       </blockquote>
       <p>or to runs</p>
       <p>
-      <blockquote>
+      <blockquote> 
         <pre>? flextrum<b>(</b>3,6<b>) :=</b> ["cyan", "sky-blue"]
-
+# value [&quot;cyan&quot;, &quot;sky-blue&quot;]
+ 
 ? flextrum
-# value: [red, burnt-orange, yellow, cyan, sky-blue, violet] diverge</pre>
+# value: [&quot;red&quot;, &quot;burnt-orange&quot;, &quot;yellow&quot;, &quot;cyan&quot;, &quot;sky-blue&quot;, &quot;violet&quot;] diverge</pre>
       </blockquote>
       <p>Notice that the size of the run replaced can differ from the size of
         the run replacing it. The rest of the list slides over to accommodate.
         A <i>read-only</i> facet of a list allows one to observe the current state
         of the list, but not to change it.</p>
-      <blockquote>
-        <pre>? def rainbow := flextrum <b>readOnly</b>
-# value: [red, burnt-orange, yellow, cyan, sky-blue, violet] diverge readOnly
+      <blockquote> 
+        <pre>? def rainbow := flextrum <b>readOnly</b>()
+# value: [&quot;red&quot;, &quot;burnt-orange&quot;, &quot;yellow&quot;, &quot;cyan&quot;, &quot;sky-blue&quot;, &quot;violet&quot;] diverge readOnly
 
 ? rainbow[2] := "light yellow"
 # problem: &lt;NoSuchMethodException: put/2&gt;
@@ -442,7 +443,7 @@
         one, or we can take a <i>snapshot</i>.</p>
       <p>
       <blockquote>
-        <pre>? def colors := flextrum <b>snapshot</b>
+        <pre>? def colors := flextrum <b>snapshot</b>()
 # value: [red, burnt-orange, yellow, cyan, sky-blue, violet]
 
 ? flextrum(1,1) := ["mauve"]
@@ -473,9 +474,9 @@
       <p>
       <blockquote>
         <pre>? def parentMapM := ["MarkM" <b>=></b> ["Ann",   "Bernie"],
->                       "Jeff"  <b>=></b> ["Ann",   "Bernie"],
->                       "Ann"   <b>=></b> ["Grina", "Isaac"],
->                       "Max"   <b>=></b> ["Lisa",  "Jeff"]]</pre>
+>                    "Jeff"  <b>=></b> ["Ann",   "Bernie"],
+>                    "Ann"   <b>=></b> ["Grina", "Isaac"],
+>                    "Max"   <b>=></b> ["Lisa",  "Jeff"]]</pre>
       </blockquote>
       <p>Notice that a two-element EList is a natural way to write a pair.</p>
       <p>Of course, we can look up someone's parents </p>
@@ -502,10 +503,10 @@
       <blockquote>
         <pre>
 ? def parentMapT := ["Terry"   => ["Betty", "Bill"],
->                       "Cindy"   => ["Betty", "Bill"],
->                       "Everett" => ["Betty", "Bill"],
->                       "Angie"   => ["Cindy", "Louis"],
->                       "Mandy"   => ["Cindy", "Louis"]]</pre>
+>                    "Cindy"   => ["Betty", "Bill"],
+>                    "Everett" => ["Betty", "Bill"],
+>                    "Angie"   => ["Cindy", "Louis"],
+>                    "Mandy"   => ["Cindy", "Louis"]]</pre>
       </blockquote>
       For example, let's say <code>parentMapT</code> represents another family,
       and we wish to combine the families
@@ -513,7 +514,7 @@
         <pre>
 ? def parentMapMT := parentMapT <b>|</b> parentMapM
 
-? (parentMapM <b>&</b> parentMapT) size
+? (parentMapM <b>&amp;</b> parentMapT) size()
 # value: 0</pre>
       </blockquote>
       <p>The &quot;<code>|</code>&quot; operator brings about a union of the families
@@ -560,8 +561,8 @@
       <p>
       <blockquote>
         <pre>? def CapLanguages := ["E" => null,
-&gt;                         "Joule" => null,
-&gt;                         "Trusty Scheme" => null]
+&gt;                      "Joule" => null,
+&gt;                      "Trusty Scheme" => null]
 # value: [E => null, Trusty Scheme => null, Joule => null]
 </pre>
       </blockquote>
@@ -569,7 +570,7 @@
         to write. This convenience</p>
       <p>
       <blockquote>
-        <pre>? def CapLanguages := ["E", "Joule", "Trusty Scheme"] <b>asKeys</b>
+        <pre>? def CapLanguages := ["E", "Joule", "Trusty Scheme"] <b>asKeys</b>()
 # value: [E => null, Trusty Scheme => null, Joule => null]
 </pre>
       </blockquote>
@@ -581,10 +582,10 @@
         Open-Source systems.</p>
       <p>
       <blockquote>
-        <pre>? def CapOSs := ["Hydra", "KeyKOS", "EROS"] asKeys
+        <pre>? def CapOSs := ["Hydra", "KeyKOS", "EROS"] asKeys()
 # value: [Hydra => null, EROS => null, KeyKOS => null]
 
-? def OpenSource := ["Linux", "Netscape", "Apache", "E", "EROS"] asKeys
+? def OpenSource := ["Linux", "Netscape", "Apache", "E", "EROS"] asKeys()
 # value: [E => null, EROS => null, Apache => null,
 #         Linux => null, Netscape => null]
 
@@ -592,7 +593,7 @@
 # value: [Hydra => null, E => null, Joule => null,
 #         Trusty Scheme => null, EROS => null, KeyKOS => null]
 
-? def OpenCaps := CapSystems <b>&</b> OpenSource
+? def OpenCaps := CapSystems <b>&amp;</b> OpenSource
 # value: [E => null, EROS => null]
 
 ? def ClosedCaps := CapSystems <b>-</b> OpenSource
@@ -603,15 +604,15 @@
       <p>Since we know we're only interested in the keys, by asking for a list
         of the keys:</p>
       <blockquote>
-        <pre>? OpenCaps <b>getKeys</b>
+        <pre>? OpenCaps <b>getKeys</b>()
 # value: [E, EROS]
 </pre>
       </blockquote>
       <p>we see the list of all open-source capability systems known to this author.
         But beware, the EMap is not the terrain.</p>
       <h3>Changing EMaps</h3>
-      <p>EMaps respond to <code>diverge</code>, <code>snapshot</code>, and <code>readOnly</code>
-        in exactly the same way ELists do.</p>
+      <p>EMaps respond to <code>diverge()</code>, <code>snapshot()</code>, and 
+        <code>readOnly()</code> in exactly the same way ELists do.</p>
       <!-- #EndEditable --></TD>
     <TD WIDTH="10%">&nbsp;</TD>
   </TR>



1.5       +173 -141  e/doc/elang/io/text-file-io.html

Index: text-file-io.html
===================================================================
RCS file: /cvs/e/doc/elang/io/text-file-io.html,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- text-file-io.html	2001/07/16 03:28:30	1.4
+++ text-file-io.html	2001/07/16 10:42:48	1.5
@@ -46,15 +46,38 @@
         </TR>
       </TABLE>
       <hr>
-      <!-- #BeginEditable "LongBody" -->
-      <p>As explained in <a href="uri-exprs.html"><i>URI Expressions</i></a>,
-        the value of a &quot;file:&quot; URI expression is a java.io.File object.
-        Such a file object doesn't necessarily represent a file that already exists
-        on your file system. It might represent an existing directory, an existing
-        &quot;normal&quot; file (a non-directory), or it might represent a file
-        that doesn't yet exist -- a potential file or directory. You can test
-        which as follows:</p>
-      <blockquote>
+      <!-- #BeginEditable "LongBody" --> 
+      <h2>Pay no attention to the man behind the curtain.</h2>
+      <p>(The following lines of code set up your file system so that this test 
+        will succeed. It fetches the text of the Jabberwock poem <a href="http://www.erights.org/elang/intro/jabberwocky.txt">from 
+        the web</a> and places it into your &quot;<code>c:/jabbertest/</code>&quot; 
+        directory, which it creates if needed. It also ensures deletes any files 
+        or directories named &quot;<code>jabberwocky2.txt</code>&quot; or &quot;<code>a</code>&quot; 
+        in that directory if such exists, since the following test cases make 
+        use of their absence.)</p>
+      <p> 
+      <blockquote> 
+        <pre>? def poem := &lt;http://www.erights.org/elang/intro/jabberwocky.txt&gt;
+# value: &lt;http://www.erights.org/elang/intro/jabberwocky.txt&gt;
+ 
+? &lt;file:c:/jabbertest&gt; mkdirs(); null
+? &lt;file:c:/jabbertest/jabberwocky.txt&gt; setText(poem getText())
+? &lt;file:c:/jabbertest/jabberwocky2.txt&gt; delete(); null
+? &lt;file:c:/jabbertest/a/b/c&gt; delete(); null
+? &lt;file:c:/jabbertest/a/b&gt; delete(); null
+? &lt;file:c:/jabbertest/a&gt; delete(); null
+</pre>
+      </blockquote>
+      <hr>
+      <h1>&quot;&lt;file:...&gt;&quot; URI Expressions</h1>
+      <p>As explained in <a href="uri-exprs.html"><i>URI Expressions</i></a>, 
+        the value of a &quot;<code>&lt;file:...&gt;</code>&quot; URI expression 
+        is a <code>java.io.File</code> object. Such a file object doesn't necessarily 
+        represent a file that already exists on your file system. It might represent 
+        an existing directory, an existing &quot;normal&quot; file (a non-directory), 
+        or it might represent a file that doesn't yet exist -- a potential file 
+        or directory. You can test which as follows:</p>
+      <blockquote> 
         <pre>? def j1 := &lt;file:c:/jabbertest/jabberwocky.txt&gt;
 # value: &lt;file:c:/jabbertest/jabberwocky.txt&gt;
 
@@ -67,13 +90,19 @@
 ? j1 <b>isDirectory</b>()
 # value: false</pre>
       </blockquote>
-      <p>Not surprisingly, the jabberwocky.txt file we created earlier exists,
-        and is a normal file, and therefore is not a directory.
-      <blockquote>
+      <p>Not surprisingly, the jabberwocky.txt file we created earlier exists, 
+        and is a normal file, and therefore is not a directory. 
+      <blockquote> 
         <pre>? def j2 := &lt;c:/jabbertest/jabberwocky2.txt&gt;
-# value: &lt;file:c:/jabbertest/jabberwocky2.txt&gt;
-
-? j2 exists()
+# value: &lt;file:c:/jabbertest/jabberwocky2.txt&gt;</pre>
+      </blockquote>
+      The URI here shows an allowable shorthand. For the convenience of MSWindows 
+      users, if the URI begins with a single letter followed by a colon, then 
+      a preceding &quot;<code>file:</code>&quot; is assumed. (On MSWindows this 
+      single letter is known as the <i>drive letter</i>, and names approximately 
+      a mounted volume.) 
+      <blockquote> 
+        <pre>? j2 exists()
 # value: false
 
 ? j2 isNormal()
@@ -82,9 +111,9 @@
 ? j2 isDirectory()
 # value: false</pre>
       </blockquote>
-      <p>On the other hand, &quot;jabberwocky2.txt&quot; does not yet exist, and
+      <p>On the other hand, &quot;jabberwocky2.txt&quot; does not yet exist, and 
         is therefore neither normal nor a directory.</p>
-      <blockquote>
+      <blockquote> 
         <pre>? def desk := &lt;c:/windows/desktop&gt;
 # value: &lt;file:c:/windows/desktop/&gt;
 
@@ -97,17 +126,17 @@
 ? desk isDirectory()
 # value: true</pre>
       </blockquote>
-      <p>&quot;desk&quot; now represents our Windows Desktop which, as you can
+      <p>&quot;desk&quot; now represents our Windows Desktop which, as you can 
         see, is a directory.</p>
       <blockquote> 
         <pre>? desk <b>getCanonicalPath</b>()
 # value: &quot;C:/WINDOWS/Desktop/&quot;
 </pre>
       </blockquote>
-      <p>To aid portability, E enables (and encourages) you to deal with Files
-        using &quot;/&quot; as the path separator character. But you can use &quot;getCanonicalPath&quot;
-        when you want to see what the path-name of the file looks like to your
-        operating system.
+      <p>To aid portability, E enables (and encourages) you to deal with Files 
+        using &quot;/&quot; as the path separator character. But you can use &quot;getCanonicalPath&quot; 
+        when you want to see what the path-name of the file looks like to your 
+        operating system. 
       <blockquote> 
         <pre>? desk <b>getName</b>()
 # value: "desktop"
@@ -130,10 +159,10 @@
         <b>renameTo</b>(file) all behave just as in Java, and operate on both 
         normal files and directories. See the javadoc-umentation.</p>
       <h2><a name="ReadingText"></a>Reading Text</h2>
-      <p>As we saw in the Jabberwocky example, if you use a normal File as the
-        collection of a for loop, E assumes the file is a text file, and treats
+      <p>As we saw in the Jabberwocky example, if you use a normal File as the 
+        collection of a for loop, E assumes the file is a text file, and treats 
         it as a collection of lines.</p>
-      <blockquote>
+      <blockquote> 
         <pre>? var size := 0
 # value: 0
  
@@ -144,11 +173,11 @@
 ? size
 # value: 270</pre>
       </blockquote>
-      <p>To aid portability, each of these lines ends with a newline character,
-        '\n', independent of how newlines are actually represented on the current
-        platform. On Windows newlines are represented with a pair of characters,
-        so the above size is smaller than the Windows file size.
-      <blockquote>
+      <p>To aid portability, each of these lines ends with a newline character, 
+        '\n', independent of how newlines are actually represented on the current 
+        platform. On Windows newlines are represented with a pair of characters, 
+        so the above size is smaller than the Windows file size. 
+      <blockquote> 
         <pre>? &lt;c:/jabbertest/jabberwocky.txt&gt; <b></b>getText() size()
 # value: 270</pre>
       </blockquote>
@@ -156,11 +185,11 @@
         using &quot;<code>getText()</code>&quot;. As you might be able to guess 
         from the agreement on size, <code>getText()</code> also turns platform-specific 
         newlines into newline characters.</p>
-      <p>When you don't want to read the whole file at once, you instead open
+      <p>When you don't want to read the whole file at once, you instead open 
         a text reading stream on the File using &quot;textReader&quot;:</p>
       <blockquote> 
         <pre>? def reader := &lt;c:/jabbertest/jabberwocky.txt&gt; <b>textReader</b>()
-# value: &lt;BufferedReader&gt;
+# value: &lt;TextReader&gt;
  
 ? reader <b>readChar</b>()
 # value: '\''
@@ -174,30 +203,30 @@
 ? reader <b>readString</b>(1000) size()
 # value: 232</pre>
       </blockquote>
-      <p>&quot;readChar&quot; returns the next character. &quot;readLine&quot;
-        reads a line of text, but, following Java conventions, without the terminating
-        newline. &quot;readString(num)&quot; will read num characters, and return
-        them as a String. However, if there aren't num character left before the
-        end of file, it will return the rest of the characters and leave the stream
-        at end of file.
-      <blockquote>
+      <p>&quot;readChar&quot; returns the next character. &quot;readLine&quot; 
+        reads a line of text, but, following Java conventions, without the terminating 
+        newline. &quot;readString(num)&quot; will read num characters, and return 
+        them as a String. However, if there aren't num character left before the 
+        end of file, it will return the rest of the characters and leave the stream 
+        at end of file. 
+      <blockquote> 
         <pre>? reader readChar() == null
 # value: true</pre>
       </blockquote>
-      <p>When the stream is at end of file, the above read-requests all return
+      <p>When the stream is at end of file, the above read-requests all return 
         null.</p>
       <blockquote> 
         <pre>? reader <b>close</b>()
 ? reader readChar()
 # problem: &lt;IOException: Stream closed&gt;</pre>
       </blockquote>
-      <p>When you're done with a stream, you should always be sure to close it.
-        That's fine for interactive use, but how can you be sure your program
-        will close the stream when an I/O error might throw you out of your function
+      <p>When you're done with a stream, you should always be sure to close it. 
+        That's fine for interactive use, but how can you be sure your program 
+        will close the stream when an I/O error might throw you out of your function 
         before you get to your close message? By using try/finally:</p>
       <blockquote> 
         <pre>? def reader := &lt;c:/jabbertest/jabberwocky.txt&gt; textReader()
-# value: &lt;BufferedReader&gt;
+# value: &lt;TextReader&gt;
 
 ? var size := 0
 # value: 0
@@ -212,13 +241,13 @@
 &gt; }
 # value: 261</pre>
       </blockquote>
-      <p>This loop uses a reader to loop through the file one line at a time.
-        The &quot;finally&quot; clause will be sure we close the stream no matter
-        how we exit the try block. If, for example, &quot;reader readLine&quot;
-        throws an IOException (always a possibility), the stream will still be
+      <p>This loop uses a reader to loop through the file one line at a time. 
+        The &quot;finally&quot; clause will be sure we close the stream no matter 
+        how we exit the try block. If, for example, &quot;reader readLine&quot; 
+        throws an IOException (always a possibility), the stream will still be 
         closed.</p>
-      <p>Notice that the cumulative size is smaller than before. This is because
-        &quot;readLine&quot; produces lines <i>not</i> terminated by any form
+      <p>Notice that the cumulative size is smaller than before. This is because 
+        &quot;readLine&quot; produces lines <i>not</i> terminated by any form 
         of newline.</p>
       <blockquote> 
         <pre>? &lt;c:/jabbertest/jabberwocky2.txt&gt; exists()
@@ -228,22 +257,24 @@
 # problem: &lt;FileNotFoundException: c:\jabbertest\jabberwocky2.txt \
 #           (The system cannot find the file specified)&gt;</pre>
       </blockquote>
-      <p>Not surprisingly, you can't open a text Reader on a file that doesn't
-        exist. However...
+      <p>(Note that the above example doesn't yet pass as an Updoc test case due 
+        to the <i><a href="../tools/updoc.html#continuation-bug">line continuation 
+        bug</a></i>.) 
+      <p>Not surprisingly, you can't open a text Reader on a file that doesn't 
+        exist. However... 
       <h2><a name="WritingText"></a>Writing Text</h2>
-      <blockquote>
+      <blockquote> 
         <pre>? def writer := &lt;c:/jabbertest/jabberwocky2.txt&gt; <b>textWriter</b>()
 # value: &lt;TextWriter&gt;
  
 ? &lt;c:/jabbertest/jabberwocky2.txt&gt; exists()
 # value: true</pre>
       </blockquote>
-      <p>... you can open a TextWriter, which also causes the file to be created
-        if needed. You then fill the file with content by writing to the TextWriter,
-        and then closing it. For example, to copy the contents of
-&lt;c:/jabbertest/jabberwocky.txt&gt;
+      <p>... you can open a TextWriter, which also causes the file to be created 
+        if needed. You then fill the file with content by writing to the TextWriter, 
+        and then closing it. For example, to copy the contents of &lt;c:/jabbertest/jabberwocky.txt&gt; 
         into &lt;c:/jabbertest/jabberwock2.txt&gt;:</p>
-      <blockquote>
+      <blockquote> 
         <pre>? try {
 &gt;     for line in &lt;c:/jabbertest/jabberwocky.txt&gt; {
 &gt;         writer <b>print</b>(line)
@@ -252,7 +283,7 @@
 &gt;     writer close()
 &gt; }</pre>
       </blockquote>
-      <p>Once again, we use a try/finally expression to ensure that the Writer
+      <p>Once again, we use a try/finally expression to ensure that the Writer 
         gets closed no matter how we leave the expression.</p>
       <p>&quot;print(object)&quot; prints the stringified form of the object to 
         the Writer. The stringified form of a String is the String itself. The 
@@ -260,23 +291,23 @@
         &quot;. <font color="#ff0000">(*** No longer quite true. Need to explain 
         about the quoted form.)</font> For example, the stringified form of a 
         number is just its decimal representation:</p>
-      <blockquote>
+      <blockquote> 
         <pre>? 2 + 3
 # value: 5
 
 ? 2 / 3
 # value: 0.6666666666666666</pre>
       </blockquote>
-      <p>This is the form that would get written to a file if these values were
+      <p>This is the form that would get written to a file if these values were 
         used as the argument of a &quot;print&quot; message.</p>
-      <blockquote>
+      <blockquote> 
         <pre>? &lt;c:/jabbertest/jabberwocky2.txt&gt; getText() size()
 # value: 270</pre>
       </blockquote>
       <p>As we see from the size, our file-copy code copied the whole file.</p>
-      <p>We can turn the above pattern into a useful little function for copying
+      <p>We can turn the above pattern into a useful little function for copying 
         text files:</p>
-      <blockquote>
+      <blockquote> 
         <pre>? def textFileCopy(srcFile, destFile) {
 &gt;     def writer := destFile textWriter()
 &gt;     try {
@@ -289,28 +320,28 @@
 &gt; }
 # value: &lt;textFileCopy&gt;</pre>
       </blockquote>
-      <p>Using this function, we can copy files simply:
-      <blockquote>
+      <p>Using this function, we can copy files simply: 
+      <blockquote> 
         <pre>? textFileCopy(&lt;c:/jabbertest/jabberwocky.txt&gt;,
 &gt;              &lt;c:/jabbertest/jabberwocky2.txt&gt;)</pre>
       </blockquote>
-      <p>Your interactive command-line interpreter already has an TextWriter that's
-        always open, called &quot;stdout&quot;, that displays text on your command
+      <p>Your interactive command-line interpreter already has an TextWriter that's 
+        always open, called &quot;stdout&quot;, that displays text on your command 
         line interpreter window:</p>
-      <blockquote>
+      <blockquote> 
         <pre>? stdout
 # value: &lt;TextWriter&gt;
   
 ? stdout <b>println</b>(2/3)
 0.6666666666666666</pre>
       </blockquote>
-      <p>TextWriters also respond to a &quot;println&quot; message, which is just
-        like &quot;print&quot;, except that it also provides a newline on the
-        end. Similarly, there is also a &quot;lnPrint&quot; message that provides
-        a newline on the beginning. If we wanted to write a text-copy function
-        that worked on already open streams, rather than opening and closing them
+      <p>TextWriters also respond to a &quot;println&quot; message, which is just 
+        like &quot;print&quot;, except that it also provides a newline on the 
+        end. Similarly, there is also a &quot;lnPrint&quot; message that provides 
+        a newline on the beginning. If we wanted to write a text-copy function 
+        that worked on already open streams, rather than opening and closing them 
         ourselves, we might write:</p>
-      <blockquote>
+      <blockquote> 
         <pre>? def textStreamCopy(reader, writer) {
 &gt;     while ((def line := reader readLine()) != null) {
 &gt;         writer println(line)
@@ -319,7 +350,7 @@
 # value: &lt;textStreamCopy&gt;
 
 ? def reader := &lt;c:/jabbertest/jabberwocky.txt&gt; textReader()
-# value: &lt;BufferedReader&gt;
+# value: &lt;TextReader&gt;
 
 ? try {
 &gt;     textStreamCopy(reader, stdout)
@@ -337,14 +368,14 @@
 Beware the Jubjub bird and shun
 The frumious bandersnatch.&quot;</pre>
       </blockquote>
-      <p>We print to the writer using &quot;println&quot; above, since &quot;reader
+      <p>We print to the writer using &quot;println&quot; above, since &quot;reader 
         readLine&quot; returns a line without the terminal newline.</p>
       <p>If we replace the line containing &quot;stdout&quot; above with</p>
-      <blockquote>
+      <blockquote> 
         <pre>&gt;     textStreamCopy(reader, stdout <b>indent</b>(&quot;...&quot;))</pre>
       </blockquote>
       <p>and do the above sequence again, we get</p>
-      <blockquote>
+      <blockquote> 
         <pre>Twas Brillig and the Slithy Toves
 ...Did gyre and gimbal in the wabe
 ...All mimsy were the borogroves
@@ -357,10 +388,10 @@
 ...The frumious bandersnatch.&quot;
 ...</pre>
       </blockquote>
-      <p>When you send the &quot;indent(prefix)&quot; message to an TextWriter,
-        it returns a new TextWriter that writes to the same destination, but adding
-        the extra prefix after every newline.
-      <blockquote>
+      <p>When you send the &quot;indent(prefix)&quot; message to an TextWriter, 
+        it returns a new TextWriter that writes to the same destination, but adding 
+        the extra prefix after every newline. 
+      <blockquote> 
         <pre>? stdout indent(&quot;...&quot;) <b>lnPrint</b>(&lt;c:/jabbertest/jabberwocky.txt&gt; getText())
 
 ...Twas Brillig and the Slithy Toves
@@ -375,18 +406,18 @@
 ...The frumious bandersnatch.&quot;
 ...</pre>
       </blockquote>
-      <p>Finally, there are also global &quot;print&quot; and &quot;println&quot;
-        functions that send the corresponding message to stdout and also return
+      <p>Finally, there are also global &quot;print&quot; and &quot;println&quot; 
+        functions that send the corresponding message to stdout and also return 
         their argument.</p>
-      <blockquote>
+      <blockquote> 
         <pre>? <b>println</b>(2/3)
 0.6666666666666666
 # value: 0.6666666666666666</pre>
       </blockquote>
       <h2><a name="Directories"></a>Directories</h2>
-      <p>As we saw in the original Jabberwocky example, if you use a for-loop
-        to iterate a File object that is a directory, the loop variable gets bound
-        to each File (normal file or directory) in this directory. With this piece
+      <p>As we saw in the original Jabberwocky example, if you use a for-loop 
+        to iterate a File object that is a directory, the loop variable gets bound 
+        to each File (normal file or directory) in this directory. With this piece 
         of information, we can now write our first non-trivial useful program:</p>
       <blockquote> 
         <pre>? def writeDirMap(filedir, writer) {
@@ -406,21 +437,21 @@
 &gt; }
 # value: &lt;writeDirMap&gt;</pre>
       </blockquote>
-      <p>&quot;writeDirMap&quot; is a recursive function only meant to be called
-        from &quot;dirMapper&quot;. &quot;filedir&quot; is a File object that
-        may represent either a normal file or a directory. writeMapDir uses &quot;lnPrint&quot;
-        to print the local-name part of filedir onto writer, preceded by a newline.
-        If filedir is a normal file, we're done. If it's a directory, then we
-        suffix the name with a &quot;/&quot;, so someone looking at the output
-        can tell it's a directory, and then call ourselves recursively with each
-        File (normal file or directory) in this directory. In this recursive call,
-        we pass a new TextWriter, &quot;nested&quot; which is just like &quot;writer&quot;,
-        except that it has an extra prefix string consisting of a number of spaces
-        equal to our local name, followed by a &quot;/&quot;. As you'll see, this
-        results in outline-style output in which it's easy to figure out what's
-        under what. This prefix string gets output after the newline written by
-        the call to &quot;lnPrint&quot; in the nested call to &quot;writeDirMap&quot;.
-      <blockquote>
+      <p>&quot;writeDirMap&quot; is a recursive function only meant to be called 
+        from &quot;dirMapper&quot;. &quot;filedir&quot; is a File object that 
+        may represent either a normal file or a directory. writeMapDir uses &quot;lnPrint&quot; 
+        to print the local-name part of filedir onto writer, preceded by a newline. 
+        If filedir is a normal file, we're done. If it's a directory, then we 
+        suffix the name with a &quot;/&quot;, so someone looking at the output 
+        can tell it's a directory, and then call ourselves recursively with each 
+        File (normal file or directory) in this directory. In this recursive call, 
+        we pass a new TextWriter, &quot;nested&quot; which is just like &quot;writer&quot;, 
+        except that it has an extra prefix string consisting of a number of spaces 
+        equal to our local name, followed by a &quot;/&quot;. As you'll see, this 
+        results in outline-style output in which it's easy to figure out what's 
+        under what. This prefix string gets output after the newline written by 
+        the call to &quot;lnPrint&quot; in the nested call to &quot;writeDirMap&quot;. 
+      <blockquote> 
         <pre>? def dirMapper(filedir, destFile) {
 &gt;     def writer := destFile textWriter()
 &gt;     try {
@@ -432,17 +463,17 @@
 &gt; }
 # value: &lt;dirMapper&gt;</pre>
       </blockquote>
-      <p>Just wraps the top-level call to &quot;writeDirMap&quot; with the opening
-        of a Writer onto destFile, and the insertion of the last newline. We can
-        call &quot;dirMapper&quot; to get a useful textual roadmap to a portion
-        of our directory hierarchy. For example, when I map out my Windows Start
-        Menu:
-      <blockquote>
+      <p>Just wraps the top-level call to &quot;writeDirMap&quot; with the opening 
+        of a Writer onto destFile, and the insertion of the last newline. We can 
+        call &quot;dirMapper&quot; to get a useful textual roadmap to a portion 
+        of our directory hierarchy. For example, when I map out my Windows Start 
+        Menu: 
+      <blockquote> 
         <pre>? dirMapper(&lt;file: &quot;/Windows/Start Menu&quot;&gt;,
 &gt;           &lt;file:/startMenuMap.txt&gt;)</pre>
       </blockquote>
       <pre>The beginning of my resulting file looks like</pre>
-      <blockquote>
+      <blockquote> 
         <pre>Start Menu/
           /ebash.pif
           /Programs/
@@ -456,62 +487,63 @@
           /        /Internet Mail.lnk
           /        /Microsoft NetMeeting.lnk</pre>
       </blockquote>
-      <p>Yours, of course, will differ in the details. If you map your
-&lt;file:/&gt;
-        instead, go out and get a cup of java. It'll take a while. (My little
-        laptop has over 53,000 files and directories on it, each of which produces
+      <p>Yours, of course, will differ in the details. If you map your &lt;file:/&gt; 
+        instead, go out and get a cup of java. It'll take a while. (My little 
+        laptop has over 53,000 files and directories on it, each of which produces 
         a line in the map file.)</p>
-      <p>We've seen how to create new normal files -- by opening up a textWriter.
+      <p>We've seen how to create new normal files -- by opening up a textWriter. 
         How do we create directories? With &quot;mkdir&quot; or &quot;mkdirs&quot;:</p>
-      <blockquote>
-        <pre>? def abc := &lt;c:/a/b/c&gt;
-# value: &lt;file:c:/a/b/c&gt;
+      <blockquote> 
+        <pre>? def abc := &lt;c:/jabbertest/a/b/c&gt;
+# value: &lt;file:c:/jabbertest/a/b/c&gt;
 
 ? abc exists()
 # value: false</pre>
       </blockquote>
-      <p>At this point, &lt;file:/a/b/c&gt; is neither a directory nor a normal file.
-      <blockquote>
+      <p>At this point, &lt;file:/jabbertest/a/b/c&gt; is neither a directory 
+        nor a normal file. 
+      <blockquote> 
         <pre>? abc <b>mkdirs</b>()
 # value: true</pre>
       </blockquote>
-      <p>If &lt;file:/a/b&gt; already existed, and was a directory, then &quot;<code>mkdir</code>&quot; 
-        would have been adequate. However, if &lt;file:/a/b&gt; didn't exist, 
-        &quot;mkdir&quot; would have failed. &quot;<code>mkdirs</code>&quot;, 
-        on the other hand, creates the parent directories as necessary in order 
-        to create &lt;file:/a/b/c&gt; as a directory. 
-      <blockquote>
+      <p>If <code>&lt;file:/jabbertest/a/b&gt;</code> already existed, and was 
+        a directory, then &quot;<code>mkdir</code>&quot; would have been adequate. 
+        However, if <code>&lt;file:/jabbertest/a/b&gt;</code> didn't exist, &quot;<code>mkdir</code>&quot; 
+        would have failed. &quot;<code>mkdirs</code>&quot;, on the other hand, 
+        creates the parent directories as necessary in order to create <code>&lt;file:/jabbertest/a/b/c&gt;</code> 
+        as a directory. 
+      <blockquote> 
         <pre>? abc exists()
 # value: true</pre>
         <pre>? abc isDirectory()
 # value: true
  
 ? abc
-# value: &lt;file:c:/a/b/c/&gt;</pre>
+# value: &lt;file:c:/jabbertest/a/b/c/&gt;</pre>
       </blockquote>
-      <p>abc now prints out with a terminal slash to indicate that it represents
+      <p>abc now prints out with a terminal slash to indicate that it represents 
         a directory.</p>
       <blockquote> 
-        <pre>? def ab := &lt;c:/a/b&gt;
-# value: &lt;file:c:/a/b/&gt;
+        <pre>? def ab := &lt;c:/jabbertest/a/b&gt;
+# value: &lt;file:c:/jabbertest/a/b/&gt;
 
 ? ab<b>[</b>&quot;c&quot;<b>]</b>
-# value: &lt;file:c:/a/b/c/&gt;
+# value: &lt;file:c:/jabbertest/a/b/c/&gt;
 
 ? ab[&quot;..&quot;]
 # problem: &lt;SecurityException: &quot;..&quot; not allowed: ..&gt;</pre>
       </blockquote>
-      <p>Directories are collections, mapping from local file names to the contained
-        Files (normal files or directories). We've already seen that directories
-        support the for-loop the way would expect such a collection to. In addition,
-        we can use the square-bracket indexing operator to get a File of a given
-        name within a directory. However, we can only descend the directory hierarchy.
-        For reasons explained in <i>Capability Programming Patterns</i> E disallows
-        the use of &quot;..&quot; to navigate upwards.
+      <p>Directories are collections, mapping from local file names to the contained 
+        Files (normal files or directories). We've already seen that directories 
+        support the for-loop the way would expect such a collection to. In addition, 
+        we can use the square-bracket indexing operator to get a File of a given 
+        name within a directory. However, we can only descend the directory hierarchy. 
+        For reasons explained in <i>Capability Programming Patterns</i> E disallows 
+        the use of &quot;..&quot; to navigate upwards. 
       <h2><a name="URLs"></a>URLs</h2>
       <p><font color="#ff0000">*** to be written</font></p>
-      <p>
-      <P ALIGN="left">&nbsp;
+      <p> 
+      <P ALIGN="left">&nbsp; 
       <!-- #EndEditable --></TD>
     <TD WIDTH="10%">&nbsp;</TD>
   </TR>



1.24      +2 -2      e/src/esrc/scripts/eBrowser.e

Index: eBrowser.e
===================================================================
RCS file: /cvs/e/src/esrc/scripts/eBrowser.e,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- eBrowser.e	2001/07/14 12:57:20	1.23
+++ eBrowser.e	2001/07/16 10:42:48	1.24
@@ -432,13 +432,13 @@
         def runner() {
             E call(target, operation, [])
         }
-        uiTools newToolButton(uri, tipText ,runner)
+        uiTools newToolButton(uri, tipText, runner)
     }
     def addMenuItem(menu, name, operation, target) :any {
         def runner() {
             E call(target, operation, [])
         }
-        uiTools addMenuItem(menu, name,runner)
+        uiTools addMenuItem(menu, name, runner)
     }
     def icons__uriGetter {
         to get(name) :any {



1.28      +7 -0      e/src/jsrc/org/erights/e/elib/base/TextWriter.java

Index: TextWriter.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/base/TextWriter.java,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- TextWriter.java	2001/04/08 21:15:12	1.27
+++ TextWriter.java	2001/07/16 10:42:48	1.28
@@ -325,4 +325,11 @@
             off = nl + 1;
         }
     }
+    
+    /**
+     * A TextWriter prints itself on a TextWriter as &lt;TextWriter&gt;.
+     */
+    public void printOn(TextWriter out) throws IOException {
+        out.print("<TextWriter>");
+    }
 }



1.12      +6 -2      e/src/jsrc/org/erights/e/elib/tables/Twine.java

Index: Twine.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/tables/Twine.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- Twine.java	2001/07/14 12:57:24	1.11
+++ Twine.java	2001/07/16 10:42:48	1.12
@@ -217,13 +217,16 @@
     
     /**
      * Return a new Twine that represents a concatenation of the parts of 
-     * these this and other.  The last part of this may be merged with the 
-     * first part of other.
+     * this and other.  <p>
+     *
+     * The last part of this may be merged with the first part of other.
      */
     public ConstList add(Object other) {
         Twine otherTwine;
         if (other instanceof Twine) {
             otherTwine = (Twine)other;
+        } else if (other instanceof Character) {
+            otherTwine = Twine.fromString(other.toString());
         } else {
             otherTwine = Twine.fromString(E.toString(other));
         }
@@ -291,6 +294,7 @@
         for (int p2 = 0; p2 < len; p2++) {
             char c = charAt(p2);
             String newStr = null;
+            //XXX Redundant with CharacterSugar.escaped(c).
             switch(c) {
                 case '\b': { newStr = "\\b";        break; }
                 case '\t': { newStr = "\\t";        break; }



1.13      +9 -0      e/src/jsrc/org/erights/e/meta/java/io/BufferedReaderSugar.java

Index: BufferedReaderSugar.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/meta/java/io/BufferedReaderSugar.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- BufferedReaderSugar.java	2001/03/20 03:18:25	1.12
+++ BufferedReaderSugar.java	2001/07/16 10:42:48	1.13
@@ -22,6 +22,7 @@
 import java.io.BufferedReader;
 import java.io.IOException;
 import org.erights.e.elib.base.SourceSpan;
+import org.erights.e.elib.base.TextWriter;
 import org.erights.e.elib.tables.AssocFunc;
 import org.erights.e.elib.tables.FlexList;
 import org.erights.e.elib.tables.Twine;
@@ -115,5 +116,13 @@
         } finally {
             self.close();
         }
+    }
+    
+    /**
+     * A BufferedReader prints as &lt;TextReader&gt;
+     */
+    static public void printOn(BufferedReader self, TextWriter out) 
+    throws IOException {
+        out.print("<TextReader>");
     }
 }



1.11      +50 -0     e/src/jsrc/org/erights/e/meta/java/lang/CharacterSugar.java

Index: CharacterSugar.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/meta/java/lang/CharacterSugar.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- CharacterSugar.java	2001/03/28 22:30:50	1.10
+++ CharacterSugar.java	2001/07/16 10:42:48	1.11
@@ -18,6 +18,10 @@
 
 Contributor(s): ______________________________________.
 */
+
+import java.io.IOException;
+import org.erights.e.elib.base.TextWriter;
+
 /**
  * A sweetener defining extra messages that may be e-sent to characters.
  *
@@ -106,5 +110,51 @@
      */
     static public char max(char self, char other) {
         return (char)Math.max((int)self, (int)other);
+    }
+
+    /**
+     * Unlike Java's Writer.print(char), E's chars print by printing
+     * their quoted form.  <p>
+     *
+     * If you want to contribute the character itself to a TextWriter,
+     * print it by doing <code>out&nbsp;print(""+c)</code>
+     */
+    static public void printOn(char self, TextWriter out)
+    throws IOException {
+        out.print("'", escaped(self), "'");
+    }
+
+    /**
+     * Just the part of a character's quoted form that encodes the
+     * character. <p>
+     *
+     * In other words, everything except the enclosing quote signs.
+     * This is equally useful for composing a quoted character or a
+     * quoted string.
+     */
+    static public String escaped(char self) {
+        StringBuffer buf = new StringBuffer();
+        //XXX Redundant with the inner loop of Twine.quote()
+        switch(self) {
+            case '\b': { buf.append("\\b");        break; }
+            case '\t': { buf.append("\\t");        break; }
+            case '\n': { buf.append("\\n\\\n");    break; }
+            case '\f': { buf.append("\\f");        break; }
+            case '\r': { buf.append("\\r");        break; }
+            case '\"': { buf.append("\\\"");       break; }
+            case '\'': { buf.append("\\\'");       break; }
+            case '\\': { buf.append("\\\\");       break; }
+            default: {
+                if (self < 32 && self > 255) {
+                    String num = "0000" + Integer.toHexString(self);
+                    int len = num.length();
+                    num = num.substring(len - 4, len);
+                    buf.append("\\u" + num);
+                } else {
+                    buf.append(self);
+                }
+            }
+        }
+        return buf.toString();
     }
 }