on the Curl Web Content Markup Language

on the Curl Web Content Markup and Programming Language from www.curl.com and www.curlap.com

Sunday, June 26, 2011

Curl page from Ruby CGI

Over at Aule-Browser I have Ruby CGI generating a page with the following:

This web page is Curl web content (no HTML5 or CSS or JavaScript.)


For information about Curl web markup, programming in Curl and Curl open-source: www.Curl.com


Here is the code and markup used:
{curl 7.0 applet}
{curl-file-attributes character-encoding = "utf8"}
{document-style DefaultDocument}
{set-document-properties background={Background.from-string "linen"}, margin=0.75in}
{text This web page is {bold Curl web content} (no HTML5 or CSS or JavaScript.)}
{paragraph

  For information about Curl web markup, programming in Curl and Curl open-source:
  {link target="_blank", href={url "http://www.curl.com"}, www.Curl.com}
}
 \u0000  {br}  || but note that in a Ruby heredoc I must escape my unicode escape
{paragraph Here is the code and markup used:}
{pre
{curl 7.0 applet} ... etc etc ...  }
                                                                                               


but what that does not show is the simplicity of the CGI:
#!/usr/bin/ruby
# curl_01.cgi

puts "Content-Type: text/vnd.curl"
puts

puts "{curl 7.0 applet}",
<<eos
{curl-file-attributes character-encoding = "utf8"}
{applet
    {compiler-directives careful? = true}
}
{document-style DefaultDocument}

{set-document-properties background={Background.from-string "linen"}, margin=0.75in}

{text This web page is {bold Curl web content} (no HTML5 or CSS or JavaScript.)}

{paragraph

  For information about Curl web markup, programming in Curl and Curl open-source:
  {link target="_blank", href={url "http://www.curl.com"}, www.Curl.com}
}
 \\u0000  {br}  || but note that in a Ruby heredoc I must escape my unicode escape

{paragraph
  Here is the code and markup used:}

{pre |"
{curl 7.0 applet}
etc etc
}
eos

Tuesday, June 21, 2011

Curl top-level code and the doc's live code example macro

Curl neophytes are sometimes confused by the use of {value } macros in the examples in the Curl doc's.

I have placed an alternative example style below.

Curl at the top-level is rather like minimalist HTML: if you place a value in a page then the value gets displayed.

But usually a Curl applet is not a {value } expression at the top-level in a .curl file and this adds to unfamiliarity.

The example does include one use of a {value } expression - the macro is used in a {paragraph } text‑proc.

{value } is used in the live code doc's because we are passing our example value into a macro such as {example }.

In my variant example, a {do } expression is used with a top-level global public var instead. The macro {value } is used in {paragraph } as it might be used in a typical applet.

My revision:

The Curl docs on String Files for the scheme curl://some‑text‑resource has a live code {example } using {string-url }

Here is a variant of that example which uses the Curl macro {with-open-streams   do }

The example is not wrapped in a {value } macro as neophytes find this confusing and it is not required for this example at the 'price' of a public global var in the example code.  The text‑proc paragraph preserves our whitespace for our lines as read.

|| Note: we do not need to {set } myinput in this variant of the example.

{def result:StringBuf = {StringBuf}}
{do
    || create a string to be read as a stream
    def mystring:String = "This is some string data I want to read as a stream \nin order to test a macro"

    || Construct a Url under the curl://string directory, using the
    || string we want to read as the filename.
    def myurl:Url = {string-url mystring}

    || Now, read from it as if it were a normal file.
    let myinput:#TextInputStream

    {with-open-streams myinput = {read-open myurl} do

        {until myinput.end-of-stream? do
            {result.concat {myinput.read-one-line}}}

    }
}  

{paragraph text-preserve-whitespace?=true, {value result}}

Wednesday, June 8, 2011

OpenCurl Curl

While I see the expression OpenCurl only twice at http://www.curl.com/, I am seeing it in the readme.txt files of Curl projects at sourceforge.net and have noted the variant OPENCURL at code.google.com/p/zuzu-curl

The failure to protect Curl as a trademark of the M.I.T. spin-off corp has had the sad consequence of confusion with cURL.

The latest Curl library in beta as sourceforge bears the identifier COM.CURL.EXT and not OPENCURL.EXT.

Perhaps when that library goes to a 1.x release we will be closer to Curl 8.0 aka curl9.

Thursday, April 14, 2011

def for constants and the new look of Curl code

Here is what the Curl docs say about the def macro:

