summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--data/keywords.txt2
-rw-r--r--doc/lib.txt2
-rw-r--r--koch.nim4
-rw-r--r--lib/pure/htmlparser.nim32
-rw-r--r--lib/pure/os.nim10
-rw-r--r--lib/pure/unicode.nim4
-rw-r--r--lib/pure/xmldom.nim16
-rw-r--r--lib/pure/xmldomparser.nim105
-rw-r--r--lib/pure/xmlparser.nim (renamed from lib/pure/xmltreeparser.nim)44
-rw-r--r--lib/pure/xmltree.nim24
-rw-r--r--rod/scanner.nim9
-rw-r--r--rod/wordrecg.nim6
-rw-r--r--tests/wildhtml.html23
-rw-r--r--tools/niminst.nim5
-rw-r--r--tools/nimweb.nim2
-rw-r--r--tools/trimcc.nim2
-rw-r--r--web/news.txt9
-rw-r--r--web/nimrod.ini1
18 files changed, 226 insertions, 74 deletions
diff --git a/data/keywords.txt b/data/keywords.txt
index 3cf9790ef..a6d96834a 100644
--- a/data/keywords.txt
+++ b/data/keywords.txt
@@ -5,7 +5,7 @@ discard distinct div
 elif else end enum except
 finally for from generic
 if implies import in include is isnot iterator
-lambda
+lambda let
 macro method mod
 nil not notin
 object of or out
diff --git a/doc/lib.txt b/doc/lib.txt
index 609889607..b94ac987e 100644
--- a/doc/lib.txt
+++ b/doc/lib.txt
@@ -177,7 +177,7 @@ XML Processing
 * `xmltree <xmltree.html>`_
   A simple XML tree. More efficient and simpler than the DOM.
 
-* `xmltreeparser <xmltreeparser.html>`_ 
+* `xmlparser <xmlparser.html>`_ 
   This module parses an XML document and creates its XML tree representation.
   
 * `htmlparser <htmlparser.html>`_ 
diff --git a/koch.nim b/koch.nim
index e5d963b1e..bf07f3ba9 100644
--- a/koch.nim
+++ b/koch.nim
@@ -108,13 +108,13 @@ proc safeRemove(filename: string) =
 proc bootIteration(args: string): bool = 
   var nimrod1 = "rod" / "nimrod1".exe
   safeRemove(nimrod1)
-  moveFile(nimrod1, "rod" / "nimrod".exe)
+  moveFile(dest=nimrod1, source="rod" / "nimrod".exe)
   exec "rod" / "nimrod1 cc $# $# rod/nimrod.nim" % [bootOptions, args]
   # Nimrod does not produce an executable again if nothing changed. That's ok:
   result = sameFileContent("rod" / "nimrod".exe, nimrod1)
   safeRemove("bin" / "nimrod".exe)
   var dest = "bin" / "nimrod".exe
-  copyFile(dest, "rod" / "nimrod".exe)
+  copyFile(dest=dest, source="rod" / "nimrod".exe)
   inclFilePermissions(dest, {fpUserExec})
   safeRemove(nimrod1)
   if result: echo "executables are equal: SUCCESS!"
diff --git a/lib/pure/htmlparser.nim b/lib/pure/htmlparser.nim
index 982fdd088..278bf9b90 100644
--- a/lib/pure/htmlparser.nim
+++ b/lib/pure/htmlparser.nim
@@ -265,7 +265,7 @@ proc addNode(father, son: PXmlNode) =
 proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode
 
 proc expected(x: var TXmlParser, n: PXmlNode): string =
-  result = errorMsg(x, "</" & n.tag & "$1> expected")
+  result = errorMsg(x, "</" & n.tag & "> expected")
 
 proc untilElementEnd(x: var TXmlParser, result: PXmlNode, 
                      errors: var seq[string]) =
@@ -378,17 +378,19 @@ proc parseHtml*(s: PStream): PXmlNode =
   var errors: seq[string] = @[]
   result = parseHtml(s, "unknown_html_doc", errors)
 
