#!/bin/sh
: ; exec klone $0 "$@"
; The above line allows not to embed the exact path of the klone executable

;;Skeleton of a typical klone script

(setq args (getopts "USAGE: %0 [options] [URLs...]
Opens new netscape windows on the URLs.
If no URL given, uses the contents of the X cut buffer (for this, need the 
external unix command \"xselection\"
URL can also be the name of an existing file
This uses the netscape -remote system."
    ("-f" () flux "reads continually the stdin, and incrementally opens
netscape windows on the URLs it finds there. URLs must begin by:
(ftp|http|https|news)://")
    ("-v" () verbose "verbose mode")
   ))

(defun main (&aux
  )
  (if
    flux
    (flux-read *standard-input*)
    args
    (dolist (url args) (netscape-new url))
    t
    (netscape-new (url-from-xselection))
  )
)

;; Quotes , () spaces into their % form
;; Removes garbage often found with cut and paste: trailing/prefixing spaces,
;; dots, commas... Prefixes by http:// if needed (or ftp:// for numeric IPs
;; In case of multi-line pastes, seeks only full URLs with protocols to be safe
;; tp:// ==> ftp://
;; ttp:// ==> http://
;; a.name.url ==> http://
;; a.numeric.ip ==> ftp://

(setq multi-line-re (regcomp "[^ \t\r\n][ \t\r]*\n[ \t\r]*[^ \t\r\n]"))
(setq URL-re (regcomp 
    "(ftp|http|https|news):[/][/][-a-zA-Z_0-9.:@]+[^ \t\n\r]*"))

(defun netscape-new (url)
  (if (regexec multi-line-re url) 
    (progn
      (doregexp (re URL-re url)
	(netscape-new (re 0))
    ))
    (progn
      (replace-string url "^([ \t\n\r])+" "" :all t :quote t)
      (replace-string url "([ \t\n\r.,])+$" "" :all t :quote t)
      (replace-string url "^tp:[/][/]" "ftp://" :all t :quote t)
      (replace-string url "^ftp[.]" "ftp://ftp." :all t :quote t)
      (replace-string url "^ttp:[/][/]" "http://" :all t :quote t)
      (replace-string url "^([0-9]+[.][0-9]+[.][0-9]+[.][0-9]+)"
	"ftp://\\1" :all t)
      (if (file-stats url) (setq url
	  (+ "file:"
	    (concat-paths *current-directory* (expand-filename url)))))
      (replace-string url " " "%20" :all t :quote t)
      (replace-string url "," "%2c" :all t :quote t)
      (replace-string url "[(]" "%28" :all t :quote t)
      (replace-string url "[)]" "%29" :all t :quote t)
      (when (/= 0 (wait (system (list "netscape" 
		"-noraise" "-remote" (+ "openURL(" url ",new-window)")
	))))
	(setq *SIGHUP-on-exit* ())
	(system (list "netscape" url)) ;no netscape? run it
	(select :timeout 5000)
))))

(defun url-from-xselection ()
  (String (sh:open xselection PRIMARY))
)

(defun flux-read (in &aux 
    (buffer (copy ""))
    (pos 0)
    chars
    (re (regcomp URL-re))		;must be different
  )
  (stream-mode in :blocking ())
  (catch 'EOF
    (while t
      (select in)
      (nconc buffer (setq chars (read-chars () in)))	;append read chunck
      (verbose? "%0 chars read: %r1" (length chars) chars)
      (while (re buffer pos)		;find URLs in buffer
	(setq pos re.0.1)		;and position ourselves afterwards
	(netscape-new (re 0))
	(verbose? "URL found at (%0 %1): %r2" re.0.0 re.0.1 (re 0))
      )
      (when (> pos 0)			;get rid of scanned part
	(setq buffer (subseq buffer pos))
	(verbose? "Dumping first %0 chars" pos)
	pos = 0
      )
    )
  )
)

(main)

;; Specs found on: http://www.netscape.com/newsref/std/x-remote.html
;;
;; When Netscape Navigator is invoked with the -remote argument, it
;; does not open a window, but instead connects to and controls an
;; already-existing process. The argument to the -remote switch is an Xt
;; action to invoke, with optional arguments. 
;; 
;; Remote control is implemented using X properties, so the two
;; processes need not be running on the same machine, and need not
;; share a file system. 
;; 
;; All of Netscape's action names are the same as its resource names;
;; so, for example, if you wanted to know the name of the action that
;; corresponds to the ``Add Bookmark'' menu item, you could look in
;; Netscape.ad for ``Add Bookmark'' and see that the resource that is
;; set to that string is addBookmark - that's the name of the Action as
;; well. 
;; 
;; You can use Actions in Translation tables in the usual Xt-ish way, but
;; you can also invoke them directly via the -remote option, like this:
;; netscape -remote 'addBookmark()'. That command will cause
;; the existing Netscape Navigator process to add its current URL to the
;; bookmarks, just as if you had selected that menu item. 
;; 
;; To open a document, you would do netscape -remote
;; 'openURL(http://home.netscape.com)'. 
;; 
;; If there is no Netscape 1.1 (or newer) window on the screen, the
;; command will fail. 
;; 
;; Multiple -remote options may be given on the same command line.
;; They will be executed sequentially until or unless one fails. 
;; 
;; If the command fails, and error message will be reported to stderr and it
;; will exit with a nonzero status. 
;; 
;; 
;;                 SPECIAL ACTIONS 
;; 
;; Invoking any action with no arguments (as above) will have the same
;; effect as selecting the corresponding menu item. However, some
;; actions have slightly different behavior that can be accessed by
;; passing arguments: 
;; 
;;      openURL ( ) 
;;          Prompts for a URL with a dialog box. 
;;      openURL (URL) 
;;          Opens the specified document without prompting. 
;;      openURL (URL, new-window) 
;;          Create a new window displaying the the specified
;;          document. 
;;      openFile ( ) 
;;          Prompts for a file with a dialog box. 
;;      openFile (File) 
;;          Opens the specified file without prompting. 
;;      saveAs ( ) 
;;          Prompts for a file with a dialog box (like the menu item). 
;;      saveAs (Output-File) 
;;          Writes HTML to the specified file without prompting. 
;;      saveAs (Output-File, Type) 
;;          Writes to the specified file with the type specified - the type
;;          may be HTML, Text, or PostScript. 
;;      mailto ( ) 
;;          pops up the mail dialog with the To: field empty. 
;;      mailto (a, b, c) 
;;          Puts the addresses "a, b, c" in the default To: field. 
;;      addBookmark ( ) 
;;          Adds the current document to the bookmark list. 
;;      addBookmark (URL) 
;;          Adds the given document to the bookmark list. 
;;      addBookmark (URL, Title) 
;;          Adds the given document to the bookmark list, with the
;;          given title. 
;; 
;; All actions not listed here ignore any arguments given them. However,
;; they may be expanded to take arguments in the future. For a full list of
;; available actions, consult the resource file, Netscape.ad. 
;; 
;; 
;; 
;;                FURTHER CONTROL 
;; 
;; A few other options exist for finer-grained control of the behavior of the
;; remotely executed commands. 
;; 
;; -id window 
;;      You can select a window to control with the -id command-line
;;      option; otherwise, the first Netscape Navigator window found will
;;      be used. The argument to this option is an X window id, as a
;;      decimal or hexadecimal number. (You can find window IDs with
;;      the xwininfo(1) or xlswins(1) programs.) For example: 
;; 
;;      netscape -id 0x3c00124 -remote 'openURL(http://home.netscape.com)'
;; 
;; -raise
;; -noraise 
;;      You can control whether the -remote command will cause the
;;      Netscape window to automatically raise itself to the top with the
;;      -raise and -noraise options. The default is to raise, but this may
;;      be disabled as follows: 
;; 
;;              netscape -noraise -remote 'openURL(http://home.netscape.com)'
;; 
;;      The -raise and -noraise options apply to all following -remote
;;      commands on the command line, and may be interleaved. For
;;      example, to add a bookmark without raising the window, and then
;;      open a URL and raise the window, one could do 
;; 
;;              netscape -noraise -remote 'addBookmark(http://foo)'  \
;;                       -raise   -remote 'openURL(http://bar)'


;;; EMACS MODES
;;; Local Variables: ***
;;; mode:lisp ***
;;; End: ***