def  declares
one or more new constants in the current block of code whose type may be inferred from the type of the value expression used to initialize it. The new constant is implicitly declared to be constant and may not be set to a different value after it has been initialized, but if the constant is a class instance its internal state may change.
This changes the face of curl coding as can be seen in the following snippet from a server HTTP procedure which you can find in the Curl extended examples.  The code is found within a {for } loop expression:

            def (num-bytes-decoded, chars) =
                {decode-characters
                    request.underlying-FastArray,
                    CharEncoding.ascii,
                    in-end = i + 2
                }
            || Now break apart the first line, and make a string of the headers.
            def end-of-line = {chars.find '\n'}
            {if end-of-line >= 0 then
                def first-line = {{chars.substr 0, end-of-line}.trim-clone}
                def command-pieces = {first-line.split split-chars = ' '}

This is not top-level code but code in a procedure within a class so  def   is used without braces.  The docs suggest the use of curly braces around a {def } expression when it is class-level or top-level so as to be distinct in appearance from local declarations.  The code is easy to read, there are few type declarations and any later destructive assignment is precluded.

Note that in the case of
   def (num-bytes-decoded, chars) =
the procedure  {decode-characters } itself returns
   (num-bytes-decoded:int, chars:String)
but such an expression might have returned more than two values with the surplus ignored by the def macro in its assignments.

The def  of an object reference to an instance of a class can preclude bugs and undesired ad hoc "bug fixes" and keep code readable as well as facilitate testing.

implicit primitive

An implicit constructor or factory can convert its single argument to a chosen type.

A class may be declared with more than one as implicit  and they will be searched in their declaration order for the first one which can be applied to the argument.

There are a few restrictions but they are not too subtle and they are detailed in the docs.

The important reminder from the docs might be this:
The choice of which implicit constructor or factory to call depends on the runtime type of the value [of the argument passed] (my emphasis and parenthetical addition)
An interesting example can be found by looking into the Curl constants named curl-version and curl-version-number.  The latter is an instance of a VersionNumber.

The implicit factory for VersionNumber is documented as

  public implicit
   {VersionNumber.from-string
     string:StringInterface
   }:VersionNumber

The Curl docs provide a live-code working example.  Here is my code from my simplified version of the example:

  {define-proc {make-version-table  ...:VersionNumber}:Table

and here is how to execute the procedure:

  {make-version-table "7.0.1", "7.0.3+"}

Looking at the last the two REST arguments you can see how smart this is.

The code in the Curl example uses a loop:

  {for version-num key i in ... do

  }

and in the loop that local var version-num is sent a VersionNumber clone method named

  n-clone

as in

  { version.n-clone n = j }     ||  j is a loop counter in my simplified version

to clone selected portions of the version number object.

All we have are strings but the code also includes no asa operator doing any type casts.

NOTE:  (a quote from the Curl docs)
You can also use asa to convert a value to a class type, providing there is a corresponding implicit constructor or factory in the class.

Wednesday, April 6, 2011

Rilke links in Curl

I added a simple web page with links to Rilke's Letters to a Young Poet.  Those pages are themselves in German, so I didn't anticipate any problem.  But when I did a simple edit to the Curl page in a cpanel text editor on my linux host, things began to go wrong.  All that I needed were the characters ä and å in the Windows-1252 encoding. I had chosen this character encodiing to investigate a quirk in the Opera browser.  But how to get the characters into the cpanel editor?

The Windows clipboard kept being "smart" and forcing the characters into 16-bit Unicode (the cahracters above were added using HTML entities - not an option in the source of the Curl text file.

Then a solution dawned on me: don't use an editor. Use the Windows command line! ALT-0228 and ALT-0229 on a cmd command line, mark, copy, paste into the web page for the cpanel editor (with the Curl file carefully re-loaded by the editor in Windows-1252) and all displayed correctly when the applet loaded.

The HTML file in which the Curl is an embedded Object is set to "windows-1252" and the Curl source file is set with a document character encoding on "win32:1252".

Tuesday, April 5, 2011

Curl character encodings

I have added a post above displaying the CharEncoding which Curl 7.0 offers on my Windows installation.

The two lists there cover more than 100 character encodings: both are from the procedure {get‑all‑character‑encodings} (note the use of & # 8209 ; to get that procedure name to appear here with non-breaking hyphens.)

The reason for using them is that Curl offers a CharEncoding class feature to obtain an instance by name - but the docs had no complete list of names, no doubt because the HostEncoding instances will vary by platform and current installation.

One dump is from a breakpoint in the debugger and one is console output from a loop over the {Array‑of CharEncoding} which is returned by the proc.

The types in that container include:

NoneCharEncoding
ShiftJISCharEncoding
EUCJPCharEncoding
UTF8CharEncoding
UTF16CharEncoding
UTF16UnknownEndianCharEncoding
SingleByteCharEncoding
MappedSingleByteCharEncoding
HostEncoding

with most being in the last.  The first is a system default for no encoding specified.

I happened to note that the Curl mother site www.curlap.com pages are encoded in Shift‑JIS.

A few days ago I noticed that some Classical Greek in UNICODE (UTF‑16) displays correctly in the Curl 7.0 IDE but not in any of my Windows web browsers.  I have not yet tested a Curl desktop Dcurl application to see if the UTF‑16 presents correctly in an RIA test.

By way of contrast, the current Pharo Smaltalk environment offers 14 encodings for Workspace contents. EncodedCharSet in Pharo currently has subclasses for GB2312, JISX0208, KSX1001, Latin1 and Unicode.