-proc loadHtml*(path: string, reportErrors = false): PXmlNode = 
+proc loadHtml*(path: string, errors: var seq[string]): PXmlNode = 
   ## Loads and parses HTML from file specified by ``path``, and returns 
-  ## a ``PXmlNode``. If `reportErrors` is true, the parsing errors are
-  ## ``echo``ed, otherwise they are ignored.
+  ## a ``PXmlNode``.  Every occured parsing error is added to
+  ## the `errors` sequence.
   var s = newFileStream(path, fmRead)
   if s == nil: raise newException(EIO, "Unable to read file: " & path)
-  
-  var errors: seq[string] = @[]
   result = parseHtml(s, path, errors)
-  if reportErrors: 
-    for msg in items(errors): echo(msg)
+
+proc loadHtml*(path: string): PXmlNode = 
+  ## Loads and parses HTML from file specified by ``path``, and returns 
+  ## a ``PXmlNode``. All parsing errors are ignored.
+  var errors: seq[string] = @[]  
+  result = loadHtml(path, errors)
 
 when true:
   nil
@@ -402,4 +404,18 @@ else:
     if n == nil or n.htmlTag != tagHtml: 
       errors.add("<html> tag expected")
     checkHtmlAux(n, errors)
+  
+when isMainModule:
+  import os
+
+  var errors: seq[string] = @[]  
+  var x = loadHtml(paramStr(1), errors)
+  for e in items(errors): echo e
+  
+  var f: TFile
+  if open(f, "test.txt", fmWrite):
+    f.write($x)
+    f.close()
+  else:
+    quit("cannot write test.txt")
   
\ No newline at end of file
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index ef526993a..4bb25098d 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nimrod's Runtime Library
-#        (c) Copyright 2009 Andreas Rumpf
+#        (c) Copyright 2010 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -619,9 +619,11 @@ proc sameFileContent*(path1, path2: string): bool =
   close(a)
   close(b)
 
-proc copyFile*(dest, source: string) =
+proc copyFile*(dest, source: string) {.deprecated.} =
   ## Copies a file from `source` to `dest`. If this fails,
   ## `EOS` is raised.
