diff -Naur -x '*~' -x CVS -x '*.orig' -x '*.rej' base/src/wiliki/edit.scm WiLiKi/src/wiliki/edit.scm
--- base/src/wiliki/edit.scm	2005-08-23 03:14:23.000000000 +0000
+++ WiLiKi/src/wiliki/edit.scm	2006-05-14 16:40:18.000000000 +0000
@@ -43,10 +43,10 @@
       (label (@ (for donttouch)) ,($$ "Don't update 'Recent Changes'"))))
   
   `((form
-     (@ (method POST) (action ,(cgi-name-of (wiliki))))
+     (@ (method POST) (action ,(wiliki:local-cgi (wiliki) "")))
      ,@(buttons) ,@(donttouch-checkbox)
      (br)
-     (input (@ (type hidden) (name c) (value c)))
+     (input (@ (type hidden) (name c) (value c)))       
      (input (@ (type hidden) (name p) (value ,pagename)))
      (input (@ (type hidden) (name l) (value ,(wiliki:lang))))
      (input (@ (type hidden) (name mtime) (value ,mtime)))
diff -Naur -x '*~' -x CVS -x '*.orig' -x '*.rej' base/src/wiliki/format.scm WiLiKi/src/wiliki/format.scm
--- base/src/wiliki/format.scm	2005-09-05 01:00:22.000000000 +0000
+++ WiLiKi/src/wiliki/format.scm	2006-05-14 16:40:19.000000000 +0000
@@ -51,6 +51,8 @@
           wiliki:format-time
           wiliki:format-content
           wiliki:formatter
+	  wiliki:format-wikiname-anchor
+	  wiliki:format-cgi-anchor	  	  
           wiliki:format-page-header
           wiliki:format-page-content
           wiliki:format-page-footer
@@ -98,6 +100,11 @@
                                 (wiliki:format-content page)))
    (head-elements :init-keyword :head-elements
                   :init-value (lambda (page opts) '()))
+  (wikiname       :init-keyword :wikiname
+		  :init-value (lambda (name) (list "[[" name "]]")))
+  (cgi            :init-keyword :cgi
+		  :init-value (lambda (args text) (append args text)))
+      
    ))
 
 ;; Global context and the default formatter
@@ -252,6 +259,18 @@
 ;; all the closure slots of <wiliki-formatter> and the default behavior
 ;; will directly be embedded in these methods.
 
+(define-method wiliki:format-wikiname-anchor ((fmt <wiliki-formatter>) name)
+   ((ref fmt 'wikiname) name))
+
+(define-method wiliki:format-wikiname-anchor (name)
+  (wiliki:format-wikiname-anchor (the-formatter) name))
+
+(define-method wiliki:format-cgi-anchor ((fmt <wiliki-formatter>) args text)
+   ((ref fmt 'cgi) args text))
+
+(define-method wiliki:format-cgi-anchor (args text)
+   (wiliki:format-cgi-anchor (the-formatter) args text))
+
 (define-method wiliki:format-wikiname ((fmt <wiliki-formatter>) name)
   ((ref fmt 'bracket) name))
 (define-method wiliki:format-wikiname ((name <string>))
diff -Naur -x '*~' -x CVS -x '*.orig' -x '*.rej' base/src/wiliki/macro.scm WiLiKi/src/wiliki/macro.scm
--- base/src/wiliki/macro.scm	2005-09-05 01:00:22.000000000 +0000
+++ WiLiKi/src/wiliki/macro.scm	2006-05-14 16:40:19.000000000 +0000
@@ -253,7 +253,7 @@
 
         (define (make-anchor headings)
           (let ((id (wiliki:calculate-heading-id headings)))
-            `(li (a (@ (href ,#`",(wiliki:self-url \"~a\" pagename)#,id"))
+            `(li (a (@ (href ,(string-append (wiliki:wikiname-local-url (wiliki) pagename) "#" id)))
                     ,@(wiliki:format-line-plainly (car headings))))))
 
         (let1 headings
diff -Naur -x '*~' -x CVS -x '*.orig' -x '*.rej' base/src/wiliki/rss.scm WiLiKi/src/wiliki/rss.scm
--- base/src/wiliki/rss.scm	2005-08-23 03:14:23.000000000 +0000
+++ WiLiKi/src/wiliki/rss.scm	2006-05-14 16:40:20.000000000 +0000
@@ -43,7 +43,7 @@
 
 (define (rss-format entries)
   (let* ((self (wiliki))
-         (full-url (full-script-path-of self)))
+         (full-url (wiliki:wikiname-full-url self (top-page-of self))))
     `("Content-type: text/xml\n\n"
       "<?xml version=\"1.0\" encoding=\"" ,(output-charset) "\" ?>\n"
       "<rdf:RDF
@@ -57,10 +57,10 @@
         (rdf-link  full-url)
         (rdf-description (description-of self))
         (rdf-items-seq
-         (map (lambda (entry) (rdf-li (url-full "~a" (cv-out (car entry)))))
+         (map (lambda (entry) (rdf-li (wiliki:wikiname-full-url self (car entry))))
               entries)))
       ,(map (lambda (entry)
-              (let1 url (url-full "~a" (cv-out (car entry)))
+              (let1 url (wiliki:wikiname-full-url self (car entry))
                 (rdf-item url
                           (rdf-title (car entry))
                           (rdf-link url)
diff -Naur -x '*~' -x CVS -x '*.orig' -x '*.rej' base/src/wiliki.scm WiLiKi/src/wiliki.scm
--- base/src/wiliki.scm	2005-09-05 01:00:21.000000000 +0000
+++ WiLiKi/src/wiliki.scm	2006-05-14 16:51:42.000000000 +0000
@@ -47,11 +47,15 @@
   (use wiliki.page)
   (use wiliki.db)
   (export <wiliki> wiliki-main wiliki
-          wiliki:language-link wiliki:self-url
+          wiliki:language-link
           wiliki:top-link wiliki:edit-link wiliki:history-link
           wiliki:all-link wiliki:recent-link wiliki:search-box
           wiliki:menu-links wiliki:page-title
           wiliki:wikiname-anchor wiliki:wikiname-anchor-string
+	  wiliki:full-url-prefix wiliki:local-cgi wiliki:full-cgi
+	  wiliki:wikiname-local-url wiliki:wikiname-full-url
+	  wiliki:wikiname->uri-component
+	  wiliki:uri-component->wikiname
           wiliki:get-formatted-page-content
           wiliki:recent-changes-alist
           wiliki:page-lines-fold
@@ -155,54 +159,12 @@
                   :init-value 40)
    (textarea-cols :accessor textarea-cols-of :init-keyword :textarea-cols
                   :init-value 80)
+   (space-replacement :accessor space-replacement-of :init-keyword :space-replacement
+		      :init-value "_")
    ))
 
 ;; Various gadgets -----------------------------------------
 
-(define (cgi-name-of wiliki)
-  (and wiliki (sys-basename (script-name-of wiliki))))
-
-(define (full-script-path-of wiliki)
-  (and wiliki
-       (format "~a://~a~a~a"
-               (protocol-of wiliki)
-               (server-name-of wiliki)
-               (if (or (and (= (server-port-of wiliki) 80)
-                            (string=? (protocol-of wiliki) "http"))
-                       (and (= (server-port-of wiliki) 443)
-                            (string=? (protocol-of wiliki) "https")))
-                 ""
-                 #`":,(server-port-of wiliki)")
-               (script-name-of wiliki))))
-
-(define (lang-spec language prefix)
-  (if (equal? language (language-of (wiliki)))
-    ""
-    #`",|prefix|l=,|language|"))
-
-(define-values (url url-full)
-  (let ()
-    (define (url-format full? fmt args)
-      (let* ((self (wiliki))
-             (fstr (if fmt
-                     #`"?,|fmt|,(lang-spec (wiliki:lang) '&)"
-                     (lang-spec (wiliki:lang) '?))))
-        (string-append
-         (if full?
-           (full-script-path-of self)
-           (cgi-name-of self))
-         (if (null? args)
-           fstr
-           (apply format fstr
-                  (map (compose uri-encode-string x->string) args))))))
-    (values
-     (lambda (fmt . args) (url-format #f fmt args)) ;; url
-     (lambda (fmt . args) (url-format #t fmt args)) ;; url-full
-     )))
-
-;; For export
-(define wiliki:self-url url)
-
 ;; Creates a link to switch language
 (define (wiliki:language-link page)
   (and-let* ((target (or (ref page 'command) (ref page 'key))))
@@ -210,9 +172,8 @@
         (case (wiliki:lang)
           ((jp) (values 'en "->English"))
           (else (values 'jp "->Japanese")))
-      `(a (@ (href ,(string-append (cgi-name-of (wiliki)) "?" target
-                                   (lang-spec language '&))))
-          "[" ,label "]"))))
+      `(a (@ (href ,(wiliki:local-cgi `(,target ("l" . ,(symbol->string language))))))
+	     "[" ,label "]"))))
 
 ;; fallback
 (define-method title-of (obj) "WiLiKi")
@@ -306,7 +267,7 @@
      :command "c=a"
      :content `((ul
                  ,@(map (lambda (k)
-                          `(li ,(wiliki:wikiname-anchor k)))
+                          `(li ,(wiliki:format-wikiname-anchor (wiliki:formatter) k)))
                         (sort (wiliki-db-map (lambda (k v) k)) string<?))))
      )))
 
@@ -321,7 +282,7 @@
                  `(tr
                    (td ,(wiliki:format-time (cdr p)))
                    (td "(" ,(how-long-since (cdr p)) " ago)")
-                   (td ,(wiliki:wikiname-anchor (car p)))))
+                   (td ,(wiliki:format-wikiname-anchor (wiliki:formatter) (car p)))))
                (wiliki-db-recent-changes))))
      )))
 
@@ -341,7 +302,7 @@
      `((ul
         ,@(map (lambda (p)
                  `(li
-                   ,(wiliki:wikiname-anchor (car p))
+                   ,(wiliki:format-wikiname-anchor (wiliki:formatter) (car p))
                    ,(or (and-let* ((mtime (get-keyword :mtime (cdr p) #f)))
                           #`"(,(how-long-since mtime))")
                         "")))
@@ -385,32 +346,39 @@
 ;; Default menu link composers
 (define (wiliki:top-link page)
   (and (not (equal? (ref page 'title) (top-page-of (wiliki))))
-       `(a (@ (href ,#`",(cgi-name-of (wiliki)),(lang-spec (wiliki:lang) '?)"))
-           ,($$ "[Top Page]"))))
+       `(a (@ (href ,(wiliki:wikiname-local-url (wiliki) (top-page-of (wiliki)))))
+	   ,($$ "[Top Page]"))))
 
 (define (wiliki:edit-link page)
   (and (ref (wiliki) 'editable?)
        (wiliki:persistent-page? page)
-       `(a (@ (href ,(url "p=~a&c=e" (ref page 'key)))) ,($$ "[Edit]"))))
+       (wiliki:format-cgi-anchor (wiliki:formatter)
+				 `(("p" . ,(ref page 'key)) ("c" . "e"))
+				 ($$ "[Edit]"))))
 
 (define (wiliki:history-link page)
   (and (ref (wiliki) 'log-file)
        (wiliki:persistent-page? page)
-       `(a (@ (href ,(url "p=~a&c=h" (ref page 'key))))
-           ,($$ "[Edit History]"))))
+       (wiliki:format-cgi-anchor (wiliki:formatter)
+				 `(("p" . ,(ref page 'key)) ("c" . "h"))
+				 ($$ "[Edit History]"))))
 
 (define (wiliki:all-link page)
   (and (not (equal? (ref page 'command) "c=a"))
-       `(a (@ (href ,(url "c=a"))) ,($$ "[All Pages]"))))
+       (wiliki:format-cgi-anchor (wiliki:formatter)
+				 '(("c" . "a"))
+				 ($$ "[All Pages]"))))
 
 (define (wiliki:recent-link page)
   (and (not (equal? (ref page 'command) "c=r"))
-       `(a (@ (href ,(url "c=r"))) ,($$ "[Recent Changes]"))))
+       (wiliki:format-cgi-anchor (wiliki:formatter)
+				 '(("c" . "r"))
+				 ($$ "[Recent Changes]"))))
 
 (define (wiliki:search-box)
-  `((form (@ (method POST) (action ,(cgi-name-of (wiliki)))
+  `((form (@ (method POST) (action ,(wiliki:local-cgi (wiliki) ""))
              (style "margin:0pt; padding:0pt"))
-          (input (@ (type hidden) (name c) (value s)))
+	  (input (@ (type "hidden") (name "c") (value "s")))
           (input (@ (type text) (name key) (size 15)
                     (style "margin:0pt; padding:0pt")))
           (input (@ (type submit) (name search) (value ,($$ "Search"))
@@ -431,8 +399,10 @@
 
 (define (wiliki:page-title page)
   `((h1 ,(if (wiliki:persistent-page? page)
-           `(a (@ (href ,(url "c=s&key=[[~a]]" (ref page 'key))))
-               ,(ref page 'title))
+           `(a (@ (href ,(wiliki:local-cgi (wiliki)
+					   `(("c" . "s")
+					     ("key" . ,(string-append "[[" (ref page 'key) "]]"))))))
+	       ,(ref page 'title))
            (ref page 'title)))))
 
 (define (wiliki:default-page-header page opts)
@@ -450,11 +420,10 @@
 
 (define (wiliki:default-head-elements page opts)
   `((title ,(ref page 'title))
-    ,@(or (and-let* ((w (wiliki))
-                     (fsp (full-script-path-of w)))
-            `((base (@ (href ,fsp)))
+    ,@(or (and-let* ((w (wiliki)))
+            `((base (@ (href ,(wiliki:full-cgi w (top-page-of w)))))
               (link (@ (rel "alternative") (type "application/rss+xml")
-                       (title "RSS") (href ,(format "~a?c=rss" fsp))))))
+                       (title "RSS") (href ,(wiliki:full-cgi w "c=rss"))))))
           '())
     ,(or (and-let* ((w (wiliki)) (ss (style-sheet-of w)))
            `(link (@ (rel "stylesheet") (href ,ss) (type "text/css"))))
@@ -463,14 +432,6 @@
             "body { background-color: #eeeedd }"))
     ))
 
-;; Returns SXML anchor node and string for given wikiname.
-(define (wiliki:wikiname-anchor wikiname)
-  `(a (@ (href ,(url "~a" (cv-out wikiname)))) ,wikiname))
-
-(define (wiliki:wikiname-anchor-string wikiname)
-  (tree->string
-   (wiliki:sxml->stree
-    `(a (@ (href ,(url "~a" (cv-out wikiname)))) ,wikiname))))
 
 (define (default-format-time time)
   (if time
@@ -526,21 +487,139 @@
               ;; virtual one?  Note also the order of this check must match
               ;; the order in cmd-view.
               ((or (wiliki-db-exists? real-name) (virtual-page? real-name))
-               (list (wiliki:wikiname-anchor real-name)))
+               (list (wiliki:format-wikiname-anchor (wiliki:formatter) real-name)))
               (else
                `(,real-name
-                 (a (@ (href ,(url "p=~a&c=e" (cv-out real-name)))) "?")))))
+                 (a (@ (href ,(wiliki:local-cgi
+				 (wiliki) 
+				 `(("p" . ,(cv-out real-name))
+				   ("c" . "e"))))) "?")))))
       )
   )
 
+(define (wiliki:default-wikiname-anchor name)
+   `(a (@ (class "wikiname") (href ,(wiliki:wikiname-local-url (wiliki) name))) ,name))
+
+(define (wiliki:default-cgi-anchor args text)
+   `(a (@ (href ,(wiliki:local-cgi (wiliki) args))) ,text))
+
 (wiliki:formatter
  (make <wiliki-formatter>
    :bracket       default-format-wikiname
    :time          default-format-time
    :header        wiliki:default-page-header
    :footer        wiliki:default-page-footer
-   :head-elements wiliki:default-head-elements))
+   :head-elements wiliki:default-head-elements
+   :wikiname      wiliki:default-wikiname-anchor
+   :cgi           wiliki:default-cgi-anchor))
 
+;; Building URIs -----------------------------------------
+
+;;; Utility for when the full URL, with server name and protocol, is
+;;; necessary.
+
+(define-method wiliki:full-url-prefix ((wiliki <wiliki>))
+  (and wiliki
+       (format "~a://~a~a"
+               (protocol-of wiliki)
+               (server-name-of wiliki)
+               (if (or (and (= (server-port-of wiliki) 80)
+                            (string=? (protocol-of wiliki) "http"))
+                       (and (= (server-port-of wiliki) 443)
+                            (string=? (protocol-of wiliki) "https")))
+                 ""
+                 #`":,(server-port-of wiliki)"))))
+
+;;; Creates an "action" link from argument string
+
+(define-method wiliki:local-cgi ((self <wiliki>) (args <string>))
+   (if (or (eq? (wiliki:lang) (language-of self))
+	   (#/[\?&]l=/ args))
+       (string-append (script-name-of self) "?" args)
+       (string-append (script-name-of self) "?" args "&l=" (symbol->string (wiliki:lang)))))
+
+(define-method wiliki:local-cgi ((args <string>))
+   (wiliki:local-cgi (wiliki) args))
+
+;;; assembles an alist of arguments into a string,
+;;; then creates an action link   
+   
+(define-method wiliki:local-cgi ((self <wiliki>) (args <pair>))
+   (define (format-arg arg)
+      (cond
+	 ((not (pair? arg)) arg)
+	 ((null? (cdr arg)) (car arg))
+	 (else
+	    (string-append (car arg) "=" (cdr arg)))))
+   (wiliki:local-cgi self (string-join 
+			     (map format-arg args) "&")))
+
+(define-method wiliki:local-cgi ((args <pair>))
+   (wiliki:local-cgi (wiliki) args))
+   
+;;; creates a full action link, including server part
+   
+(define-method wiliki:full-cgi ((self <wiliki>) args)
+   (string-append (wiliki:full-url-prefix self) 
+		  (wiliki:local-cgi self args)))
+
+(define-method wiliki:full-cgi (args)
+   (wiliki:full-cgi (wiliki) args))
+
+;;; Maps a wikiname like "Le Café" to a local URL like
+;;; "/cgi-bin/wiliki.cgi?Le+Caf%c3%a9"
+
+(define-method wiliki:wikiname-local-url ((self <wiliki>) wikiname)
+   (let ((uri-c (wiliki:wikiname->uri-component self wikiname))
+	 (path (script-name-of self)))
+	(if (eq? (wiliki:lang) (language-of self))
+	    (string-append path "?" uri-c)
+	    (string-append path "?" uri-c "&l=" (symbol->string (wiliki:lang))))))
+
+(define-method wiliki:wikiname-local-url (wikiname)
+   (wiliki:wikiname-local-url (wiliki) wikiname))
+
+;;; Maps a wikiname like "Le Café" to  full URL like
+;;; "https://www.example.net/cgi-bin/wiliki.cgi?Le+Caf%c3%a9"
+   
+(define-method wiliki:wikiname-full-url ((self <wiliki>) wikiname)
+   (let ((local-url (wiliki:wikiname-local-url self wikiname))
+	 (full-url-prefix (wiliki:full-url-prefix self)))
+	(string-append full-url-prefix local-url)))
+
+(define-method wiliki:wikiname-full-url (wikiname)
+   (wiliki:wikiname-full-url (wiliki) wikiname))
+
+;;; Maps a wikiname like "Le Café" o an URI component like "Le+Caf%c3%a9"
+   
+(define-method wiliki:wikiname->uri-component ((self <wiliki>) wikiname)
+   (uri-encode-string
+      (regexp-replace-all #/ / wikiname 
+			  (space-replacement-of self))))
+
+(define-method wiliki:wikiname->uri-component (wikiname)
+   (wiliki:wikiname->uri-component (wiliki) wikiname))
+
+;;; Maps an URI component like "Le+Caf%c3%a9 to a wikiname like "Le Café"
+   
+(define-method wiliki:uri-component->wikiname ((self <wiliki>) uri-component)
+   (regexp-replace-all (string->regexp (space-replacement-of self))
+		       (uri-decode-string uri-component)
+		       " "))
+
+(define-method wiliki:uri-component->wikiname (uri-component)
+   (wiliki:uri-component->wikiname (wiliki) uri-component))
+
+;; Legacy stuff, deprecated
+
+(define (wiliki:wikiname-anchor wikiname)
+   (wiliki:format-wikiname-anchor (wiliki:formatter) wikiname))
+
+(define (wiliki:wikiname-anchor-string wikiname)
+   (tree->string
+     (wiliki:sxml->stree
+	(wiliki:format-wikiname-anchor (wiliki:formatter) wikiname))))
+   
 ;; Macros -----------------------------------------
 
 (define (expand-writer-macros content)
@@ -637,7 +716,7 @@
    ))
 
 (define (redirect-page key)
-  (cgi-header :location (url "~a" key) :status "302 Moved"))
+  (cgi-header :location (wiliki:wikiname-full-url (wiliki) key) :status "302 Moved"))
 
 
 
@@ -667,7 +746,7 @@
   (define (get-path-info)
     (and-let* ((path (cgi-get-metavariable "PATH_INFO"))
                ((string-prefix? "/" path))
-               (conv (cv-in (uri-decode-string (string-drop path 1)))))
+               (conv (wiliki:uri-component->wikiname (string-drop path 1))))
       conv))
 
   (let1 pg
@@ -678,7 +757,7 @@
             (else ""))
     (if (equal? pg "")
       (top-page-of wiki)
-      pg))
+      (wiliki:uri-component->wikiname wiki pg)))
   )
 
 ;; Entry ------------------------------------------
diff -Naur -x '*~' -x CVS -x '*.orig' -x '*.rej' base/test/Makefile WiLiKi/test/Makefile
--- base/test/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ WiLiKi/test/Makefile	2006-05-14 16:40:49.000000000 +0000
@@ -0,0 +1,23 @@
+GOSH = /usr/local/bin/gosh
+TEST_OUT = test.log logger.log test.dbm _test
+TESTS = format.scm log.scm test-wiliki.scm
+
+all: gosh-path
+
+gosh-path :
+	echo "$(GOSH)" > gosh-path
+
+check : all
+	@rm -rf $(TEST_OUT)
+	@for t in $(TESTS); do \
+	  $(GOSH) -I. -I../src $$t >> test.log; \
+	done
+
+clean :
+	rm -rf core gosh-path $(TEST_OUT) *~
+
+distclean : clean
+	rm -f Makefile
+
+maintainer-clean : clean
+	rm -f Makefile