+  ## **Deprecated since version 0.8.8**: Use this proc with named arguments
+  ## only, because the order will change!
   when defined(Windows):
     if CopyFileA(source, dest, 0'i32) == 0'i32: OSError()
   else:
@@ -647,8 +649,10 @@ proc copyFile*(dest, source: string) =
     close(s)
     close(d)
 
-proc moveFile*(dest, source: string) =
+proc moveFile*(dest, source: string) {.deprecated.} =
   ## Moves a file from `source` to `dest`. If this fails, `EOS` is raised.
+  ## **Deprecated since version 0.8.8**: Use this proc with named arguments
+  ## only, because the order will change!
   if crename(source, dest) != 0'i32: OSError()
 
 proc removeFile*(file: string) =
diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim
index bebbe56c5..099509afe 100644
--- a/lib/pure/unicode.nim
+++ b/lib/pure/unicode.nim
@@ -83,8 +83,8 @@ proc toUTF8*(c: TRune): string =
     result[0] = chr(i)
   elif i <=% 0x07FF:
     result = newString(2)
-    result[0] = chr(i shr 6 or 0b110_0000)
-    result[1] = chr(i and ones(6) or 0b10_000000)
+    result[0] = chr((i shr 6) or 0b110_00000)
+    result[1] = chr((i and ones(6)) or 0b10_000000)
   elif i <=% 0xFFFF:
     result = newString(3)
     result[0] = chr(i shr 12 or 0b1110_0000)
diff --git a/lib/pure/xmldom.nim b/lib/pure/xmldom.nim
index 76c666de0..babf60108 100644
--- a/lib/pure/xmldom.nim
+++ b/lib/pure/xmldom.nim
@@ -227,7 +227,7 @@ proc createAttributeNS*(doc: PDocument, namespaceURI: string, qualifiedName: str
     raise newException(EInvalidCharacterErr, "Invalid character")
   # Exceptions
   if qualifiedName.contains(':'):
-    if namespaceURI == nil or namespaceURI == "":
+    if namespaceURI == nil:
       raise newException(ENamespaceErr, "When qualifiedName contains a prefix namespaceURI cannot be nil")
     elif qualifiedName.split(':')[0].toLower() == "xml" and namespaceURI != "http://www.w3.org/XML/1998/namespace":
       raise newException(ENamespaceErr, 
@@ -303,7 +303,7 @@ proc createElement*(doc: PDocument, tagName: string): PElement =
 proc createElementNS*(doc: PDocument, namespaceURI: string, qualifiedName: string): PElement =
   ## Creates an element of the given qualified name and namespace URI.
   if qualifiedName.contains(':'):
-    if namespaceURI == nil or namespaceURI == "":
+    if namespaceURI == nil:
       raise newException(ENamespaceErr, "When qualifiedName contains a prefix namespaceURI cannot be nil")
     elif qualifiedName.split(':')[0].toLower() == "xml" and namespaceURI != "http://www.w3.org/XML/1998/namespace":
       raise newException(ENamespaceErr, 
@@ -464,8 +464,11 @@ proc localName*(n: PNode): string =
 
 proc namespaceURI*(n: PNode): string =
   ## Returns this nodes namespace URI
-
+  
   return n.FNamespaceURI
+  
+proc `namespaceURI=`*(n: PNode, value: string) = 
+  n.FNamespaceURI = value
 
 proc nextSibling*(n: PNode): PNode =
   ## Returns the next sibling of this node
@@ -507,7 +510,7 @@ proc previousSibling*(n: PNode): PNode =
       return n.FParentNode.childNodes[i - 1]
   return nil
   
-proc `prefix=`*(n: var PNode, value: string) =
+proc `prefix=`*(n: PNode, value: string) =
   ## Modifies the prefix of this node
 
   # Setter
@@ -530,11 +533,10 @@ proc `prefix=`*(n: var PNode, value: string) =
   if n.nodeType == ElementNode:
     var el: PElement = PElement(n)
     el.FTagName = value & ":" & n.FLocalName
-    n = PNode(el)
+
   elif n.nodeType == AttributeNode:
     var attr: PAttr = PAttr(n)
     attr.FName = value & ":" & n.FLocalName
-    n = PNode(attr)
 
 # Procedures
 proc appendChild*(n: PNode, newChild: PNode) =
@@ -1078,4 +1080,4 @@ proc nodeToXml(n: PNode, indent: int = 0): string =
 proc `$`*(doc: PDocument): string =
   ## Converts a PDocument object into a string representation of it's XML
   result = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
-  result.add(nodeToXml(doc.documentElement))
+  result.add(nodeToXml(doc.documentElement))
\ No newline at end of file
diff --git a/lib/pure/xmldomparser.nim b/lib/pure/xmldomparser.nim
index b73baf1ff..f338ca2e5 100644
--- a/lib/pure/xmldomparser.nim
+++ b/lib/pure/xmldomparser.nim
@@ -14,9 +14,34 @@ import xmldom, os, streams, parsexml, strutils
 #XMLDom's Parser - Turns XML into a Document
 
 type
-  #Parsing errors
+  # Parsing errors
   EMismatchedTag* = object of E_Base ## Raised when a tag is not properly closed
   EParserError* = object of E_Base ## Raised when an unexpected XML Parser event occurs
+
+  # For namespaces
+  xmlnsAttr = tuple[name, value: string, ownerElement: PElement]
+
+var nsList: seq[xmlnsAttr] = @[] # Used for storing namespaces
+
+proc getNS(prefix: string): string =
+  var defaultNS: seq[string] = @[]
+
+  for key, value, tag in items(nsList):
+    if ":" in key:
+      if key.split(':')[1] == prefix:
+        return value
+        
+    if key == "xmlns":
+      defaultNS.add(value)
+      
+  # Don't return the default namespaces
+  # in the loop, because then they would have a precedence
+  # over normal namespaces
+  if defaultNS.len() > 0:
+    return defaultNS[0] # Return the first found default namespace
+                        # if none are specified for this prefix
+    
+  return ""
     
 proc parseText(x: var TXmlParser, doc: var PDocument): PText =
   result = doc.createTextNode(x.charData())
@@ -28,24 +53,33 @@ proc parseElement(x: var TXmlParser, doc: var PDocument): PElement =
     case x.kind()
     of xmlEof:
       break
-    of xmlElementStart:
-      if n.tagName() != "":
-        n.appendChild(parseElement(x, doc))
-      else:
-        n = doc.createElement(x.elementName)
-    of xmlElementOpen:
+    of xmlElementStart, xmlElementOpen:
       if n.tagName() != "":
         n.appendChild(parseElement(x, doc))
       else:
-        if x.elementName.contains(':'):
-          #TODO: NamespaceURI
-          n = doc.createElementNS("nil", x.elementName)
-        else:  
-          n = doc.createElement(x.elementName)
+        n = doc.createElementNS("", x.elementName)
         
     of xmlElementEnd:
       if x.elementName == n.nodeName:
         # n.normalize() # Remove any whitespace etc.
+        
+        var ns: string
+        if x.elementName.contains(':'):
+          ns = getNS(x.elementName.split(':')[0])
+        else:
+          ns = getNS("")
+        
+        n.namespaceURI = ns
+        
+        # Remove any namespaces this element declared
+        var count = 0 # Variable which keeps the index
+                      # We need to edit it..
+        for i in low(nsList)..len(nsList)-1:
+          if nsList[count][2] == n:
+            nsList.delete(count)
+            dec(count)
+          inc(count)
+
         return n
       else: #The wrong element is ended
         raise newException(EMismatchedTag, "Mismatched tag at line " & 
@@ -54,11 +88,15 @@ proc parseElement(x: var TXmlParser, doc: var PDocument): PElement =
     of xmlCharData:
       n.appendChild(parseText(x, doc))
     of xmlAttribute:
+      if x.attrKey == "xmlns" or x.attrKey.startsWith("xmlns:"):
+        nsList.add((x.attrKey, x.attrValue, n))
+        
       if x.attrKey.contains(':'):
-        #TODO: NamespaceURI
-        n.setAttributeNS("nil", x.attrKey, x.attrValue)
+        var ns = getNS(x.attrKey)
+        n.setAttributeNS(ns, x.attrKey, x.attrValue)
       else:
         n.setAttribute(x.attrKey, x.attrValue)
+
     of xmlCData:
       n.appendChild(doc.createCDATASection(x.charData()))
     of xmlComment:
@@ -75,16 +113,13 @@ proc parseElement(x: var TXmlParser, doc: var PDocument): PElement =
 
   raise newException(EMismatchedTag, 
     "Mismatched tag at line " & $x.getLine() & " column " & $x.getColumn)
-    
-proc loadXML*(path: string): PDocument =
-  ## Loads and parses XML from file specified by ``path``, and returns 
+
+proc loadXMLStream*(stream: PStream): PDocument =
+  ## Loads and parses XML from a stream specified by ``stream``, and returns 
   ## a ``PDocument``
-  
-  var s = newFileStream(path, fmRead)
-  if s == nil: raise newException(EIO, "Unable to read file " & path)
 
   var x: TXmlParser
-  open(x, s, path, {reportComments})
+  open(x, stream, nil, {reportComments})
   
   var XmlDoc: PDocument
   var DOM: PDOMImplementation = getDOM()
@@ -102,10 +137,32 @@ proc loadXML*(path: string): PDocument =
     else:
       raise newException(EParserError, "Unexpected XML Parser event")
 
-  close(x)
   return XmlDoc
 
+proc loadXML*(xml: string): PDocument =
+  ## Loads and parses XML from a string specified by ``xml``, and returns 
+  ## a ``PDocument``
+  var s = newStringStream(xml)
+  return loadXMLStream(s)
+  
+    
+proc loadXMLFile*(path: string): PDocument =
+  ## Loads and parses XML from a file specified by ``path``, and returns 
+  ## a ``PDocument``
+  
+  var s = newFileStream(path, fmRead)
+  if s == nil: raise newException(EIO, "Unable to read file " & path)
+  return loadXMLStream(s)
+
 
 when isMainModule:
-  var xml = loadXML(r"C:\Users\Dominik\Desktop\Code\Nimrod\xmldom\test.xml")
-  echo($xml)
+  var xml = loadXMLFile(r"C:\Users\Dominik\Desktop\Code\Nimrod\xmldom\test.xml")
+  #echo(xml.getElementsByTagName("m:test2")[0].namespaceURI)
+  #echo(xml.getElementsByTagName("bla:test")[0].namespaceURI)
+  #echo(xml.getElementsByTagName("test")[0].namespaceURI)
+  for i in items(xml.getElementsByTagName("*")):
+    if i.namespaceURI != nil:
+      echo(i.nodeName, "=", i.namespaceURI)
+
+    
+  echo($xml)
\ No newline at end of file
diff --git a/lib/pure/xmltreeparser.nim b/lib/pure/xmlparser.nim
index bf2c05570..635497fa8 100644
--- a/lib/pure/xmltreeparser.nim
+++ b/lib/pure/xmlparser.nim
@@ -25,6 +25,8 @@ proc raiseInvalidXml(errors: seq[string]) =
 proc addNode(father, son: PXmlNode) = 
   if son != nil: add(father, son)
 
+proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode
+
 proc untilElementEnd(x: var TXmlParser, result: PXmlNode, 
                      errors: var seq[string]) =
   while true:
@@ -33,11 +35,11 @@ proc untilElementEnd(x: var TXmlParser, result: PXmlNode,
       if x.elementName == result.tag: 
         next(x)
       else:
-        errors.add(errorMsg(x, "</" & result.tag & "$1> expected"))
+        errors.add(errorMsg(x, "</" & result.tag & "> expected"))
         # do not skip it here!
       break
     of xmlEof:
-      errors.add(errorMsg(x, "</" & result.tag & "$1> expected"))
+      errors.add(errorMsg(x, "</" & result.tag & "> expected"))
       break
     else:
       result.addNode(parse(x, errors))
@@ -91,7 +93,7 @@ proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode =
     next(x)
   of xmlEntity:
     ## &entity;
-    ## XXX To implement!
+    errors.add(errorMsg(x, "unknown entity: " & x.entityName))
     next(x)
   of xmlEof: nil
 
@@ -110,6 +112,8 @@ proc parseXml*(s: PStream, filename: string,
     of xmlComment, xmlWhitespace: nil # just skip it
     of xmlError:
       errors.add(errorMsg(x))
+    of xmlSpecial:
+      errors.add(errorMsg(x, "<some_tag> expected"))      
     else:
       errors.add(errorMsg(x, "<some_tag> expected"))
       break
@@ -122,17 +126,33 @@ proc parseXml*(s: PStream): PXmlNode =
   result = parseXml(s, "unknown_html_doc", errors)
   if errors.len > 0: raiseInvalidXMl(errors)
 
-proc loadXml*(path: string, reportErrors = false): PXmlNode = 
+proc loadXml*(path: string, errors: var seq[string]): PXmlNode = 
   ## Loads and parses XML from file specified by ``path``, and returns 
-  ## a ``PXmlNode``. If `reportErrors` is true, the parsing errors are
-  ## ``echo``ed, otherwise an exception is thrown.
+  ## a ``PXmlNode``. Every occured parsing error is added to the `errors`
+  ## sequence.
   var s = newFileStream(path, fmRead)
   if s == nil: raise newException(EIO, "Unable to read file: " & path)
-  
-  var errors: seq[string] = @[]
   result = parseXml(s, path, errors)
-  if reportErrors: 
-    for msg in items(errors): echo(msg)
-  elif errors.len > 0: 
-    raiseInvalidXMl(errors)
 
+proc loadXml*(path: string): PXmlNode = 
+  ## Loads and parses XML from file specified by ``path``, and returns 
+  ## a ``PXmlNode``.  All parsing errors are turned into an ``EInvalidXML``
+  ## exception.  
+  var errors: seq[string] = @[]
+  result = loadXml(path, errors)
+  if errors.len > 0: raiseInvalidXMl(errors)
+
+when isMainModule:
+  import os
+
+  var errors: seq[string] = @[]  
+  var x = loadXml(paramStr(1), errors)
+  for e in items(errors): echo e
+  
+  var f: TFile
+  if open(f, "xmltest.txt", fmWrite):
+    f.write($x)
+    f.close()
+  else:
+    quit("cannot write test.txt")
+    
diff --git a/lib/pure/xmltree.nim b/lib/pure/xmltree.nim
index 2b0977874..7b77fe156 100644
--- a/lib/pure/xmltree.nim
+++ b/lib/pure/xmltree.nim
@@ -153,8 +153,15 @@ proc addIndent(result: var string, indent: int) =
   result.add("\n")
   for i in 1..indent: result.add(' ')
   
+proc noWhitespace(n: PXmlNode): bool =
+  #for i in 1..n.len-1:
+  #  if n[i].kind != n[0].kind: return true
+  for i in 0..n.len-1:
+    if n[i].kind in {xnText, xnEntity}: return true
+  
 proc add*(result: var string, n: PXmlNode, indent = 0, indWidth = 2) = 
   ## adds the textual representation of `n` to `result`.
+  if n == nil: return
   case n.k
   of xnElement:
     result.add('<')
@@ -168,10 +175,19 @@ proc add*(result: var string, n: PXmlNode, indent = 0, indWidth = 2) =
         result.add('"')
     if n.len > 0:
       result.add('>')
-      for i in 0..n.len-1:
-        result.addIndent(indent+indWidth)
-        result.add(n[i], indent+indWidth, indWidth)
-      result.addIndent(indent)
+      if n.len > 1:
+        if noWhitespace(n):
+          # for mixed leaves, we cannot output whitespace for readability,
+          # because this would be wrong. For example: ``a<b>b</b>`` is
+          # different from ``a <b>b</b>``.
+          for i in 0..n.len-1: result.add(n[i], indent+indWidth, indWidth)
+        else: 
+          for i in 0..n.len-1:
+            result.addIndent(indent+indWidth)
+            result.add(n[i], indent+indWidth, indWidth)
+          result.addIndent(indent)
+      else:
+        result.add(n[0], indent+indWidth, indWidth)
       result.add("</")
       result.add(n.fTag)
       result.add(">")
diff --git a/rod/scanner.nim b/rod/scanner.nim
index 9367208da..04a41fb5c 100644
--- a/rod/scanner.nim
+++ b/rod/scanner.nim
@@ -50,7 +50,8 @@ type
     tkBind, tkBlock, tkBreak, tkCase, tkCast, 
     tkConst, tkContinue, tkConverter, tkDiscard, tkDistinct, tkDiv, tkElif, 
     tkElse, tkEnd, tkEnum, tkExcept, tkFinally, tkFor, tkFrom, tkGeneric, tkIf, 
-    tkImplies, tkImport, tkIn, tkInclude, tkIs, tkIsnot, tkIterator, tkLambda, 
+    tkImplies, tkImport, tkIn, tkInclude, tkIs, tkIsnot, tkIterator,
+    tkLambda, tkLet,
     tkMacro, tkMethod, tkMod, tkNil, tkNot, tkNotin, tkObject, tkOf, tkOr, 
     tkOut, tkProc, tkPtr, tkRaise, tkRef, tkReturn, tkShl, tkShr, tkTemplate, 
     tkTry, tkTuple, tkType, tkVar, tkWhen, tkWhile, tkWith, tkWithout, tkXor,
@@ -82,7 +83,8 @@ const
     "bind", "block", "break", "case", "cast", 
     "const", "continue", "converter", "discard", "distinct", "div", "elif", 
     "else", "end", "enum", "except", "finally", "for", "from", "generic", "if", 
-    "implies", "import", "in", "include", "is", "isnot", "iterator", "lambda", 
+    "implies", "import", "in", "include", "is", "isnot", "iterator",
+    "lambda", "let", 
     "macro", "method", "mod", "nil", "not", "notin", "object", "of", "or", 
     "out", "proc", "ptr", "raise", "ref", "return", "shl", "shr", "template", 
     "try", "tuple", "type", "var", "when", "while", "with", "without", "xor",
@@ -769,7 +771,8 @@ proc rawGetTok(L: var TLexer, tok: var TToken) =
       Inc(L.bufpos)
     of '\"': 
       getString(L, tok, false)
-    of '\'': 
+    of '\'':
+      tok.tokType = tkCharLit
       getCharacter(L, tok)
       tok.tokType = tkCharLit
     of lexbase.EndOfFile: 
diff --git a/rod/wordrecg.nim b/rod/wordrecg.nim
index 1d078dfcc..daadd57d0 100644
--- a/rod/wordrecg.nim
+++ b/rod/wordrecg.nim
@@ -26,7 +26,8 @@ type
     wBind, wBlock, wBreak, wCase, wCast, wConst, 
     wContinue, wConverter, wDiscard, wDistinct, wDiv, wElif, wElse, wEnd, wEnum, 
     wExcept, wFinally, wFor, wFrom, wGeneric, wIf, wImplies, wImport, wIn, 
-    wInclude, wIs, wIsnot, wIterator, wLambda, wMacro, wMethod, wMod, wNil, 
+    wInclude, wIs, wIsnot, wIterator, wLambda, wLet,
+    wMacro, wMethod, wMod, wNil, 
     wNot, wNotin, wObject, wOf, wOr, wOut, wProc, wPtr, wRaise, wRef, wReturn, 
     wShl, wShr, wTemplate, wTry, wTuple, wType, wVar, wWhen, wWhile, wWith, 
     wWithout, wXor, wYield,
@@ -67,7 +68,8 @@ const
     "bind", "block", "break", "case", "cast", 
     "const", "continue", "converter", "discard", "distinct", "div", "elif", 
     "else", "end", "enum", "except", "finally", "for", "from", "generic", "if", 
-    "implies", "import", "in", "include", "is", "isnot", "iterator", "lambda", 
+    "implies", "import", "in", "include", "is", "isnot", "iterator",
+    "lambda", "let",
     "macro", "method", "mod", "nil", "not", "notin", "object", "of", "or", 
     "out", "proc", "ptr", "raise", "ref", "return", "shl", "shr", "template", 
     "try", "tuple", "type", "var", "when", "while", "with", "without", "xor",
diff --git a/tests/wildhtml.html b/tests/wildhtml.html
index 06ff2eaf4..dfab7ba95 100644
--- a/tests/wildhtml.html
+++ b/tests/wildhtml.html
@@ -1,2 +1,25 @@
 <!DOCTYPE some doctype >
   
+<html>
+  <head>
+    <title>Test title!</title>
+  </head>
+
+  <body>
+    Ein Text mit vielen Zeichenumbr&uuml;chen. <br />
+    <br><br>
+    
+    <ul>
+      <li>first <span class = "34" >Item.</span>
+      <li>second Item.
+      <li>third item. Mit &auml;.
+    </ul>
+    
+    Para 0.
+    
+    <p>Para1. </p>
+    <p>Para 2.
+    
+  </body>
+</html>
+
diff --git a/tools/niminst.nim b/tools/niminst.nim
index 078aba6df..2a5b18c38 100644
--- a/tools/niminst.nim
+++ b/tools/niminst.nim
@@ -290,7 +290,8 @@ proc writeFile(filename, content, newline: string) =
     quit("Cannot open for writing: " & filename)
 
 proc srcdist(c: var TConfigData) =
-  for x in walkFiles("lib/*.h"): CopyFile("build" / extractFilename(x), x)
+  for x in walkFiles("lib/*.h"):
+    CopyFile(dest="build" / extractFilename(x), source=x)
   for osA in 1..c.oses.len:
     for cpuA in 1..c.cpus.len:
       var dir = buildDir(osA, cpuA)
@@ -307,7 +308,7 @@ proc srcdist(c: var TConfigData) =
       readCFiles(c, osA, cpuA)
       for i in 0 .. c.cfiles[osA][cpuA].len-1:
         var dest = dir / extractFilename(c.cfiles[osA][cpuA][i])
-        CopyFile(dest, c.cfiles[osA][cpuA][i])
+        CopyFile(dest=dest, source=c.cfiles[osA][cpuA][i])
         c.cfiles[osA][cpuA][i] = dest
   # second pass: remove duplicate files
   for osA in countdown(c.oses.len, 1):
diff --git a/tools/nimweb.nim b/tools/nimweb.nim
index bebde6cc5..7889591fc 100644
--- a/tools/nimweb.nim
+++ b/tools/nimweb.nim
@@ -179,7 +179,7 @@ proc buildPdfDoc(c: var TConfigData, destPath: string) =
       Exec("pdflatex " & changeFileExt(d, "tex"))
       # delete all the crappy temporary files:
       var pdf = splitFile(d).name & ".pdf"
-      moveFile(destPath / pdf, pdf)
+      moveFile(dest=destPath / pdf, source=pdf)
       removeFile(changeFileExt(pdf, "aux"))
       if existsFile(changeFileExt(pdf, "toc")):
         removeFile(changeFileExt(pdf, "toc"))
diff --git a/tools/trimcc.nim b/tools/trimcc.nim
index 966f406d4..47dd2a4b4 100644
--- a/tools/trimcc.nim
+++ b/tools/trimcc.nim
@@ -10,7 +10,7 @@ proc walker(dir: string) =
   for kind, path in walkDir(dir):

     case kind

     of pcFile:

-      moveFile(newName(path), path)

+      moveFile(dest=newName(path), source=path)

       # test if installation still works:

       if execShellCmd(r"nimrod c --force_build tests\tlastmod") == 0:

         echo "Optional: ", path

diff --git a/web/news.txt b/web/news.txt
index 4764bc49a..178bdead7 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -21,6 +21,8 @@ Bugfixes
 - Fixed a bug in ``os.setFilePermissions`` for Windows.
 - An overloadable symbol can now have the same name as an imported module.
 - Fixed a serious bug in ``strutils.cmpIgnoreCase``. 
+- Fixed ``unicode.toUTF8``. 
+- The compiler now rejects ``'\n'``. 
 
 
 Additions
@@ -40,7 +42,7 @@ Additions
 - Added ``xmldom`` module.
 - Added ``xmldomparser`` module.
 - Added ``xmltree`` module.
-- Added ``xmltreeparser`` module.
+- Added ``xmlparser`` module.
 - Added ``htmlparser`` module.
 - Many wrappers now do not contain redundant name prefixes (like ``GTK_``,
   ``lua``). The new wrappers are available in ``lib/newwrap``. Change
@@ -63,6 +65,11 @@ Changes affecting backwards compatibility
   the standard library's path. 
 - The compiler does not include a Pascal parser for bootstrapping purposes any
   more. Instead there is a ``pas2nim`` tool that contains the old functionality.
+- The procs ``os.copyFile`` and ``os.moveFile`` have been deprecated
+  temporarily, so that the compiler warns about their usage. Use them with
+  named arguments only, because the parameter order will change the next
+  version!
+- ``atomic`` and ``let`` are now keywords.
 
 
 2009-12-21 Version 0.8.6 released
diff --git a/web/nimrod.ini b/web/nimrod.ini
index 1cb494f9c..b92a0f36f 100644
--- a/web/nimrod.ini
+++ b/web/nimrod.ini
@@ -31,6 +31,7 @@ srcdoc: "pure/streams;pure/terminal;pure/cgi;impure/web;pure/unicode"
 srcdoc: "impure/zipfiles;pure/xmlgen;pure/macros;pure/parseutils;pure/browsers"
 srcdoc: "impure/db_postgres;impure/db_mysql;pure/httpserver;pure/httpclient"
 srcdoc: "pure/ropes;pure/unidecode/unidecode;pure/xmldom;pure/xmldomparser"
+srcdoc: "pure/xmlparser;pure/htmlparser;pure/xmltree"
 
 webdoc: "wrappers/libcurl;pure/md5;wrappers/mysql;wrappers/iup"
 webdoc: "wrappers/sqlite3;wrappers/python;wrappers/tcl"