From: Ramakrishnan Muthukrishnan Date: Sun, 19 May 2013 18:10:48 +0000 (+0530) Subject: submodulized .emacs.d setup X-Git-Url: https://git.rkrishnan.org/%5B/%5D%20/uri/flags/%22doc.html//%22%22.?a=commitdiff_plain;h=57763b70c44804ec856f8bff9dbcae18bc33c345;p=.emacs.d.git submodulized .emacs.d setup --- diff --git a/.gitmodules b/.gitmodules index 9a65b06..421b435 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,3 +17,15 @@ [submodule "vendor/company-mode"] path = vendor/company-mode url = https://github.com/company-mode/company-mode.git +[submodule "vendor/haskell-mode"] + path = vendor/haskell-mode + url = https://github.com/haskell/haskell-mode.git +[submodule "vendor/swank-js"] + path = vendor/swank-js + url = https://github.com/swank-js/swank-js.git +[submodule "themes/solarized"] + path = themes/solarized + url = https://github.com/bbatsov/solarized-emacs.git +[submodule "themes/zenburn"] + path = themes/zenburn + url = https://github.com/bbatsov/zenburn-emacs.git diff --git a/emacs/ac-python.el b/emacs/ac-python.el new file mode 100644 index 0000000..cb35e4e --- /dev/null +++ b/emacs/ac-python.el @@ -0,0 +1,72 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;; Simple Python Completion Source for Auto-Complete +;;;;; ================================================= +;;;;; +;;;;; This file provides a completion source for Auto-Complete: +;;;;; http://www.emacswiki.org/emacs/AutoComplete +;;;;; +;;;;; Installation +;;;;; ------------ +;;;;; +;;;;; Setup Auto-Complete in the usual fashion, and make sure it gets loaded for +;;;;; python buffers. Then, place this file in your load-path, and add +;;;;; +;;;;; (require 'ac-python) +;;;;; +;;;;; to your .emacs file (after loading Auto-Complete). +;;;;; +;;;;; Usage +;;;;; ----- +;;;;; +;;;;; Python symbols will be completed by Auto-Complete, once Emacs learns about +;;;;; these symbols. This is the short-coming of the plugin, but it's a small +;;;;; price to pay. +;;;;; +;;;;; To teach Emacs about symbols in imported modules, Emacs needs to execute +;;;;; the Python source. This can be accomplished with `python-send-buffer` for +;;;;; example, often bound to `C-c C-c`. If a python process is already running, +;;;;; this is essentially instantaneous. +;;;;; +;;;;; --- +;;;;; +;;;;; Version: 20110519 +;;;;; License: MIT +;;;;; Author: Chris Poole +;;;;; More information: http://chrispoole.com/project/ac-python +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defun ac-get-python-symbol-at-point () + "Return python symbol at point. + +Assumes symbol can be alphanumeric, `.' or `_'." + (let ((end (point)) + (start (ac-python-start-of-expression))) + (buffer-substring-no-properties start end))) + +(defun ac-python-completion-at-point () + "Returns a possibly empty list of completions for the symbol at +point." + (python-symbol-completions (ac-get-python-symbol-at-point))) + +(defun ac-python-start-of-expression () + "Return point of the start of python expression at point. + +Assumes symbol can be alphanumeric, `.' or `_'." + (save-excursion + (and (re-search-backward + (rx (or buffer-start (regexp "[^[:alnum:]._]")) + (group (1+ (regexp "[[:alnum:]._]"))) point) + nil t) + (match-beginning 1)))) + +(defvar ac-source-python + '((candidates . ac-python-completion-at-point) + (prefix . ac-python-start-of-expression) + (symbol . "f") + (requires . 2)) + "Source for python completion.") + +(add-hook 'python-mode-hook (lambda () (add-to-list 'ac-sources 'ac-source-python))) + +(provide 'ac-python) \ No newline at end of file diff --git a/emacs/basic-mode.el b/emacs/basic-mode.el new file mode 100644 index 0000000..70f58c6 --- /dev/null +++ b/emacs/basic-mode.el @@ -0,0 +1,669 @@ +;; basic-mode.el --- A mode for editing Visual Basic programs. + +;; Copyright (C) 1996, Fred White + +;; Author: Fred White +;; Version: 1.0 (April 18, 1996) +;; Keywords: languages basic + +;; LCD Archive Entry: +;; basic-mode|Fred White|fwhite@world.std.com| +;; A mode for editing Visual Basic programs.| +;; 18-Apr-96|1.0|~/modes/basic-mode.el.Z| + +;; This file is NOT part of GNU Emacs but the same permissions apply. +;; +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 2, or (at your +;; option) any later version. +;; +;; GNU Emacs is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2 of the +;; License, or (at your option) any later version. + + +;; Purpose of this package: +;; This is a mode for editing programs written in The World's Most +;; Successful Programming Language. It features automatic +;; indentation, font locking, keyword capitalization, and some minor +;; convenience functions. + +;; Installation instructions +;; Put basic-mode.el somewhere in your path, compile it, and add the +;; following to your init file: + +;; (autoload 'basic-mode "basic-mode" "Basic mode." t) +;; (setq auto-mode-alist (append '(("\\.\\(frm\\|bas\\|cls\\)$" . +;; basic-mode)) auto-mode-alist)) + +;; Of course, under Windows 3.1, you'll have to name this file +;; something shorter than basic-mode.el + + + +;; Known bugs: +;; Doesn't know about ":" separated stmts +;; Doesn't know about single-line IF stmts + + +;; todo: +;; fwd/back-compound-statement +;; completion over OCX methods and properties. +;; ensure Then at the end of IF statements. +;; IDE integration +;; etc. + + +(provide 'basic-mode) + +(defvar basic-xemacs-p (string-match "XEmacs\\|Lucid" (emacs-version))) +(defvar basic-winemacs-p (string-match "Win-Emacs" (emacs-version))) + +;; Variables you may want to customize. +(defvar basic-mode-indent 2 "*Default indentation per nesting level") +(defvar basic-fontify-p t "*Whether to fontify Basic buffers.") +(defvar basic-capitalize-keywords-p t + "*Whether to capitalize BASIC keywords.") +(defvar basic-wild-files "*.frm *.bas *.cls" + "*Wildcard pattern for BASIC source files") +(defvar basic-ide-pathname nil + "*The full pathname of your Visual Basic exe file, if any.") + + +(defvar basic-keywords-to-highlight + '("Dim" "If" "Then" "Else" "ElseIf" "End If") + "*A list of keywords to highlight in Basic mode, or T, meaning all keywords") + +(defvar basic-defn-templates + (list "Public Sub ()\nEnd Sub\n\n" + "Public Function () As Variant\nEnd Function\n\n" + "Public Property Get ()\nEnd Property\n\n") + "*List of function templates though which basic-new-sub cycles.") + + + +(defvar basic-mode-syntax-table nil) +(if basic-mode-syntax-table + () + (setq basic-mode-syntax-table (make-syntax-table)) + (modify-syntax-entry ?\' "\<" basic-mode-syntax-table) ; Comment starter + (modify-syntax-entry ?\n ">" basic-mode-syntax-table) + (modify-syntax-entry ?\\ "w" basic-mode-syntax-table) + (modify-syntax-entry ?_ "w" basic-mode-syntax-table)) + + +(defvar basic-mode-map nil) +(if basic-mode-map + () + (setq basic-mode-map (make-sparse-keymap)) + (define-key basic-mode-map "\t" 'basic-indent-line) + (define-key basic-mode-map "\r" 'basic-newline-and-indent) + (define-key basic-mode-map "\M-\C-a" 'basic-beginning-of-defun) + (define-key basic-mode-map "\M-\C-e" 'basic-end-of-defun) + (define-key basic-mode-map "\M-\C-h" 'basic-mark-defun) + (define-key basic-mode-map "\M-\C-\\" 'basic-indent-region) + (define-key basic-mode-map "\M-q" 'basic-fill-or-indent) + (if basic-xemacs-p + (progn + (if basic-winemacs-p + (define-key basic-mode-map '(control C) 'basic-start-ide)) + (define-key basic-mode-map "\M-G" 'basic-grep) + (define-key basic-mode-map '(meta backspace) 'backward-kill-word) + (define-key basic-mode-map '(control meta /) 'basic-new-sub)))) + + +;; These abbrevs are valid only in a code context. +(defvar basic-mode-abbrev-table nil) + +(defvar basic-mode-hook ()) + + +;; Is there a way to case-fold all regexp matches? + +(defconst basic-defun-start-regexp + (concat + "^[ \t]*\\([Pp]ublic \\|[Pp]rivate \\|[Ss]tatic \\)*" + "\\([Ss]ub\\|[Ff]unction\\|[Pp]roperty +[GgSsLl]et\\|[Tt]ype\\)" + "[ \t]+\\(\\w+\\)[ \t]*(?")) + +(defconst basic-defun-end-regexp + "^[ \t]*[Ee]nd \\([Ss]ub\\|[Ff]unction\\|[Pp]roperty\\|[Tt]ype\\)") + + +;; Includes the compile-time #if variation. +(defconst basic-if-regexp "^[ \t]*#?[Ii]f") +(defconst basic-else-regexp "^[ \t]*#?[Ee]lse\\([Ii]f\\)?") +(defconst basic-endif-regexp "[ \t]*#?[Ee]nd[ \t]*[Ii]f") + +(defconst basic-continuation-regexp "^.*\\_[ \t]*$") +(defconst basic-label-regexp "^[ \t]*[a-zA-Z0-9_]+:$") + +(defconst basic-select-regexp "^[ \t]*[Ss]elect[ \t]+[Cc]ase") +(defconst basic-case-regexp "^[ \t]*[Cc]ase") +(defconst basic-select-end-regexp "^[ \t]*[Ee]nd[ \t]+[Ss]elect") + +(defconst basic-for-regexp "^[ \t]*[Ff]or") +(defconst basic-next-regexp "^[ \t]*[Nn]ext") + +(defconst basic-do-regexp "^[ \t]*[Dd]o") +(defconst basic-loop-regexp "^[ \t]*[Ll]oop") + +(defconst basic-while-regexp "^[ \t]*[Ww]hile") +(defconst basic-wend-regexp "^[ \t]*[Ww]end") + +(defconst basic-with-regexp "^[ \t]*[Ww]ith") +(defconst basic-end-with-regexp "^[ \t]*[Ee]nd[ \t]+[Ww]ith") + +(defconst basic-blank-regexp "^[ \t]*$") +(defconst basic-comment-regexp "^[ \t]*\\s<.*$") + + +;; This is some approximation of the set of reserved words in Visual Basic. +(defconst basic-all-keywords + '("Aggregate" "And" "App" "AppActivate" "Application" "Array" "As" + "Asc" "AscB" "Atn" "Beep" "BeginTrans" "ByVal" "CBool" "CByte" "CCur" + "CDate" "CDbl" "CInt" "CLng" "CSng" "CStr" "CVErr" "CVar" "Call" + "Case" "ChDir" "ChDrive" "Character" "Choose" "Chr" "ChrB" + "ClassModule" "Clipboard" "Close" "Collection" "Column" "Columns" + "Command" "CommitTrans" "CompactDatabase" "Component" "Components" + "Const" "Container" "Containers" "Cos" "CreateDatabase" "CreateObject" + "CurDir" "Currency" "DBEngine" "DDB" "Data" "Database" "Databases" + "Date" "DateAdd" "DateDiff" "DatePart" "DateSerial" "DateValue" "Day" + "Debug" "Declare" "Deftype" "DeleteSetting" "Dim" "Dir" "Do" "Domain" + "Double" "Dynaset" "EOF" "Each" "Else" "End" "Environ" "Erase" "Err" + "Error" "Exit" "Exp" "FV" "False" "Field" "Fields" "FileAttr" + "FileCopy" "FileDateTime" "FileLen" "Fix" "Font" "For" "Form" + "FormTemplate" "Format" "Forms" "FreeFile" "FreeLocks" "Function" + "Get" "GetAllSettings" "GetAttr" "GetObject" "GetSetting" "GoSub" + "GoTo" "Group" "Groups" "Hex" "Hour" "IIf" "IMEStatus" "IPmt" "IRR" + "If" "InStr" "Input" "Int" "Integer" "Is" "IsArray" "IsDate" "IsEmpty" + "IsError" "IsMissing" "IsNull" "IsNumeric" "IsObject" "Kill" "LBound" + "LCase" "LOF" "LSet" "LTrim" "Left" "Len" "Let" "Like" "Line" "Load" + "LoadPicture" "LoadResData" "LoadResPicture" "LoadResString" "Loc" + "Lock" "Log" "Long" "Loop" "MDIForm" "MIRR" "Me" "MenuItems" + "MenuLine" "Mid" "Minute" "MkDir" "Month" "MsgBox" "NPV" "NPer" "Name" + "New" "Next" "Now" "Oct" "On" "Open" "OpenDatabase" "Operator" + "Option" "PPmt" "PV" "Parameter" "Parameters" "Partition" "Picture" + "Pmt" "Print" "Printer" "Printers" "Private" "ProjectTemplate" + "Properties" "Public" "Put" "QBColor" "QueryDef" "QueryDefs" "RGB" + "RSet" "RTrim" "Randomize" "Rate" "ReDim" "Recordset" "Recordsets" + "RegisterDatabase" "Relation" "Relations" "Rem" "RepairDatabase" + "Reset" "Resume" "Return" "Right" "RmDir" "Rnd" "Rollback" "RowBuffer" + "SLN" "SYD" "SavePicture" "SaveSetting" "Screen" "Second" "Seek" + "SelBookmarks" "Select" "SelectedComponents" "SendKeys" "Set" + "SetAttr" "SetDataAccessOption" "SetDefaultWorkspace" "Sgn" "Shell" + "Sin" "Single" "Snapshot" "Space" "Spc" "Sqr" "Static" "Stop" "Str" + "StrComp" "StrConv" "String" "Sub" "SubMenu" "Switch" "Tab" "Table" + "TableDef" "TableDefs" "Tan" "Then" "Time" "TimeSerial" "TimeValue" + "Timer" "To" "Trim" "True" "Type" "TypeName" "UBound" "UCase" "Unload" + "Unlock" "Val" "VarType" "Verb" "Weekday" "Wend" + "While" "Width" "With" "Workspace" "Workspaces" "Write" "Year")) + + +(defun basic-word-list-regexp (keys) + (let ((re "\\b\\(") + (key nil)) + (while keys + (setq key (car keys) + keys (cdr keys)) + (setq re (concat re key (if keys "\\|" "")))) + (concat re "\\)\\b"))) + +(defun basic-keywords-to-highlight () + (if (eq basic-keywords-to-highlight t) + basic-all-keywords + basic-keywords-to-highlight)) + + +(defvar basic-font-lock-keywords + (list + ;; Names of functions. + (list basic-defun-start-regexp 3 'font-lock-function-name-face) + + ;; Statement labels + (cons basic-label-regexp 'font-lock-keyword-face) + + ;; Case values + ;; String-valued cases get font-lock-string-face regardless. + (list "^[ \t]*[Cc]ase[ \t]+\\([^'\n]+\\)" 1 'font-lock-keyword-face t) + + ;; Any keywords you like. + (cons (basic-word-list-regexp (basic-keywords-to-highlight)) + 'font-lock-keyword-face))) + + + +(defun basic-mode () + "A mode for editing Microsoft Visual Basic programs. +Features automatic indentation, font locking, keyword capitalization, +and some minor convenience functions. +Commands: +\\{basic-mode-map}" + (interactive) + (kill-all-local-variables) + (use-local-map basic-mode-map) + (setq major-mode 'basic-mode) + (setq mode-name "Basic") + (set-syntax-table basic-mode-syntax-table) + + (add-hook 'write-file-hooks 'basic-untabify) + + (setq local-abbrev-table basic-mode-abbrev-table) + (if basic-capitalize-keywords-p + (progn + (make-local-variable 'pre-abbrev-expand-hook) + (add-hook 'pre-abbrev-expand-hook 'basic-pre-abbrev-expand-hook) + (abbrev-mode 1))) + + + (make-local-variable 'comment-start) + (setq comment-start "' ") + (make-local-variable 'comment-start-skip) + (setq comment-start-skip "'+ *") + (make-local-variable 'comment-column) + (setq comment-column 40) + (make-local-variable 'comment-end) + (setq comment-end "") + + (make-local-variable 'indent-line-function) + (setq indent-line-function 'basic-indent-line) + + (make-local-variable 'font-lock-keywords) + (setq font-lock-keywords basic-font-lock-keywords) + + (if basic-fontify-p + (font-lock-mode 1)) + + (run-hooks 'basic-mode-hook)) + + +(defun basic-construct-keyword-abbrev-table () + (if basic-mode-abbrev-table + nil + (let ((words basic-all-keywords) + (word nil) + (list nil)) + (while words + (setq word (car words) + words (cdr words)) + (setq list (cons (list (downcase word) word) list))) + + (define-abbrev-table 'basic-mode-abbrev-table list)))) + +(basic-construct-keyword-abbrev-table) + + +(defun basic-in-code-context-p () + (if (fboundp 'buffer-syntactic-context) ; XEmacs function. + (null (buffer-syntactic-context)) + ;; Attempt to simulate buffer-syntactic-context + ;; I don't know how reliable this is. + (let* ((beg (save-excursion + (beginning-of-line) + (point))) + (list + (parse-partial-sexp beg (point)))) + (and (null (nth 3 list)) ; inside string. + (null (nth 4 list)))))) ; inside cocmment + +(defun basic-pre-abbrev-expand-hook () + ;; Allow our abbrevs only in a code context. + (setq local-abbrev-table + (if (basic-in-code-context-p) + basic-mode-abbrev-table))) + + + +(defun basic-newline-and-indent (&optional count) + "Insert a newline, updating indentation." + (interactive) + (expand-abbrev) + (basic-indent-line) + (call-interactively 'newline-and-indent)) + +(defun basic-beginning-of-defun () + (interactive) + (re-search-backward basic-defun-start-regexp)) + +(defun basic-end-of-defun () + (interactive) + (re-search-forward basic-defun-end-regexp)) + +(defun basic-mark-defun () + (interactive) + (beginning-of-line) + (basic-end-of-defun) + (set-mark (point)) + (basic-beginning-of-defun) + (if basic-xemacs-p + (zmacs-activate-region))) + +(defun basic-indent-defun () + (interactive) + (save-excursion + (basic-mark-defun) + (call-interactively 'basic-indent-region))) + + +(defun basic-fill-long-comment () + "Fills block of comment lines around point." + ;; Derived from code in ilisp-ext.el. + (interactive) + (save-excursion + (beginning-of-line) + (let ((comment-re "^[ \t]*\\s<+[ \t]*")) + (if (looking-at comment-re) + (let ((fill-prefix + (buffer-substring + (progn (beginning-of-line) (point)) + (match-end 0)))) + + (while (and (not (bobp)) + (looking-at basic-comment-regexp)) + (forward-line -1)) + (if (not (bobp)) (forward-line 1)) + + (let ((start (point))) + + ;; Make all the line prefixes the same. + (while (and (not (eobp)) + (looking-at comment-re)) + (replace-match fill-prefix) + (forward-line 1)) + + (if (not (eobp)) + (beginning-of-line)) + + ;; Fill using fill-prefix + (fill-region-as-paragraph start (point)))))))) + + +(defun basic-fill-or-indent () + "Fill long comment around point, if any, else indent current definition." + (interactive) + (cond ((save-excursion + (beginning-of-line) + (looking-at basic-comment-regexp)) + (basic-fill-long-comment)) + (t + (basic-indent-defun)))) + + +(defun basic-new-sub () + "Insert template for a new subroutine. Repeat to cycle through alternatives." + (interactive) + (beginning-of-line) + (let ((templates (cons basic-blank-regexp + basic-defn-templates)) + (tem nil) + (bound (point))) + (while templates + (setq tem (car templates) + templates (cdr templates)) + (cond ((looking-at tem) + (replace-match (or (car templates) + "")) + (setq templates nil)))) + + (search-backward "()" bound t))) + + +(defun basic-untabify () + "Do not allow any tabs into the file" + (if (eq major-mode 'basic-mode) + (untabify (point-min) (point-max))) + nil) + +(defun basic-default-tag () + (if (and (not (bobp)) + (save-excursion + (backward-char 1) + (looking-at "\\w"))) + (backward-word 1)) + (let ((s (point)) + (e (save-excursion + (forward-word 1) + (point)))) + (buffer-substring s e))) + +(defun basic-grep (tag) + "Search BASIC source files in current directory for tag." + (interactive + (list (let* ((def (basic-default-tag)) + (tag (read-string + (format "Grep for [%s]: " def)))) + (if (string= tag "") def tag)))) + + (grep (format "grep -n %s %s" tag basic-wild-files))) + + + +(defun basic-start-ide () + "Start Visual Basic (or your favorite IDE, (after Emacs, of course)) +on the project file in the current directory. +Note: it's not a good idea to leave Visual Basic running while you +are editing in emacs, since Visual Basic has no provision for reloading +changed files." + (interactive) + (let (file) + (cond ((not (fboundp 'win-exec)) + (error "Not available")) + ((null basic-ide-pathname) + (error "No pathname set for Visual Basic. See basic-ide-pathname")) + ((setq file (car (directory-files (pwd) t "\\.vbp"))) + (iconify-emacs) + (win-exec basic-ide-pathname 'win-show-normal file)) + (t + (error "No project file found."))))) + + + +;;; Indentation-related stuff. + +(defun basic-indent-region (start end) + "Perform basic-indent-line on each line in region." + (interactive "r") + (save-excursion + (goto-char start) + (beginning-of-line) + (while (and (not (eobp)) + (< (point) end)) + (if (not (looking-at basic-blank-regexp)) + (basic-indent-line)) + (forward-line 1))) + + (cond ((fboundp 'zmacs-deactivate-region) + (zmacs-deactivate-region)) + ((fboundp 'deactivate-mark) + (deactivate-mark)))) + + + +(defun basic-previous-line-of-code () + (if (not (bobp)) + (forward-line -1)) ; previous-line depends on goal column + (while (and (not (bobp)) + (or (looking-at basic-blank-regexp) + (looking-at basic-comment-regexp))) + (forward-line -1))) + + +(defun basic-find-original-statement () + ;; If the current line is a continuation from the previous, move + ;; back to the original stmt. + (let ((here (point))) + (basic-previous-line-of-code) + (while (and (not (bobp)) + (looking-at basic-continuation-regexp)) + (setq here (point)) + (basic-previous-line-of-code)) + (goto-char here))) + +(defun basic-find-matching-stmt (open-regexp close-regexp) + ;; Searching backwards + (let ((level 0)) + (while (and (>= level 0) (not (bobp))) + (basic-previous-line-of-code) + (basic-find-original-statement) + (cond ((looking-at close-regexp) + (setq level (+ level 1))) + ((looking-at open-regexp) + (setq level (- level 1))))))) + +(defun basic-find-matching-if () + (basic-find-matching-stmt basic-if-regexp basic-endif-regexp)) + +(defun basic-find-matching-select () + (basic-find-matching-stmt basic-select-regexp basic-select-end-regexp)) + +(defun basic-find-matching-for () + (basic-find-matching-stmt basic-for-regexp basic-next-regexp)) + +(defun basic-find-matching-do () + (basic-find-matching-stmt basic-do-regexp basic-loop-regexp)) + +(defun basic-find-matching-while () + (basic-find-matching-stmt basic-while-regexp basic-wend-regexp)) + +(defun basic-find-matching-with () + (basic-find-matching-stmt basic-with-regexp basic-end-with-regexp)) + + +(defun basic-calculate-indent () + (let ((original-point (point))) + (save-excursion + (beginning-of-line) + ;; Some cases depend only on where we are now. + (cond ((or (looking-at basic-defun-start-regexp) + (looking-at basic-label-regexp) + (looking-at basic-defun-end-regexp)) + 0) + + ;; The outdenting stmts, which simply match their original. + ((or (looking-at basic-else-regexp) + (looking-at basic-endif-regexp)) + (basic-find-matching-if) + (current-indentation)) + + ;; All the other matching pairs act alike. + ((looking-at basic-next-regexp) ; for/next + (basic-find-matching-for) + (current-indentation)) + + ((looking-at basic-loop-regexp) ; do/loop + (basic-find-matching-do) + (current-indentation)) + + ((looking-at basic-wend-regexp) ; while/wend + (basic-find-matching-while) + (current-indentation)) + + ((looking-at basic-with-regexp) ; with/end with + (basic-find-matching-with) + (current-indentation)) + + ((looking-at basic-select-end-regexp) ; select case/end select + (basic-find-matching-select) + (current-indentation)) + + ;; A case of a select is somewhat special. + ((looking-at basic-case-regexp) + (basic-find-matching-select) + (+ (current-indentation) basic-mode-indent)) + + (t + ;; Other cases which depend on the previous line. + (basic-previous-line-of-code) + + ;; Skip over label lines, which always have 0 indent. + (while (looking-at basic-label-regexp) + (basic-previous-line-of-code)) + + (cond + ((looking-at basic-continuation-regexp) + (basic-find-original-statement) + ;; Indent continuation line under matching open paren, + ;; or else one word in. + (let* ((orig-stmt (point)) + (matching-open-paren + (condition-case () + (save-excursion + (goto-char original-point) + (beginning-of-line) + (backward-up-list 1) + ;; Only if point is now w/in cont. block. + (if (<= orig-stmt (point)) + (current-column))) + (error nil)))) + (cond (matching-open-paren + (1+ matching-open-paren)) + (t + ;; Else, after first word on original line. + (back-to-indentation) + (forward-word 1) + (while (looking-at "[ \t]") + (forward-char 1)) + (current-column))))) + (t + (basic-find-original-statement) + (let ((indent (current-indentation))) + ;; All the various +indent regexps. + (cond ((looking-at basic-defun-start-regexp) + (+ indent basic-mode-indent)) + + ((or (looking-at basic-if-regexp) + (looking-at basic-else-regexp)) + (+ indent basic-mode-indent)) + + ((or (looking-at basic-select-regexp) + (looking-at basic-case-regexp)) + (+ indent basic-mode-indent)) + + ((or (looking-at basic-do-regexp) + (looking-at basic-for-regexp) + (looking-at basic-while-regexp) + (looking-at basic-with-regexp)) + (+ indent basic-mode-indent)) + + (t + ;; By default, just copy indent from prev line. + indent)))))))))) + +(defun basic-indent-to-column (col) + (let* ((bol (save-excursion + (beginning-of-line) + (point))) + (point-in-whitespace + (<= (point) (+ bol (current-indentation)))) + (blank-line-p + (save-excursion + (beginning-of-line) + (looking-at basic-blank-regexp)))) + + (cond ((/= col (current-indentation)) + (save-excursion + (beginning-of-line) + (back-to-indentation) + (delete-region bol (point)) + (indent-to col)))) + + ;; If point was in the whitespace, move back-to-indentation. + (cond (blank-line-p + (end-of-line)) + (point-in-whitespace + (back-to-indentation))))) + +(defun basic-indent-line () + "Indent current line for BASIC" + (interactive) + (basic-indent-to-column (basic-calculate-indent))) diff --git a/emacs/cldoc.el b/emacs/cldoc.el new file mode 100644 index 0000000..9e4086f --- /dev/null +++ b/emacs/cldoc.el @@ -0,0 +1,1538 @@ +;;; cldoc.el --- show Common Lisp operators and variables information in echo area + +;; Copyright (C) 1996, 97, 98, 99, 2000 Free Software Foundation, Inc. +;; Copyright (C) 2004 Yuji Minejima + +;; This program (cldoc.el) is based on eldoc.el. +;; Eldoc Author: Noah Friedman +;; Keywords: extensions + +;; $Id: cldoc.el,v 1.16 2004/12/01 02:06:43 yuji Exp $ + +;; This file is not part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; cldoc.el is basically an eldoc clone for Common Lisp. +;; The following comment is from eldoc.el +;; > This program was inspired by the behavior of the "mouse documentation +;; > window" on many Lisp Machine systems; as you type a function's symbol +;; > name as part of a sexp, it will print the argument list for that +;; > function. Behavior is not identical; for example, you need not actually +;; > type the function name, you need only move point around in a sexp that +;; > calls it. Also, if point is over a documented variable, it will print +;; > the one-line documentation for that variable instead, to remind you of +;; > that variable's meaning. +;; +;; cldoc.el has a database of parameters and results of Common Lisp's standard +;; functions, and syntax rules of standard macros and special operators. +;; cldoc.el automatically uses SLIME's autodoc facility if available to display +;; parameters of user defined functions and macros, and the values of global +;; variables. + + +;; One useful way to enable this minor mode is to put the following in your +;; .emacs: +;; +;; ;; all users +;; (autoload 'turn-on-cldoc-mode "cldoc" nil t) +;; (add-hook 'lisp-mode-hook 'turn-on-cldoc-mode) +;; +;; ;; ilisp users +;; (add-hook 'ilisp-mode-hook 'turn-on-cldoc-mode) +;; (setq ilisp-bindings-*bind-space-p* nil) +;; +;; ;; slime users +;; (add-hook 'slime-repl-mode-hook +;; #'(lambda () +;; (turn-on-cldoc-mode) +;; (define-key slime-repl-mode-map " " nil))) +;; (add-hook 'slime-mode-hook +;; #'(lambda () (define-key slime-mode-map " " nil))) +;; (setq slime-use-autodoc-mode nil) + +;; todo +;; * handling of operators with multiple syntax rules (e.g. file-position). +;; * handling of operators which implementations are allowed to extend +;; (e.g. directory) + + +;;; Code: +(require 'cl) + +;; Use idle timers if available in the version of emacs running. +;; Please don't change this to use `require'; this package works +;; as-is in XEmacs 19.14 and later and I am striving to maintain +;; compatibility between emacs variants. +(or (featurep 'timer) + (load "timer" t)) + +(defgroup cldoc nil + "Show function arglist or variable docstring in echo area." + :group 'lisp + :group 'extensions) + +;;;###autoload +(defcustom cldoc-mode nil + "*If non-nil, show the defined parameters for the elisp function near point. + +For the emacs lisp function at the beginning of the sexp which point is +within, show the defined parameters for the function in the echo area. +This information is extracted directly from the function or macro if it is +in pure lisp. If the emacs function is a subr, the parameters are obtained +from the documentation string if possible. + +If point is over a documented variable, print that variable's docstring +instead. + +This variable is buffer-local." + :type 'boolean + :group 'cldoc) +(make-variable-buffer-local 'cldoc-mode) + +(defcustom cldoc-idle-delay 0.50 + "*Number of seconds of idle time to wait before printing. +If user input arrives before this interval of time has elapsed after the +last input, no documentation will be printed. + +If this variable is set to 0, no idle time is required." + :type 'number + :group 'cldoc) + +;;;###autoload +(defcustom cldoc-minor-mode-string " Cldoc" + "*String to display in mode line when Cldoc Mode is enabled." + :type 'string + :group 'cldoc) + +(defcustom cldoc-argument-case 'upcase + "Case to display argument names of functions, as a symbol. +This has two preferred values: `upcase' or `downcase'. +Actually, any name of a function which takes a string as an argument and +returns another string is acceptable." + :type '(radio (function-item upcase) + (function-item downcase) + function) + :group 'cldoc) + +(defcustom cldoc-echo-area-use-multiline-p 'truncate-sym-name-if-fit + "*Allow long cldoc messages to resize echo area display. +If value is `t', never attempt to truncate messages; complete symbol name +and function arglist or 1-line variable documentation will be displayed +even if echo area must be resized to fit. + +If value is any non-nil value other than `t', symbol name may be truncated +if it will enable the function arglist or documentation string to fit on a +single line without resizing window. Otherwise, behavior is just like +former case. + +If value is nil, messages are always truncated to fit in a single line of +display in the echo area. Function or variable symbol name may be +truncated to make more of the arglist or documentation string visible. + +Non-nil values for this variable have no effect unless +`cldoc-echo-area-multiline-supported-p' is non-nil." + :type '(radio (const :tag "Always" t) + (const :tag "Never" nil) + (const :tag "Yes, but truncate symbol names if it will\ + enable argument list to fit on one line" truncate-sym-name-if-fit)) + :group 'cldoc) + +;;; No user options below here. + +;; Non-nil if this version of emacs supports dynamically resizable echo areas. +(defvar cldoc-echo-area-multiline-supported-p + (and (string-lessp "21" emacs-version) + (save-match-data + (numberp (string-match "^GNU Emacs" (emacs-version)))))) + +;; Commands after which it is appropriate to print in the echo area. +;; Cldoc does not try to print function arglists, etc. after just any command, +;; because some commands print their own messages in the echo area and these +;; functions would instantly overwrite them. But self-insert-command as well +;; as most motion commands are good candidates. +;; This variable contains an obarray of symbols; do not manipulate it +;; directly. Instead, use `cldoc-add-command' and `cldoc-remove-command'. +(defvar cldoc-message-commands nil) + +;; This is used by cldoc-add-command to initialize cldoc-message-commands +;; as an obarray. +;; It should probably never be necessary to do so, but if you +;; choose to increase the number of buckets, you must do so before loading +;; this file since the obarray is initialized at load time. +;; Remember to keep it a prime number to improve hash performance. +(defvar cldoc-message-commands-table-size 31) + +;; Bookkeeping; elements are as follows: +;; 0 - contains the last symbol read from the buffer. +;; 1 - contains the string last displayed in the echo area for that +;; symbol, so it can be printed again if necessary without reconsing. +;; 2 - 'function if function args, 'variable if variable documentation. +(defvar cldoc-last-data (make-vector 3 nil)) +(defvar cldoc-last-message nil) + +;; Idle timers are supported in Emacs 19.31 and later. +(defvar cldoc-use-idle-timer-p (fboundp 'run-with-idle-timer)) + +;; cldoc's timer object, if using idle timers +(defvar cldoc-timer nil) + +;; idle time delay currently in use by timer. +;; This is used to determine if cldoc-idle-delay is changed by the user. +(defvar cldoc-current-idle-delay cldoc-idle-delay) + +;; Put minor mode string on the global minor-mode-alist. +;;;###autoload +(cond ((fboundp 'add-minor-mode) + (add-minor-mode 'cldoc-mode 'cldoc-minor-mode-string)) + ((assq 'cldoc-mode (default-value 'minor-mode-alist))) + (t + (setq-default minor-mode-alist + (append (default-value 'minor-mode-alist) + '((cldoc-mode cldoc-minor-mode-string)))))) + + +;;;###autoload +(defun cldoc-mode (&optional prefix) + "*Enable or disable cldoc mode. +See documentation for the variable of the same name for more details. + +If called interactively with no prefix argument, toggle current condition +of the mode. +If called with a positive or negative prefix argument, enable or disable +the mode, respectively." + (interactive "P") + (setq cldoc-last-message nil) + (cond (cldoc-use-idle-timer-p + (add-hook 'post-command-hook 'cldoc-schedule-timer) + (add-hook 'pre-command-hook 'cldoc-pre-command-refresh-echo-area)) + (t + ;; Use post-command-idle-hook if defined, otherwise use + ;; post-command-hook. The former is only proper to use in Emacs + ;; 19.30; that is the first version in which it appeared, but it + ;; was obsolesced by idle timers in Emacs 19.31. + (add-hook (if (boundp 'post-command-idle-hook) + 'post-command-idle-hook + 'post-command-hook) + 'cldoc-print-current-symbol-info t t) + ;; quick and dirty hack for seeing if this is XEmacs + (and (fboundp 'display-message) + (add-hook 'pre-command-hook + 'cldoc-pre-command-refresh-echo-area t t)))) + (setq cldoc-mode (if prefix + (>= (prefix-numeric-value prefix) 0) + (not cldoc-mode))) + (and (interactive-p) + (if cldoc-mode + (message "cldoc-mode is enabled") + (message "cldoc-mode is disabled"))) + (when (and cldoc-mode (and (boundp 'slime-autodoc-mode) slime-autodoc-mode)) + (slime-autodoc-mode -1)) + cldoc-mode) + +;;;###autoload +(defun turn-on-cldoc-mode () + "Unequivocally turn on cldoc-mode (see variable documentation)." + (interactive) + (cldoc-mode 1)) + + +;; Idle timers are part of Emacs 19.31 and later. +(defun cldoc-schedule-timer () + (or (and cldoc-timer + (memq cldoc-timer timer-idle-list)) + (setq cldoc-timer + (run-with-idle-timer cldoc-idle-delay t + 'cldoc-print-current-symbol-info))) + + ;; If user has changed the idle delay, update the timer. + (cond ((not (= cldoc-idle-delay cldoc-current-idle-delay)) + (setq cldoc-current-idle-delay cldoc-idle-delay) + (timer-set-idle-time cldoc-timer cldoc-idle-delay t)))) + +(defun cldoc-message (&rest args) + (let ((omessage cldoc-last-message)) + (cond ((eq (car args) cldoc-last-message)) + ((or (null args) + (null (car args))) + (setq cldoc-last-message nil)) + ;; If only one arg, no formatting to do so put it in + ;; cldoc-last-message so eq test above might succeed on + ;; subsequent calls. + ((null (cdr args)) + (setq cldoc-last-message (car args))) + (t + (setq cldoc-last-message (apply 'format args)))) + ;; In emacs 19.29 and later, and XEmacs 19.13 and later, all messages + ;; are recorded in a log. Do not put cldoc messages in that log since + ;; they are Legion. + (cond ((fboundp 'display-message) + ;; XEmacs 19.13 way of preventing log messages. + (cond (cldoc-last-message + (display-message 'no-log cldoc-last-message)) + (omessage + (clear-message 'no-log)))) + (t + ;; Emacs way of preventing log messages. + (let ((message-log-max nil)) + (cond (cldoc-last-message + (message "%s" cldoc-last-message)) + (omessage + (message nil))))))) + cldoc-last-message) + +;; This function goes on pre-command-hook for XEmacs or when using idle +;; timers in Emacs. Motion commands clear the echo area for some reason, +;; which make cldoc messages flicker or disappear just before motion +;; begins. This function reprints the last cldoc message immediately +;; before the next command executes, which does away with the flicker. +;; This doesn't seem to be required for Emacs 19.28 and earlier. +(defun cldoc-pre-command-refresh-echo-area () + (and cldoc-last-message + (if (cldoc-display-message-no-interference-p) + (cldoc-message cldoc-last-message) + (setq cldoc-last-message nil)))) + +;; Decide whether now is a good time to display a message. +(defun cldoc-display-message-p () + (and (cldoc-display-message-no-interference-p) + (cond (cldoc-use-idle-timer-p + ;; If this-command is non-nil while running via an idle + ;; timer, we're still in the middle of executing a command, + ;; e.g. a query-replace where it would be annoying to + ;; overwrite the echo area. + (and (not this-command) + (symbolp last-command) + (intern-soft (symbol-name last-command) + cldoc-message-commands))) + (t + ;; If we don't have idle timers, this function is + ;; running on post-command-hook directly; that means the + ;; user's last command is still on `this-command', and we + ;; must wait briefly for input to see whether to do display. + (and (symbolp this-command) + (intern-soft (symbol-name this-command) + cldoc-message-commands) + (sit-for cldoc-idle-delay)))))) + +;; Check various conditions about the current environment that might make +;; it undesirable to print cldoc messages right this instant. +(defun cldoc-display-message-no-interference-p () + (and cldoc-mode + (not executing-kbd-macro) + (not (and (boundp 'edebug-active) edebug-active)) + ;; Having this mode operate in an active minibuffer/echo area causes + ;; interference with what's going on there. + (not cursor-in-echo-area) + (not (eq (selected-window) (minibuffer-window))))) + + +(defun cldoc-print-current-symbol-info () + (and (cldoc-display-message-p) + (let* ((current-symbol (cldoc-current-symbol)) + (current-fnsym (cldoc-fnsym-in-current-sexp)) + (doc (cond ((eq current-symbol current-fnsym) + (or (cldoc-get-fnsym-args-string current-fnsym) + (cldoc-get-var-value current-symbol))) + (t + (or (cldoc-get-var-value current-symbol) + (cldoc-get-fnsym-args-string current-fnsym)))))) + (cldoc-message doc)))) + + +(defun cldoc-get-fnsym-signature-from-lisp-process (sym) + (cond + ((fboundp 'slime-space) + ;; from slime.el + (when (and slime-space-information-p + (slime-connected-p) + (or (not (slime-busy-p)))) + (let ((result (slime-eval + `(swank:arglist-for-echo-area '(,(symbol-name sym)))))) + (when (stringp result) (cdar (read-from-string result)))))) + ;;((fboundp 'ilisp-arglist-message-lisp-space) + ;; (cldoc-ilisp-signature)) + (t nil))) + +;; Return a string containing the function parameter list, or 1-line +;; docstring if function is a subr and no arglist is obtainable from the +;; docstring or elsewhere. +(defun cldoc-get-fnsym-args-string (sym) + (let* ((entry (intern-soft (downcase (symbol-name sym)) cl-operator-signatures)) + (signature (if (and entry (boundp entry)) + (symbol-value entry) + (cldoc-get-fnsym-signature-from-lisp-process sym)))) + (setq doc + (cond + ((null signature) nil) + ((stringp signature) + (cldoc-docstring-format-sym-doc sym signature)) + (t + (let* ((tail (member '=> signature)) + (result (cldoc-function-resultstring-format (cdr tail))) + (args (cldoc-function-argstring-format (ldiff signature tail))) + (args-and-result (if tail + (format "%s => %s" args result) + (format "%s" args)))) + (cldoc-docstring-format-sym-doc sym args-and-result))))))) + +(defun cldoc-function-resultstring-format (results) + (let (str) + (do* ((results results (cdr results)) + result) + ((endp results)) + (setq result (funcall cldoc-argument-case (symbol-name (car results)))) + (if str + (setq str (format "%s, %s" str result)) + (setq str (format "%s" result)))) + str)) + + +;; Return a string containing a brief (one-line) documentation string for +;; the variable. +(defun cldoc-get-var-value (sym) + (cond + ((fboundp 'slime-autodoc) ;; from slime.el + (let* ((name (slime-autodoc-global-at-point)) + (value (when (and name + slime-space-information-p + (slime-connected-p) + (or (not (slime-busy-p))) + (slime-global-variable-name-p name)) + (slime-eval `(swank:variable-desc-for-echo-area ,name))))) + value)) + (t nil))) + +(defun cldoc-last-data-store (symbol doc type) + (aset cldoc-last-data 0 symbol) + (aset cldoc-last-data 1 doc) + (aset cldoc-last-data 2 type)) + +;; Note that any leading `*' in the docstring (which indicates the variable +;; is a user option) is removed. +(defun cldoc-docstring-first-line (doc) + (and (stringp doc) + (substitute-command-keys + (save-match-data + (let ((start (if (string-match "^\\*" doc) (match-end 0) 0))) + (cond ((string-match "\n" doc) + (substring doc start (match-beginning 0))) + ((zerop start) doc) + (t (substring doc start)))))))) + +;; If the entire line cannot fit in the echo area, the symbol name may be +;; truncated or eliminated entirely from the output to make room for the +;; description. +(defun cldoc-docstring-format-sym-doc (sym doc) + (save-match-data + (let* ((name (symbol-name sym)) + (ea-multi (and cldoc-echo-area-multiline-supported-p + cldoc-echo-area-use-multiline-p)) + ;; Subtract 1 from window width since emacs will not write + ;; any chars to the last column, or in later versions, will + ;; cause a wraparound and resize of the echo area. + (ea-width (1- (window-width (minibuffer-window)))) + (strip (- (+ (length name) (length ": ") (length doc)) ea-width))) + (cond ((or (<= strip 0) + (eq ea-multi t) + (and ea-multi (> (length doc) ea-width))) + (format "%s: %s" sym doc)) + ((> (length doc) ea-width) + (substring (format "%s" doc) 0 ea-width)) + ((>= strip (length name)) + (format "%s" doc)) + (t + ;; Show the end of the partial symbol name, rather + ;; than the beginning, since the former is more likely + ;; to be unique given package namespace conventions. + (setq name (substring name strip)) + (format "%s: %s" name doc)))))) + + +(defun cldoc-fnsym-in-current-sexp () + (let ((p (point))) + (cldoc-beginning-of-sexp) + (prog1 + ;; Don't do anything if current word is inside a string. + (if (= (or (char-after (1- (point))) 0) ?\") + nil + (cldoc-current-symbol)) + (goto-char p)))) + +(defun cldoc-beginning-of-sexp () + (let ((parse-sexp-ignore-comments t)) + (condition-case err + (while (progn + (forward-sexp -1) + (or (= (or (char-after (1- (point)))) ?\") + (> (point) (point-min))))) + (error nil)))) + +(defun cldoc-current-symbol () + (let ((c (char-after (point)))) + (and c + (memq (char-syntax c) '(?w ?_)) + (intern (current-word))))) + +;; Do indirect function resolution if possible. +(defun cldoc-symbol-function (fsym) + (let ((defn (and (fboundp fsym) + (symbol-function fsym)))) + (and (symbolp defn) + (condition-case err + (setq defn (indirect-function fsym)) + (error (setq defn nil)))) + defn)) + +(defun cldoc-function-arglist (fn) + (let* ((prelim-def (cldoc-symbol-function fn)) + (def (if (eq (car-safe prelim-def) 'macro) + (cdr prelim-def) + prelim-def)) + (arglist (cond ((null def) nil) + ((byte-code-function-p def) + (cond ((fboundp 'compiled-function-arglist) + (funcall 'compiled-function-arglist def)) + (t + (aref def 0)))) + ((eq (car-safe def) 'lambda) + (nth 1 def)) + (t t)))) + arglist)) + +(defun cldoc-function-argstring (fn) + (cldoc-function-argstring-format (cldoc-function-arglist fn))) + +(defun cldoc-function-arg-format (arg) + (typecase arg + (symbol (if (memq arg '(&allow-other-keys &aux &body &environment &key &optional + &rest &whole)) + (symbol-name arg) + (funcall cldoc-argument-case (symbol-name arg)))) + (string (if (member arg '("&allow-other-keys" "&aux" "&body" "&environment" + "&key" "&optional" "&rest" "&whole")) + arg + (funcall cldoc-argument-case (symbol-name arg)))) + (cons (cldoc-function-argstring-format arg)) + (t (format "%s" arg)))) + +(defun cldoc-function-argstring-format (arglist) + (concat "(" (mapconcat #'cldoc-function-arg-format arglist " ") ")")) + + +;; Alist of predicate/action pairs. +;; Each member of the list is a sublist consisting of a predicate function +;; used to determine if the arglist for a function can be found using a +;; certain pattern, and a function which returns the actual arglist from +;; that docstring. +;; +;; The order in this table is significant, since later predicates may be +;; more general than earlier ones. +;; +;; Compiler note for Emacs/XEmacs versions which support dynamic loading: +;; these functions will be compiled to bytecode, but can't be lazy-loaded +;; even if you set byte-compile-dynamic; to do that would require making +;; them named top-level defuns, which is not particularly desirable either. +(defvar cldoc-function-argstring-from-docstring-method-table + (list + ;; Try first searching for args starting with symbol name. + ;; This is to avoid matching parenthetical remarks in e.g. sit-for. + (list (function (lambda (doc fn) + (string-match (format "^(%s[^\n)]*)$" fn) doc))) + (function (lambda (doc) + ;; end does not include trailing ")" sequence. + (let ((end (- (match-end 0) 1))) + (if (string-match " +" doc (match-beginning 0)) + (substring doc (match-end 0) end) + ""))))) + + ;; Try again not requiring this symbol name in the docstring. + ;; This will be the case when looking up aliases. + (list (function (lambda (doc fn) + ;; save-restriction has a pathological docstring in + ;; Emacs/XEmacs 19. + (and (not (eq fn 'save-restriction)) + (string-match "^([^\n)]+)$" doc)))) + (function (lambda (doc) + ;; end does not include trailing ")" sequence. + (let ((end (- (match-end 0) 1))) + (and (string-match " +" doc (match-beginning 0)) + (substring doc (match-end 0) end)))))) + + ;; Emacs subr docstring style: + ;; (fn arg1 arg2 ...): description... + (list (function (lambda (doc fn) + (string-match "^([^\n)]+):" doc))) + (function (lambda (doc) + ;; end does not include trailing "):" sequence. + (let ((end (- (match-end 0) 2))) + (and (string-match " +" doc (match-beginning 0)) + (substring doc (match-end 0) end)))))) + + ;; XEmacs subr docstring style: + ;; "arguments: (arg1 arg2 ...) + (list (function (lambda (doc fn) + (string-match "^arguments: (\\([^\n)]+\\))" doc))) + (function (lambda (doc) + ;; also skip leading paren, but the first word is + ;; actually an argument, not the function name. + (substring doc (match-beginning 1) (match-end 1))))) + + ;; This finds the argstring for `condition-case'. Any others? + (list (function (lambda (doc fn) + (string-match + (format "^Usage looks like \\((%s[^\n)]*)\\)\\.$" fn) + doc))) + (function (lambda (doc) + ;; end does not include trailing ")" sequence. + (let ((end (- (match-end 1) 1))) + (and (string-match " +" doc (match-beginning 1)) + (substring doc (match-end 0) end)))))) + + ;; This finds the argstring for `setq-default'. Any others? + (list (function (lambda (doc fn) + (string-match (format "^[ \t]+\\((%s[^\n)]*)\\)$" fn) + doc))) + (function (lambda (doc) + ;; end does not include trailing ")" sequence. + (let ((end (- (match-end 1) 1))) + (and (string-match " +" doc (match-beginning 1)) + (substring doc (match-end 0) end)))))) + + ;; This finds the argstring for `start-process'. Any others? + (list (function (lambda (doc fn) + (string-match "^Args are +\\([^\n]+\\)$" doc))) + (function (lambda (doc) + (substring doc (match-beginning 1) (match-end 1))))) + + ;; These common subrs don't have arglists in their docstrings. So cheat. + (list (function (lambda (doc fn) + (memq fn '(and or list + -)))) + (function (lambda (doc) + ;; The value nil is a placeholder; otherwise, the + ;; following string may be compiled as a docstring, + ;; and not a return value for the function. + ;; In interpreted lisp form they are + ;; indistinguishable; it only matters for compiled + ;; forms. + nil + "&rest args"))) + )) + +(defun cldoc-function-argstring-from-docstring (fn) + (let ((docstring (documentation fn 'raw)) + (table cldoc-function-argstring-from-docstring-method-table) + (doc nil) + (doclist nil)) + (save-match-data + (while table + (cond ((funcall (car (car table)) docstring fn) + (setq doc (funcall (car (cdr (car table))) docstring)) + (setq table nil)) + (t + (setq table (cdr table))))) + + (cond ((not (stringp doc)) + nil) + ((string-match "&" doc) + (let ((p 0) + (l (length doc))) + (while (< p l) + (cond ((string-match "[ \t\n]+" doc p) + (setq doclist + (cons (substring doc p (match-beginning 0)) + doclist)) + (setq p (match-end 0))) + (t + (setq doclist (cons (substring doc p) doclist)) + (setq p l)))) + (cldoc-function-argstring-format (nreverse doclist)))) + (t + (concat "(" (funcall cldoc-argument-case doc) ")")))))) + + +;; When point is in a sexp, the function args are not reprinted in the echo +;; area after every possible interactive command because some of them print +;; their own messages in the echo area; the cldoc functions would instantly +;; overwrite them unless it is more restrained. +;; These functions do display-command table management. + +(defun cldoc-add-command (&rest cmds) + (or cldoc-message-commands + (setq cldoc-message-commands + (make-vector cldoc-message-commands-table-size 0))) + + (let (name sym) + (while cmds + (setq name (car cmds)) + (setq cmds (cdr cmds)) + + (cond ((symbolp name) + (setq sym name) + (setq name (symbol-name sym))) + ((stringp name) + (setq sym (intern-soft name)))) + + (and (symbolp sym) + (fboundp sym) + (set (intern name cldoc-message-commands) t))))) + +(defun cldoc-add-command-completions (&rest names) + (while names + (apply 'cldoc-add-command + (all-completions (car names) obarray 'fboundp)) + (setq names (cdr names)))) + +(defun cldoc-remove-command (&rest cmds) + (let (name) + (while cmds + (setq name (car cmds)) + (setq cmds (cdr cmds)) + + (and (symbolp name) + (setq name (symbol-name name))) + + (if (fboundp 'unintern) + (unintern name cldoc-message-commands) + (let ((s (intern-soft name cldoc-message-commands))) + (and s + (makunbound s))))))) + +(defun cldoc-remove-command-completions (&rest names) + (while names + (apply 'cldoc-remove-command + (all-completions (car names) cldoc-message-commands)) + (setq names (cdr names)))) + + +;; Prime the command list. +(cldoc-add-command-completions + "backward-" "beginning-of-" "delete-other-windows" "delete-window" + "end-of-" "forward-" "indent-for-tab-command" "goto-" "mouse-set-point" + "next-" "other-window" "previous-" "recenter" "scroll-" + "self-insert-command" "split-window-" + "up-list" "down-list") + + +(defvar cl-operator-signatures (make-vector 67 0)) + +;; note +;; these symbols are used, => =>| +(mapcar (lambda (entry) + (let ((symbol (intern (symbol-name (car entry)) cl-operator-signatures))) + (set symbol (cdr entry)))) + + '(;; evaluation and compilation + (lambda . "lambda-list [[declaration* | documentation]] form* => function") + (compile function-name-or-nil &optional lambda-expression-or-function => function warnings-p failure-p) + (eval form => result*) + (eval-when . "(situation*) form* => result*") + (load-time-value . "form &optional read-only-p => object") + (quote object => object) + (compiler-macro-function name &optional (environment nil) => function) + (define-compiler-macro . "name lambda-list [[declaration* | documentation]] form* => name") + (defmacro . "name lambda-list [[declaration* | documentation]] form* => name") + (macro-function symbol &optional (environment nil) => macro-function-or-nil) + (macroexpand form &optional (environment nil) => expansion expanded-p) + (macroexpand-1 form &optional (environment nil) => expansion expanded-p) + (define-symbol-macro . "symbol expansion => symbol") + (symbol-macrolet . "((symbol expansion)*) declaration* form* => result*") + (proclaim declaration-specifier => implementation-dependent) + (declaim . "declaration-specifier* => implementation-dependent") + (locally declaration* form* => result*) + (the value-type form => result*) + (special-operator-p symbol => generalized-boolean) + (constantp form &optional (environment nil) => generalized-boolean) + + + ;; types and classes + (coerce object result-type => result) + (deftype . "name lambda-list [[declaration* | documentation]] form* => name") + (subtypep subtype type &optional (environment nil) => subtype-p valid-p) + (typep object type-specifier &optional (environment nil) => generalized-boolean) + (type-error-datum condition => datum) + (type-error-expected-type condition => expected-type) + + + ;; data and control flow + (apply function &rest args+ => result*) + (defun . "function-name lambda-list [[declaration* | documentation]] form* => function-name") + (fdefinition function-name => definition) + (fboundp function-name => generalized-boolean) + (fmakunbound function-name => function-name) + (flet . "((function-name lambda-list [[local-declaration* | local-documentation]] local-form*)*) declaration* form* => result*") + (labels . "((function-name lambda-list [[local-declaration* | local-documentation]] local-form*)*) declaration* form* => result*") + (macrolet . "((name lambda-list [[local-declaration* | local-documentation]] local-form*)*) declaration* form* => result*") + + (funcall function &rest args => result*) + (function . "function-name-or-lambda-expression => function") + (function-lambda-expression function => lambda-expression closure-p name) + (functionp object => generalized-boolean) + (compiled-function-p object => generalized-boolean) + (defconstant . "name initial-value [documentation] => name") + (defparameter . "name initial-value [documentation] => name") + (defvar . "name [initial-value [documentation]] => name") + (destructuring-bind . "destructuring-lambda-list expression declaration* form* => result*") + (let . "({var | (var [init-form])}*) declaration* form* => result*") + (let* . "({var | (var [init-form])}*) declaration* form* => result*") + (progv . "symbols values form* => result*") + (setq . "{pair}* => result") + (psetq . "{pair}* => nil") + (block . "name-symbol form* => result*") + (catch . "tag-form form* => result*") + (go . "tag =>|") + (return-from . "name [result-form] =>|") + (return . "[result-form] =>|") + (tagbody . "{tag | statement}* => nil") + (throw . "tag-form result-form =>|") + (unwind-protect . "protected-form cleanup-form* => result*") + (not x => boolean) + (eq x y => generalized-boolean) + (eql x y => generalized-boolean) + (equal x y => generalized-boolean) + (equalp x y => generalized-boolean) + (identity object => object) + (complement function => complement-function) + (constantly value => function-constantly-returning-value) + (every predicate &rest sequences+ => generalized-boolean) + (some predicate &rest sequences+ => result) + (notevery predicate &rest sequences+ => generalized-boolean) + (notany predicate &rest sequences+ => generalized-boolean) + (and . "form* => result*") + (cond . "{(test-form form*)}* => result*") + (if . "test-form then-form [else-form] => result*") + (or . "form* => results*") + (when . "test-form form* => result*") + (unless . "test-form form* => result*") + (case . "keyform {(keys form*)}* [({otherwise | t} form*)] => result*") + (ccase . "keyplace {(keys form*)}* => result*") + (ecase . "keyform {(keys form*)}* => result*") + (typecase . "keyform {(type form*)}* [({otherwise | t} form*)] => result*") + (ctypecase . "keyplace {(type form*)}* => result*") + (etypecase . "keyform {(type form*)}* => result*") + (multiple-value-bind . "(var*) values-form declaration* form* => result*") + (multiple-value-call . "function-form form* => result*") + (multiple-value-list . "form => list") + (multiple-value-prog1 . "first-form form* => first-form-results") + (multiple-value-setq . "vars form => result") + (values &rest object => object*) + (values-list list => element*) + (nth-value . "n-form form => object") + (prog . "({var | (var [init-form])}*) declaration* {tag | statement}* => result*") + (prog* . "({var | (var [init-form])}*) declaration* {tag | statement}* => result*") + (prog1 . "first-form form* => primary-value-of-evaluated-first-form") + (prog2 . "first-form second-form form* => primary-value-of-evaluated-second-form") + (progn . "form* => result*") + (define-modify-macro . "name lambda-list function [documentation] => name") + ;;(defsetf . "access-fn update-fn [documentation] => access-fn") + ;;(defsetf . " access-fn lambda-list (store-variable*) [[declaration* | documentation]] form* => access-fn") + (define-setf-expander . "access-fn lambda-list [[declaration* | documentation]] form* => access-fn") + (get-setf-expansion place &optional (environment nil) => vars vals store-vars writer-form reader-form) + (setf . "{place newvalue}* => result*") + (psetf . "{place newvalue}* => nil") + (shiftf . "place+ newvalue => old-value-1") + (rotatef . "place* => nil") + + + ;; iteration + (do . "({var | (var [init-form [step-form]])}*) (end-test-form result-form*) declaration* {tag | statement}* => result*") + (do* . "({var | (var [init-form [step-form]])}*) (end-test-form result-form*) declaration* {tag | statement}* => result*") + (dotimes . "(var count-form [result-form]) declaration* {tag | statement}* => result*") + (dolist . "(var list-form [result-form]) declaration* {tag | statement}* => result*") + ;;(loop . "compound-form* => result*") + ;;(loop . "[name-clause] {variable-clause}* {main-clause}* => result*") + (loop-finish . " =>|") + + + ;; objects + (function-keywords method => keys allow-other-keys-p) + (ensure-generic-function function-name &key argument-precedence-order declare documentation environment generic-function-class lambda-list method-class method-combination => generic-function) + (allocate-instance class &rest initargs &key &allow-other-keys => new-instance) + (reinitialize-instance instance &rest initargs &key &allow-other-keys => instance) + (shared-initialize instance slot-names &rest initargs &key &allow-other-keys => instance) + (update-instance-for-different-class previous current &rest initargs &key &allow-other-keys => implementation-dependent) + (update-instance-for-redefined-class instance added-slots discarded-slots property-list &rest initargs &key &allow-other-keys => result*) + (change-class instance new-class &key &allow-other-keys => instance) + (slot-boundp instance slot-name => generalized-boolean) + (slot-exists-p object slot-name => generalized-boolean) + (slot-makunbound instance slot-name => instance) + (slot-missing class object slot-name operation &optional new-value => result*) + (slot-unbound class instance slot-name => result*) + (slot-value object slot-name => value) + (method-qualifiers method => qualifiers) + (no-applicable-method generic-function &rest function-arguments => result*) + (no-next-method generic-function method &rest args => result*) + (remove-method generic-function method => generic-function) + (make-instance class-designator &rest initargs &key &allow-other-keys => instance) + (make-instances-obsolete class-designator => class) + (make-load-form object &optional (environment nil) => creation-form \[initialization-form\]) + (make-load-form-saving-slots object &key slot-names (environment nil) => creation-form initialization-form) + (with-accessors . "(slot-entry*) instance-form declaration* form* => result*") + (with-slots . "({slot-name | (variable-name slot-name)}*) instance-form declaration* form* => result*") + (defclass . "class-name ({superclass-name}*) ({slot-specifier}*) [[class-option]] => new-class") + (defgeneric . "function-name gf-lambda-list [[option | {method-description}*]] => new-generic)") + (defmethod . "function-name {method-qualifier}* specialized-lambda-list [[declaration* | documentation]] form* => new-method") + (find-class symbol &optional (errorp t) environment => class) + (next-method-p => generalized-boolean) + (call-method method &optional next-method-list => result*) + (make-method form => method-object) + (call-next-method &rest args => result*) + (compute-applicable-methods generic-function function-arguments => methods) + ;;(define-method-combination . "name [[short-form-option]] => name") + ;;(define-method-combination . "name lambda-list (method-group-specifier*) [(:arguments . args-lambda-list)] [(:generic-function generic-function-symbol)] [[declaration* | documentation]] form* => name") + (find-method generic-function method-qualifiers specializers &optional (errorp t) => method) + (add-method generic-function method => generic-function) + (initialize-instance instance &rest initargs &key &allow-other-keys => instance) + (class-name class => name) + (class-of object => class) + (unbound-slot-instance condition => instance) + + ;; structures + (defstruct . "name-and-options [documentation] {slot-description}* => structure-name") + (copy-structure structure => copy) + + + ;; conditions + (cell-error-name condition => name) + (assert . "test-form [(place*) [datum-form argument-form*]] => nil") + (error datum &rest arguments =>|) + (cerror continue-format-control datum &rest arguments => nil) + (check-type . "place typespec [string] => nil") + (invalid-method-error method format-control &rest args => implementation-dependent) + (method-combination-error format-control &rest args => implementation-dependent) + (signal datum &rest arguments => nil) + (simple-condition-format-control condition => format-control) + (simple-condition-format-arguments condition => format-arguments) + (warn datum &rest arguments => nil) + (invoke-debugger condition =>|) + (break &optional (format-control *implementation-dependent-format-control*) &rest format-arguments => nil) + (handler-bind . "({(type handler)}*) form* => result*") + (handler-case . "expression [[{error-clause}* | no-error-clause]] => result* +clause::= error-clause | no-error-clause +error-clause::= (typespec ([var]) declaration* form*) +no-error-clause::= (:no-error lambda-list declaration* form*)") + (ignore-errors . "form* => result*") + (define-condition . "name (parent-type*) ({slot-spec}*) option* => name") + (make-condition type &rest slot-initializations => condition) + (compute-restarts &optional (condition nil) => restarts) + (find-restart identifier &optional (condition nil) => restart) + (invoke-restart restart-designator &rest arguments => result*) + (invoke-restart-interactively restart-designator => result*) + (restart-bind . "({(name function {key-val-pair}*)}) form* => result*") + (restart-case . "restartable-form {clause} => result*") + (restart-name restart => name) + (with-condition-restarts . "condition-form restarts-form form* => result*") + (with-simple-restart . "(name format-control format-argument*) form* => result*") + (abort &optional (condition nil) =>|) + (continue &optional (condition nil) => nil) + (muffle-warning &optional (condition nil) =>|) + (store-value value &optional (condition nil) => nil) + (use-value value &optional (condition nil) => nil) + + + ;; symbols + (symbolp object => generalized-boolean) + (keywordp object => generalized-boolean) + (make-symbol name-string => new-symbol) + (copy-symbol symbol &optional (copy-properties nil) => new-symbol) + (gensym &optional string-or-non-negative-integer => new-symbol) + (gentemp &optional (prefix "T") (package *package*) => new-symbol) + (symbol-function symbol => contents) + (symbol-name symbol => name) + (symbol-package symbol => package-or-nil) + (symbol-plist symbol => plist) + (symbol-value symbol => value) + (get symbol indicator &optional (default nil) => value) + (remprop symbol indicator => generalized-boolean) + (boundp symbol => generalized-boolean) + (makunbound symbol => symbol) + (set symbol value => value) + + + ;; packages + (export designator-for-a-list-of-symbols &optional (package *package*) => t) + (find-symbol string &optional (package *package*) => symbol status) + (find-package string-designator-or-package => package) + (find-all-symbols string-designator => symbols) + (import designator-for-a-list-of-symbols &optional (package *package*)) + (list-all-packages => packages) + (rename-package package new-name &optional (new-nicknames '()) => package-object) + (shadow symbol-names &optional (package *package*) => t) + (shadowing-import designator-for-a-list-of-symbols &optional (package *package*) => t) + (delete-package package-designator => generalized-boolean) + (make-package package-name &key (nicknames '()) (use *implementation-defined-use-list*) => package) + (with-package-iterator . "(name package-list-form &rest symbol-types) declaration* form* => result*") + (unexport designator-for-a-list-of-symbols &optional (package *package*) => t) + (unintern symbol &optional (package *package*) => generalized-boolean) + (in-package . "name => package") + (unuse-package packages-to-unuse &optional (package *package*) => t) + (use-package packages-to-use &optional (package *package*) => t) + (defpackage . "defined-package-name [[option]] => package +option::= (:nicknames nickname*)* | + (:documentation string) | + (:use package-name*)* | + (:shadow {symbol-name}*)* | + (:shadowing-import-from package-name {symbol-name}*)* | + (:import-from package-name {symbol-name}*)* | + (:export {symbol-name}*)* | + (:intern {symbol-name}*)* | + (:size integer) ") + (do-symbols . "(var [package [result-form]]) declaration* {tag | statement}* => result*") + (do-external-symbols . "(var [package [result-form]]) declaration* {tag | statement}* => result*") + (do-all-symbols . "(var [result-form]) declaration* {tag | statement}* => result*") + (intern string &optional (package *package*) => symbol status) + (package-name package-designator => name) + (package-nicknames package-designator => nicknames) + (package-shadowing-symbols package-designator => symbols) + (package-use-list package-designator => use-list) + (package-used-by-list package-designator => used-by-list) + (packagep object => generalized-boolean) + (package-error-package condition => package) + + + ;; numbers + (= &rest numbers+ => generalized-boolean) + (/= &rest numbers+ => generalized-boolean) + (< &rest numbers+ => generalized-boolean) + (> &rest numbers+ => generalized-boolean) + (<= &rest numbers+ => generalized-boolean) + (>= &rest numbers+ => generalized-boolean) + (max &rest reals+ => max-real) + (min &rest reals+ => min-real) + (minusp real => generalized-boolean) + (plusp real => generalized-boolean) + (zerop number => generalized-boolean) + (floor number &optional (divisor 1) => quotient remainder) + (ffloor number &optional (divisor 1) => quotient remainder) + (ceiling number &optional (divisor 1) => quotient remainder) + (fceiling number &optional (divisor 1) => quotient remainder) + (truncate number &optional (divisor 1) => quotient remainder) + (ftruncate number &optional (divisor 1) => quotient remainder) + (round number &optional (divisor 1) => quotient remainder) + (fround number &optional (divisor 1) => quotient remainder) + (sin radians => number) + (cos radians => number) + (tan radians => number) + (asin number => radians) + (acos number => radians) + (atan number1 &optional number2 => radians) + (sinh number => result) + (cosh number => result) + (tanh number => result) + (asinh number => result) + (acosh number => result) + (atanh number => result) + (* &rest numbers => product) + (+ &rest numbers => sum) + ;;(- number => negation) + ;;(- minuend &rest subtrahends+ => difference) + ;;(/ number => reciprocal) + ;;(/ numerator &rest denominators+ => quotient) + (1+ number => successor) + (1- number => predecessor) + (abs number => absolute-value) + (evenp integer => generalized-boolean) + (oddp integer => generalized-boolean) + (exp number => result) + (expt base-number power-number => result) + (gcd &rest integers => greatest-common-denominator) + (incf . "place [delta-form] => new-value") + (decf . "place [delta-form] => new-value") + (lcm &rest integers => least-common-multiple) + (log number &optional (base *E-base-of-the-natural-logarithms*) => logarithm) + (mod number divisor => modulus) + (rem number divisor => remainder) + (signum number => signed-prototype) + (sqrt number => root) + (isqrt natural => natural-root) + (make-random-state &optional (state nil) => new-state) + (random limit &optional (random-state *random-state*) => random-number) + (random-state-p object => generalized-boolean) + (numberp object => generalized-boolean) + (cis radians => number) + (complex realpart &optional (imagpart (coerce 0 (type-of realpart))) => complex) + (complexp object => generalized-boolean) + (conjugate number => conjugate) + (phase number => phase) + (realpart number => real) + (imagpart number => real) + (upgraded-complex-part-type typespec &optional (environment nil) => upgraded-typespec) + (realp object => generalized-boolean) + (numerator rational => numerator) + (denominator rational => denominator) + (rational number => rational) + (rationalize number => rational) + (rationalp object => generalized-boolean) + (ash integer count => shifted-integer) + (integer-length integer => number-of-bits) + (integerp object => generalized-boolean) + (parse-integer string &key (start 0) (end nil) (radix 10) junk-allowed => integer pos) + (boole op integer-1 integer-2 => result-integer) + (logand &rest integers => result-integer) + (logandc1 integer-1 integer-2 => result-integer) + (logandc2 integer-1 integer-2 => result-integer) + (logeqv &rest integers => result-integer) + (logior &rest integers => result-integer) + (lognand integer-1 integer-2 => result-integer) + (lognor integer-1 integer-2 => result-integer) + (lognot integer => result-integer) + (logorc1 integer-1 integer-2 => result-integer) + (logorc2 integer-1 integer-2 => result-integer) + (logxor &rest integers => result-integer) + (logbitp index integer => generalized-boolean) + (logcount integer => number-of-on-bits) + (logtest integer-1 integer-2 => generalized-boolean) + (byte size position => bytespec) + (byte-size bytespec => size) + (byte-position bytespec => position) + (deposit-field newbyte bytespec integer => result-integer) + (dpb newbyte bytespec integer => result-integer) + (ldb bytespec integer => byte) + (ldb-test bytespec integer => generalized-boolean) + (mask-field bytespec integer => masked-integer) + (decode-float float => significand exponent sign) + (scale-float float integer => scaled-float) + (float-radix float => float-radix) + (float-sign float-1 &optional (float-2 (float 1 float-1)) => signed-float) + (float-digits float => digits1) + (float-precision float => digits2) + (integer-decode-float float => significand exponent integer-sign) + (float number &optional prototype => float) + (floatp object) + (arithmetic-error-operands condition => operands) + (arithmetic-error-operation condition => operation) + + ;; characters + (char= &rest characters+ => generalized-boolean) + (char/= &rest characters+ => generalized-boolean) + (char< &rest characters+ => generalized-boolean) + (char> &rest characters+ => generalized-boolean) + (char<= &rest characters+ => generalized-boolean) + (char>= &rest characters+ => generalized-boolean) + (char-equal &rest characters+ => generalized-boolean) + (char-not-equal &rest characters+ => generalized-boolean) + (char-lessp &rest characters+ => generalized-boolean) + (char-greaterp &rest characters+ => generalized-boolean) + (char-not-greaterp &rest characters+ => generalized-boolean) + (char-not-lessp &rest characters+ => generalized-boolean) + (character character-designator => denoted-character) + (characterp object => generalized-boolean) + (alpha-char-p character => generalized-boolean) + (alphanumericp character => generalized-boolean) + (digit-char weight &optional (radix 10) => char) + (digit-char-p char &optional (radix 10) => weight) + (graphic-char-p char => generalized-boolean) + (standard-char-p character => generalized-boolean) + (char-upcase character => corresponding-character) + (char-downcase character => corresponding-character) + (upper-case-p character => generalized-boolean) + (lower-case-p character => generalized-boolean) + (both-case-p character => generalized-boolean) + (char-code character => code) + (char-int character => integer) + (code-char code => char-p) + (char-name character => name) + (name-char name => character-or-nil) + + + ;; conses + (cons car cdr => cons) + (consp object => generalized-boolean) + (atom object => generalized-boolean) + (rplaca cons object => cons) + (rplacd cons object => cons) + (car list => car-of-list) + (cdr list => cdr-of-list) + (copy-tree tree => new-tree) + (sublis alist tree &key key test test-not => new-tree) + (nsublis alist tree &key key test test-not => new-tree) + (subst new old tree &key key test test-not => new-tree) + (subst-if new predicate tree &key key => new-tree) + (subst-if-not new predicate tree &key key => new-tree) + (nsubst new old tree &key key test test-not => new-tree) + (nsubst-if new predicate tree &key key => new-tree) + (nsubst-if-not new predicate tree &key key => new-tree) + (tree-equal tree-1 tree-2 &key test test-not => generalized-boolean) + (copy-list list => copy) + (list &rest objects => list) + (list* &rest objects+ => result) + (list-length list => length) + (listp object => generalized-boolean) + (make-list size &key (initial-element nil) => list) + (push . "item place => new-place-value") + (pop . "place => element") + (nth n list => object) + (endp list => generalized-boolean) + (null object => boolean) + (nconc &rest lists => concatenated-list) + (append &rest lists => result) + (revappend list tail => result-list) + (nreconc list tail => result-list) + (butlast list &optional (n 1) => result-list) + (nbutlast list &optional (n 1) => result-list) + (last list &optional (n 1) => tail) + (ldiff list possible-tail => result-list) + (tailp possible-tail list => generalized-boolean) + (nthcdr n list => tail) + (rest list => tail) + (member item list &key key test test-not => tail) + (member-if predicate list &key key => tail) + (member-if-not predicate list &key key => tail) + (mapc function &rest lists+ => list-1) + (mapcar function &rest lists+ => result-list) + (mapcan function &rest lists+ => concatenated-results) + (mapl function &rest lists+ => list-1) + (maplist function &rest lists+ => result-list) + (mapcon function &rest lists+ => concatenated-results) + (acons key datum alist => new-alist) + (assoc item alist &key key test test-not => entry) + (assoc-if predicate alist &key key => entry) + (assoc-if-not predicate alist &key key => entry) + (copy-alist alist => new-alist) + (pairlis keys data &optional (alist '()) => new-alist) + (rassoc item alist &key key test test-not => entry) + (rassoc-if predicate alist &key key => entry) + (rassoc-if-not predicate alist &key key => entry) + (get-properties plist indicator-list => indicator value tail) + (getf plist indicator &optional (default nil) => value) + (remf place indicator => generalized-boolean) + (intersection list-1 list-2 &key key test test-not => result-list) + (nintersection list-1 list-2 &key key test test-not => result-list) + (adjoin item list &key key test test-not => new-list) + (pushnew item place &key key test test-not => new-place-value) + (set-difference list-1 list-2 &key key test test-not => result-list) + (nset-difference list-1 list-2 &key key test test-not => result-list) + (set-exclusive-or list-1 list-2 &key key test test-not => result-list) + (nset-exclusive-or list-1 list-2 &key key test test-not => result-list) + (subsetp list-1 list-2 &key key test test-not => generalized-boolean) + (union list-1 list-2 &key key test test-not => result-list) + (nunion list-1 list-2 &key key test test-not => result-list) + + ;; arrays + (make-array dimensions &key (element-type t) initial-element initial-contents (adjustable nil) (fill-pointer nil) (displaced-to nil) (displaced-index-offset 0) => new-array) + (adjust-array array new-dimensions &key element-type initial-element initial-contents (fill-pointer nil) displaced-to displaced-index-offset => adjusted-array) + (adjustable-array-p array => generalized-boolean) + (aref array &rest subscripts => element) + (array-dimension array axis-number => dimension) + (array-dimensions array => dimensions) + (array-element-type array => typespec) + (array-has-fill-pointer-p array => generalized-boolean) + (array-displacement array => displaced-to displaced-index-offset) + (array-in-bounds-p array &rest subscripts => generalized-boolean) + (array-rank array => rank) + (array-row-major-index array &rest subscripts => index) + (array-total-size array => size) + (arrayp object => generalized-boolean) + (fill-pointer vector => fill-pointer) + (row-major-aref array index => element) + (upgraded-array-element-type typespec &optional (environment nil) => upgraded-typespec) + (simple-vector-p object => generalized-boolean) + (svref simple-vector index => element) + (vector &rest objects => vector) + (vector-pop vector => element) + (vector-push new-element vector => new-index-p) + (vector-push-extend new-element vector &optional (extension *implementation-dependent-extension*) => new-index) + (vectorp object => generalized-boolean) + (bit bit-array &rest subscripts => bit) + (sbit bit-array &rest subscripts => bit) + (bit-and bit-array1 bit-array2 &optional (opt-arg nil) => resulting-bit-array) + (bit-andc1 bit-array1 bit-array2 &optional (opt-arg nil) => resulting-bit-array) + (bit-andc2 bit-array1 bit-array2 &optional (opt-arg nil) => resulting-bit-array) + (bit-eqv bit-array1 bit-array2 &optional (opt-arg nil) => resulting-bit-array) + (bit-ior bit-array1 bit-array2 &optional (opt-arg nil) => resulting-bit-array) + (bit-nand bit-array1 bit-array2 &optional (opt-arg nil) => resulting-bit-array) + (bit-nor bit-array1 bit-array2 &optional (opt-arg nil) => resulting-bit-array) + (bit-orc1 bit-array1 bit-array2 &optional (opt-arg nil) => resulting-bit-array) + (bit-orc2 bit-array1 bit-array2 &optional (opt-arg nil) => resulting-bit-array) + (bit-xor bit-array1 bit-array2 &optional (opt-arg nil) => resulting-bit-array) + (bit-not bit-array &optional (opt-arg nil) => resulting-bit-array) + (bit-vector-p object => generalized-boolean) + (simple-bit-vector-p object => generalized-boolean) + + + ;; strings + (simple-string-p object => generalized-boolean) + (char string index => character) + (schar simple-string index => character) + (string string-or-symbol-or-character => string) + (string-upcase string-designator &key (start 0) (end nil) => cased-string) + (string-downcase string-designator &key (start 0) (end nil) => cased-string) + (string-capitalize string-designator &key (start 0) (end nil) => cased-string) + (nstring-upcase string &key (start 0) (end nil) => modified-string) + (nstring-downcase string &key (start 0) (end nil) => modified-string) + (nstring-capitalize string &key (start 0) (end nil) => modified-string) + + (string-trim character-bag string => trimmed-string) + (string-left-trim character-bag string => trimmed-string) + (string-right-trim character-bag string => trimmed-string) + (string= string1 string2 &key (start1 0) (end1 nil) (start2 0) (end2 nil) => generalized-boolean) + (string/= string1 string2 &key (start1 0) (end1 nil) (start2 0) (end2 nil) => mismatch-index) + (string< string1 string2 &key (start1 0) (end1 nil) (start2 0) (end2 nil) => mismatch-index) + (string> string1 string2 &key (start1 0) (end1 nil) (start2 0) (end2 nil) => mismatch-index) + (string<= string1 string2 &key (start1 0) (end1 nil) (start2 0) (end2 nil) => mismatch-index) + (string>= string1 string2 &key (start1 0) (end1 nil) (start2 0) (end2 nil) => mismatch-index) + (string-equal string1 string2 &key (start1 0) (end1 nil) (start2 0) (end2 nil) => generalized-boolean) + (string-not-equal string1 string2 &key (start1 0) (end1 nil) (start2 0) (end2 nil) => mismatch-index) + (string-lessp string1 string2 &key (start1 0) (end1 nil) (start2 0) (end2 nil) => mismatch-index) + (string-greaterp string1 string2 &key (start1 0) (end1 nil) (start2 0) (end2 nil) => mismatch-index) + (string-not-greaterp string1 string2 &key (start1 0) (end1 nil) (start2 0) (end2 nil) => mismatch-index) + (string-not-lessp string1 string2 &key (start1 0) (end1 nil) (start2 0) (end2 nil) => mismatch-index) + (stringp object => generalized-boolean) + (make-string size &key (initial-element *implementation-dependent-character*) (element-type 'character) => string) + + + ;; sequences + (copy-seq proper-sequence => copied-sequence) + (elt proper-sequence index => object) + (fill proper-sequence item &key (start 0) (end nil) => sequence) ; + (make-sequence result-type size &key (initial-element *implementation-dependent-element*) => sequence) + (subseq sequence start &optional (end nil) => subsequence) + (map result-sequence-type function &rest sequences+ => result) + (map-into result-sequence function &rest sequences => result-sequence) + (reduce function sequence &key key (from-end nil) (start 0) (end nil) initial-value => result) + (count item sequence &key (from-end nil) (start 0) (end nil) key test test-not => n) + (count-if predicate sequence &key (from-end nil) (start 0) (end nil) key => n) + (count-if-not predicate sequence &key (from-end nil) (start 0) (end nil) key => n) + (length sequence => n) + (reverse sequence => reversed-sequence) + (nreverse sequence => reversed-sequence) + (sort sequence predicate &key key => destructively-sorted-sequence) + (stable-sort sequence predicate &key key => destructively-sorted-sequence) + (find item sequence &key (from-end nil) test test-not (start 0) (end nil) key => element) + (find-if predicate sequence &key (from-end nil) (start 0) (end nil) key => element) + (find-if-not predicate sequence &key (from-end nil) (start 0) (end nil) key => element) + (position item sequence &key (from-end nil) test test-not (start 0) (end nil) key => position) + (position-if predicate sequence &key (from-end nil) (start 0) (end nil) key => position) + (position-if-not predicate sequence &key (from-end nil) (start 0) (end nil) key => position) + (search subsequence sequence &key (from-end nil) test test-not key (start1 0) (start2 0) (end1 nil) (end2 nil) => position) + (mismatch sequence-1 sequence-2 &key (from-end nil) test test-not key (start1 0) (start2 0) (end1 nil) (end2 nil) => position) + (replace sequence-1 sequence-2 &key (start1 0) (end1 nil) (start2 0) (end2 nil) => destructively-modified-sequence-1) + (substitute newitem olditem sequence &key (from-end nil) test test-not (start 0) (end nil) (count nil) key => result-sequence) + (substitute-if newitem predicate sequence &key (from-end nil) (start 0) (end nil) (count nil) key => result-sequence) + (substitute-if-not newitem predicate sequence &key (from-end nil) (start 0) (end nil) (count nil) key => result-sequence) + (nsubstitute newitem olditem sequence &key (from-end nil) test test-not (start 0) (end nil) (count nil) key => sequence) + (nsubstitute-if newitem predicate sequence &key (from-end nil) (start 0) (end nil) (count nil) key=> sequence) + (nsubstitute-if-not newitem predicate sequence &key (from-end nil) (start 0) (end nil) (count nil) key => sequence) + (concatenate result-type &rest sequences => result-sequence) + (merge result-type sequence-1 sequence-2 predicate &key key => result-sequence) + (remove item sequence &key (from-end nil) test test-not (start 0) (end nil) (count nil) key => result-sequence) + (remove-if test sequence &key (from-end nil) (start 0) (end nil) (count nil) key => result-sequence) + (remove-if-not test sequence &key (from-end nil) (start 0) (end nil) (count nil) key => result-sequence) + (delete item sequence &key (from-end nil) test test-not (start 0) (end nil) (count nil) key => result-sequence) + (delete-if test sequence &key (from-end nil) (start 0) (end nil) (count nil) key => result-sequence) + (delete-if-not test sequence &key (from-end nil) (start 0) (end nil) (count nil) key => result-sequence) + (remove-duplicates sequence &key (from-end nil) test test-not (start 0) (end nil) key => result-sequence) + (delete-duplicates sequence &key (from-end nil) test test-not (start 0) (end nil) key => result-sequence) + + + ;; hash tables + (make-hash-table &key (test #'eql) (size *implementation-dependent-size*) (rehash-size *implementation-dependent-rehash-size*) (rehash-threshold *implementation-dependent-threshold) => hash-table) + (hash-table-p object => generalized-boolean) + (hash-table-count hash-table => count) + (hash-table-rehash-size hash-table => rehash-size) + (hash-table-rehash-threshold hash-table => rehash-threshold) + (hash-table-size hash-table => size) + (hash-table-test hash-table => test) + (gethash key hash-table &optional (default nil) => value present-p) + (remhash key hash-table => generalized-boolean) + (maphash function hash-table => nil) + (with-hash-table-iterator . "(name hash-table) declaration* form* => result*") + (clrhash hash-table => hash-table) + (sxhash object => hash-code) + + ;; filenames + (pathname pathspec => pathname) + (make-pathname &key host device directory name type version defaults case => pathname) + (pathnamep object => generalized-boolean) + (pathname-host pathname-designator &key (case :local) => host) + (pathname-device pathname-designator &key (case :local) => device) + (pathname-directory pathname-designator &key (case :local) => directory) + (pathname-name pathname-designator &key (case :local) => name) + (pathname-type pathname-designator &key (case :local) => type) + (pathname-version pathname-designator => version) + (load-logical-pathname-translations host => just-loaded) + (logical-pathname-translations host => translations) + (logical-pathname pathspec => logical-pathname) + (namestring pathname-designator => namestring) + (file-namestring pathname-designator => namestring) + (directory-namestring pathname-designator => namestring) + (host-namestring pathname-designator => namestring) + (enough-namestring pathname-designator &optional (defaults *default-pathname-defaults*) => namestring) + (parse-namestring thing &optional host (default-pathname *default-pathname-defaults*) &key (start 0) (end nil) (junk-allowed nil) => pathname position) + (wild-pathname-p pathname &optional (field-key nil) => generalized-boolean) + (pathname-match-p pathname wildcard => generalized-boolean) + (translate-logical-pathname pathname &key => physical-pathname) + (translate-pathname source from-wildcard to-wildcard &key => translated-pathname) + (merge-pathnames pathname &optional (default-pathname *default-pathname-defaults*) (default-version :newest) => merged-pathname) + + ;; files + (directory pathspec &key => pathnames) + (probe-file pathspec => truename) + (ensure-directories-exist pathspec &key verbose => pathspec created) + (truename filespec => truename) + (file-author pathspec => author) + (file-write-date pathspec => date) + (rename-file filespec new-name => defaulted-new-name old-truename new-truename) + (delete-file filespec => t) + (file-error-pathname condition => pathspec) + + ;; streams + (input-stream-p stream => generalized-boolean) + (output-stream-p stream => generalized-boolean) + (interactive-stream-p stream => generalized-boolean) + (open-stream-p stream => generalized-boolean) + (stream-element-type stream => typespec) + (streamp object => generalized-boolean) + (read-byte stream &optional (eof-error-p t) (eof-value nil) => byte) + (write-byte byte stream => byte) + (peek-char &optional (peek-type nil) (input-stream *standard-input*) (eof-error-p t) (eof-value nil) (recursive-p nil) => char) + (read-char &optional (input-stream *standard-input*) (eof-error-p t) (eof-value nil) (recursive-p nil) => char) + (read-char-no-hang &optional (input-stream *standard-input*) (eof-error-p t) (eof-value nil) (recursive-p nil) => char) + (terpri &optional (output-stream *standard-output*) => nil) + (fresh-line &optional (output-stream *standard-output*) => generalized-boolean) + (unread-char character &optional (input-stream *standard-input*) => nil) + (write-char character &optional (output-stream *standard-output*) => character) + (read-line &optional (input-stream *standard-input*) (eof-error-p t) (eof-value nil) (recursive-p nil) => line missing-newline-p) + (write-string string &optional (output-stream *standard-output*) &key (start 0) (end nil) => string) + (write-line string &optional (output-stream *standard-output*) &key (start 0) (end nil) => string) + (read-sequence sequence stream &key (start 0) (end nil) => position) + (write-sequence sequence stream &key (start 0) (end nil) => sequence) + (file-length stream => length) + ;;(file-position stream => position) + ;;(file-position stream position-spec => success-p) + (file-string-length stream object => length) + (open filespec &key (direction :input) (element-type 'character) if-exists if-does-not-exist external-format => stream) + (stream-external-format stream => format) + (with-open-file . "(stream filespec options*) declaration* form* => results") + (close stream &key (abort nil) => result) + (with-open-stream . "(var stream) declaration* form* => result*") + (listen &optional (input-stream *standard-input*) => generalized-boolean) + (clear-input &optional (input-stream *standard-input*) => nil) + (finish-output &optional (output-stream *standard-output*) => nil) + (force-output &optional (output-stream *standard-output*) => nil) + (clear-output &optional (output-stream *standard-output*) => nil) + (y-or-n-p &optional control &rest arguments => generalized-boolean) + (yes-or-no-p &optional control &rest arguments => generalized-boolean) + (make-synonym-stream symbol => synonym-stream) + (synonym-stream-symbol synonym-stream => symbol) + (broadcast-stream-streams broadcast-stream => streams) + (make-broadcast-stream &rest streams => broadcast-stream) + (make-two-way-stream input-stream output-stream => two-way-stream) + (two-way-stream-input-stream two-way-stream => input-stream) + (two-way-stream-output-stream two-way-stream => output-stream) + (echo-stream-input-stream echo-stream => input-stream) + (echo-stream-output-stream echo-stream => output-stream) + (make-echo-stream input-stream output-stream => echo-stream) + (concatenated-stream-streams concatenated-stream => streams) + (make-concatenated-stream &rest input-streams => concatenated-stream) + (get-output-stream-string string-output-stream => string) + (make-string-input-stream string &optional (start 0) (end nil) => string-stream) + (make-string-output-stream &key (element-type 'character) => string-stream) + (with-input-from-string . "(var string &key index start end) declaration* form* => result*") + (with-output-to-string . "(var &optional string-form &key element-type) declaration* form* => result*") + (stream-error-stream condition => stream) + + ;; printer + (copy-pprint-dispatch &optional (table *print-pprint-dispatch*) => new-table) + (formatter control-string => function) + (pprint-dispatch object &optional (table *print-pprint-dispatch*) => function found-p) + (pprint-exit-if-list-exhausted => nil) + (pprint-fill stream object &optional (colon-p t) (at-sign-p *implementation-dependent-at-sign-p*) => nil) + (pprint-linear stream object &optional (colon-p t) (at-sign-p *implementation-dependent-at-sign-p*) => nil) + (pprint-tabular stream object &optional (colon-p t) (at-sign-p *implementation-dependent-at-sign-p*) (tabsize 16) => nil) + (pprint-indent relative-to n &optional (stream *standard-output*) => nil) + (pprint-logical-block . "(stream-symbol object &key prefix per-line-prefix suffix) declaration* form* => nil") + (pprint-newline kind &optional (stream *standard-output*) => nil) + (pprint-pop => object) + (pprint-tab kind colnum colinc &optional stream => nil) + (print-object object stream => object) + (print-unreadable-object . "(object stream &key type identity) form* => nil") + (set-pprint-dispatch type-specifier function &optional (priority 0) (table *print-pprint-dispatch*) => nil) + (write object &key array base case circle escape gensym length level lines miser-width pprint-dispatch pretty radix readably right-margin (stream *standard-output*) => object) + (prin1 object &optional (output-stream *standard-output*) => object) + (princ object &optional (output-stream *standard-output*) => object) + (print object &optional (output-stream *standard-output*) => object) + (pprint object &optional (output-stream *standard-output*) => ) + (write-to-string object &key array base case circle escape gensym length level lines miser-width pprint-dispatch pretty radix readably right-margin => string) + (prin1-to-string object => string) + (princ-to-string object => string) + (print-not-readable-object condition => object) + (format destination control-string &rest args => result) + + ;; reader + (copy-readtable &optional (from-readtable *readtable*) (to-readtable nil) => readtable) + (make-dispatch-macro-character char &optional (non-terminating-p nil) (readtable *readtable*) => t) + (read &optional input-stream (eof-error-p t) (eof-value nil) (recursive-p nil) => object) + (read-preserving-whitespace &optional input-stream (eof-error-p t) (eof-value nil) (recursive-p nil) => object) + (read-delimited-list char &optional (input-stream *standard-input*) (recursive-p nil) => list) + (read-from-string string &optional (eof-error-p t) (eof-value nil) &key (start 0) (end nil) (preserve-whitespace nil) => object position) + (readtable-case readtable => case-sensitivity-mode) + (readtablep object => generalized-boolean) + (get-dispatch-macro-character disp-char sub-char &optional (readtable *readtable*) => function) + (set-dispatch-macro-character disp-char sub-char new-function &optional (readtable *readtable*) => t) + (get-macro-character char &optional (readtable *readtable*) => function non-terminating-p) + (set-macro-character char new-function &optional (non-terminating-p nil) (readtable *readtable*) => t) + (set-syntax-from-char to-char from-char &optional (to-readtable *readtable*) (from-readtable +standard-readtable+) => t) + (with-standard-io-syntax . "form* => result*") + + ;; system construction + (compile-file input-file &key (output-file *implementation-defined-output-file*) (verbose *compile-verbose*) (print *compile-print*) (external-format :default) => output-truename warnings-p failure-p) + (compile-file-pathname input-file &key (output-file *implementation-defined-output-file*) &allow-other-keys => pathname) + (load filespec &key (verbose *load-verbose*) (print *load-print*) (if-does-not-exist t) (external-format :default) => generalized-boolean) + (with-compilation-unit . "([[:override override-form]]) form* => result*") + (provide module-name => implementation-dependent) + (require module-name &optional pathname-list => implementation-dependent) + + ;; environment + (decode-universal-time universal-time &optional time-zone => second minute hour date month year day daylight-p zone) + (encode-universal-time second minute hour date month year &optional time-zone => universal-time) + (get-universal-time => universal-time) + (get-decoded-time => second minute hour date month year day daylight-p zone) + (sleep seconds => nil) + (apropos string &optional (package nil) => ) + (apropos-list string &optional (package nil) => symbols) + (describe object &optional (stream *standard-output*) => ) + (describe-object object stream => implementation-dependent) + (trace . "function-name* => trace-result") + (untrace . "function-name* => untrace-result") + (step . "form => result*") + (time . "form => result*") + (get-internal-real-time => internal-time) + (get-internal-run-time => internal-time) + (disassemble extended-function-designator-or-lambda-expression => nil) + (documentation x doc-type => documentation) + (room &optional x => implementation-dependent) + (ed &optional x => implementation-dependent) + (inspect object => implementation-dependent) + (dribble &optional pathname => implementation-dependent) + (lisp-implementation-type => description) + (lisp-implementation-version => description) + (short-site-name => description) + (long-site-name => description) + (machine-instance => description) + (machine-type => description) + (machine-version => description) + (software-type => description) + (software-version => description) + (user-homedir-pathname &optional host => pathname) + )) + + +(provide 'cldoc) + +;;; cldoc.el ends here diff --git a/emacs/espresso.el b/emacs/espresso.el new file mode 100644 index 0000000..1e6f3a9 --- /dev/null +++ b/emacs/espresso.el @@ -0,0 +1,869 @@ +;;; espresso.el --- Major mode for editing JavaScript source text +;; Copyright (C) 2008 Free Software Foundation, Inc. +;; Copyright (C) 2009 Daniel Colascione +;; Author: Karl Landstrom +;; Author: Daniel Colascione +;; Maintainer: Daniel Colascione +;; Version: 4 +;; Date: 2009-01-06 +;; Keywords: languages, oop, javascript + +;; This file is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; This file is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary + +;; This is based on Karl Landstrom's barebones javascript-mode. This +;; is much more robust and works with cc-mode's comment filling +;; (mostly). +;; +;; The main features of this JavaScript mode are syntactic +;; highlighting (enabled with `font-lock-mode' or +;; `global-font-lock-mode'), automatic indentation and filling of +;; comments, and C preprocessor fontification. +;; +;; This package has (only) been tested with GNU Emacs 22 (the latest +;; stable release). +;; +;; Installation: +;; +;; Put this file in a directory where Emacs can find it (`C-h v +;; load-path' for more info). Then add the following lines to your +;; Emacs initialization file: +;; +;; (add-to-list 'auto-mode-alist '("\\.js\\'" . espresso-mode)) +;; (autoload 'espresso-mode "espresso" nil t) +;; +;; General Remarks: +;; +;; XXX: This mode assumes that block comments are not nested inside block +;; XXX: comments and that strings do not contain line breaks. +;; +;; Exported names start with "espresso-" whereas private names start +;; with "espresso--". +;; +;; Code: + +;;; Code + +(require 'cc-mode) +(require 'font-lock) +(require 'newcomment) + +(eval-when-compile + (require 'cl)) + +;;; User customization + +(defgroup espresso nil + "Customization variables for `espresso-mode'." + :tag "JavaScript - Espresso-Mode" + :group 'languages) + +(defcustom espresso-indent-level 4 + "Number of spaces for each indentation step." + :type 'integer + :group 'espresso) + +(defcustom espresso-expr-indent-offset 0 + "Number of additional spaces used for indentation of continued +expressions. The value must be no less than minus +`espresso-indent-level'." + :type 'integer + :group 'espresso) + +(defcustom espresso-auto-indent-flag t + "Automatic indentation with punctuation characters. If non-nil, the +current line is indented when certain punctuations are inserted." + :type 'boolean + :group 'espresso) + +;;; KeyMap + +(defvar espresso-mode-map nil + "Keymap used in Espresso mode.") + +(unless espresso-mode-map + (setq espresso-mode-map (make-sparse-keymap))) + +(when espresso-auto-indent-flag + (mapc (lambda (key) + (define-key espresso-mode-map key 'espresso-insert-and-indent)) + '("{" "}" "(" ")" ":" ";" ","))) + +(defun espresso-insert-and-indent (key) + "Runs the command bound to KEY in the global keymap, and if +we're not in a string or comment, indents the current line." + (interactive (list (this-command-keys))) + (call-interactively (lookup-key (current-global-map) key)) + (let ((syntax (save-restriction (widen) (syntax-ppss)))) + (unless (nth 8 syntax) + (indent-according-to-mode)))) + +;;; Syntax table and parsing + +(defvar espresso-mode-syntax-table + (let ((table (make-syntax-table))) + (c-populate-syntax-table table) + (modify-syntax-entry ?$ "_" table) + table) + "Syntax table used in Espresso mode.") + +(defconst espresso--name-start-re "[a-zA-Z_$]" + "Matches the first character of a Espresso identifier. No grouping") + +(defconst espresso--stmt-delim-chars "^;{}?:") + +(defconst espresso--name-re (concat espresso--name-start-re + "\\(?:\\s_\\|\\sw\\)*") + "Matches a Javascript name. No grouping.") + +(defconst espresso--dotted-name-re + (concat espresso--name-re "\\(?:\\." espresso--name-re "\\)*") + "Matches a dot-separated sequence of Javascript names") + +(defconst espresso--cpp-name-re espresso--name-re + "Matches a C preprocessor name") + +(defconst espresso--opt-cpp-start "^\\s-*#\\s-*\\([[:alnum:]]+\\)" + " Regexp matching the prefix of a cpp directive including the directive +name, or nil in languages without preprocessor support. The first +submatch surrounds the directive name.") + + +(defconst espresso--class-decls + `(; var NewClass = BaseClass.extend( + ,(concat "^\\s-*\\_\\s-+" + "\\(" espresso--dotted-name-re "\\)" + "\\s-*=" "\\s-*" + "\\(" espresso--dotted-name-re + "\\)\\.extend\\(?:Final\\)?\\s-*(") + + ; NewClass: BaseClass.extend( ; for nested classes + ,(concat "^\\s-*" + "\\(" espresso--dotted-name-re "\\):" + "\\s-*\\(" espresso--dotted-name-re + "\\)\\.extend\\(?:Finak\\)?\\s-*(")) + "List of regular expressions that can match class definitions. +Each one must set match group 1 to the name of the class being +defined, and optionally, group 2 to the name of the base class.") + +(defun espresso--regexp-opt-symbol (list) + "Like regexp-opt, but surround the optimized regular expression +with `\\\\_<' and `\\\\_>'." + (concat "\\_<" (regexp-opt list t) "\\_>")) + +(defun espresso--re-search-forward-inner (regexp &optional bound count) + "Auxiliary function for `espresso--re-search-forward'." + (let ((parse) + (orig-macro-end (save-excursion + (when (espresso--beginning-of-macro) + (c-end-of-macro) + (point)))) + (saved-point (point-min))) + (while (> count 0) + (re-search-forward regexp bound) + (setq parse (parse-partial-sexp saved-point (point))) + (cond ((nth 3 parse) + (re-search-forward + (concat "\\([^\\]\\|^\\)" (string (nth 3 parse))) + (save-excursion (end-of-line) (point)) t)) + ((nth 7 parse) + (forward-line)) + ((or (nth 4 parse) + (and (eq (char-before) ?\/) (eq (char-after) ?\*))) + (re-search-forward "\\*/")) + ((and (not (and orig-macro-end + (<= (point) orig-macro-end))) + (espresso--beginning-of-macro)) + (c-end-of-macro)) + (t + (setq count (1- count)))) + (setq saved-point (point)))) + (point)) + + +(defun espresso--re-search-forward (regexp &optional bound noerror count) + "Search forward but ignore strings, cpp macros, and comments. +Invokes `re-search-forward' but treats the buffer as if strings, +cpp macros, and comments have been removed. + +If invoked while inside a macro, treat the contents of the macro +as normal text. + +" + (let ((saved-point (point)) + (search-expr + (cond ((null count) + '(espresso--re-search-forward-inner regexp bound 1)) + ((< count 0) + '(espresso--re-search-backward-inner regexp bound (- count))) + ((> count 0) + '(espresso--re-search-forward-inner regexp bound count))))) + (condition-case err + (eval search-expr) + (search-failed + (goto-char saved-point) + (unless noerror + (error (error-message-string err))))))) + + +(defun espresso--re-search-backward-inner (regexp &optional bound count) + "Auxiliary function for `espresso--re-search-backward'." + (let ((parse) + (orig-macro-start + (save-excursion + (and (espresso--beginning-of-macro) + (point)))) + (saved-point (point-min))) + (while (> count 0) + (re-search-backward regexp bound) + (when (and (> (point) (point-min)) + (save-excursion (backward-char) (looking-at "/[/*]"))) + (forward-char)) + (setq parse (parse-partial-sexp saved-point (point))) + (cond ((nth 3 parse) + (re-search-backward + (concat "\\([^\\]\\|^\\)" (string (nth 3 parse))) + (save-excursion (beginning-of-line) (point)) t)) + ((nth 7 parse) + (goto-char (nth 8 parse))) + ((or (nth 4 parse) + (and (eq (char-before) ?/) (eq (char-after) ?*))) + (re-search-backward "/\\*")) + ((and (not (and orig-macro-start + (>= (point) orig-macro-start))) + (espresso--beginning-of-macro))) + (t + (setq count (1- count)))))) + (point)) + + +(defun espresso--re-search-backward (regexp &optional bound noerror count) + "Search backward but ignore strings, preprocessor macros, and +comments. Invokes `re-search-backward' but treats the buffer as +if strings, preprocessor macros, and comments have been removed. + +If inside a macro when called, treat the macro as normal text. +" + (let ((saved-point (point)) + (search-expr + (cond ((null count) + '(espresso--re-search-backward-inner regexp bound 1)) + ((< count 0) + '(espresso--re-search-forward-inner regexp bound (- count))) + ((> count 0) + '(espresso--re-search-backward-inner regexp bound count))))) + (condition-case err + (eval search-expr) + (search-failed + (goto-char saved-point) + (unless noerror + (error (error-message-string err))))))) + + +(defun espresso--forward-function-decl () + (assert (looking-at "\\_")) + (forward-word) + (forward-comment most-positive-fixnum) + (skip-chars-forward "^(") + (unless (eobp) + (forward-list) + (forward-comment most-positive-fixnum) + (skip-chars-forward "^{")) + t) + +(defun espresso--beginning-of-defun () + (cond ((espresso--re-search-backward "\\_" (point-min) t) + (let ((pos (point))) + (save-excursion + (forward-line 0) + (when (looking-at espresso--function-heading-2-re) + (setq pos (match-beginning 1)))) + (goto-char pos))) + + (t + (goto-char (point-min))))) + +(defun espresso--end-of-defun () + ;; look for function backward. if we're inside it, go to that + ;; function's end. otherwise, search for the next function's end and + ;; go there + (unless (looking-at "\\_<") + (skip-syntax-backward "w_")) + + (let ((orig-point (point)) pos) + (when (or (looking-at "\\_") + (espresso--re-search-backward "\\_" (point-min) t)) + (goto-char (match-beginning 0)) + (let* ((func-loc (point)) + (opening-brace-loc (progn (espresso--forward-function-decl) + (point)))) + + (cond ((and (<= func-loc orig-point) + (<= orig-point opening-brace-loc)) + (setq pos opening-brace-loc)) + + ((/= 0 (nth 0 (parse-partial-sexp + opening-brace-loc orig-point 0))) + (setq pos opening-brace-loc))))) + + (cond + (pos (goto-char pos) + (forward-list)) + + ((espresso--re-search-forward "\\_" (point-max) t) + (espresso--end-of-defun)) + + (t (goto-char (point-max)))))) + +(defun espresso--beginning-of-macro (&optional lim) + (let ((here (point))) + (save-restriction + (if lim (narrow-to-region lim (point-max))) + (beginning-of-line) + (while (eq (char-before (1- (point))) ?\\) + (forward-line -1)) + (back-to-indentation) + (if (and (<= (point) here) + (looking-at espresso--opt-cpp-start)) + t + (goto-char here) + nil)))) + +(defun espresso--backward-syntactic-ws (&optional lim) + "Simple implementation of c-backward-syntactic-ws" + (save-restriction + (when lim (narrow-to-region lim (point-max))) + + (let ((in-macro (save-excursion (espresso--beginning-of-macro))) + (pos (point))) + + (while (progn (unless in-macro (espresso--beginning-of-macro)) + (forward-comment most-negative-fixnum) + (/= (point) + (prog1 + pos + (setq pos (point))))))))) + +(defun espresso--forward-syntactic-ws (&optional lim) + "Simple implementation of c-forward-syntactic-ws" + (save-restriction + (when lim (narrow-to-region (point-min) min)) + (let ((pos (point))) + (while (progn + (forward-comment most-positive-fixnum) + (when (eq (char-after) ?#) + (c-end-of-macro)) + (/= (point) + (prog1 + pos + (setq pos (point))))))))) + +;;; Font Lock + +(defun espresso--inside-param-list-p () + "Return non-nil iff point is inside a function parameter list." + (condition-case err + (save-excursion + (up-list -1) + (and (looking-at "(") + (progn (forward-symbol -1) + (or (looking-at "function") + (progn (forward-symbol -1) (looking-at "function")))))) + (error nil))) + +(defconst espresso--function-heading-1-re + (concat + "^\\s-*function\\s-+\\(" espresso--name-re "\\)") + "Regular expression matching the start of a function header. Match group 1 +is the name of the function.") + +(defconst espresso--function-heading-2-re + (concat + "^\\s-*\\(" espresso--name-re "\\)\\s-*:\\s-*function\\_>") + "Regular expression matching the start of a function entry in + an associative array. Match group 1 is the name of the function.") + +(defconst espresso--macro-decl-re + (concat "^\\s-*#\\s-*define\\s-+\\(" espresso--cpp-name-re "\\)\\s-*(") + "Regular expression matching a CPP macro definition up to the opening +parenthesis. Match group 1 is the name of the function.") + +(defconst espresso--keyword-re + (espresso--regexp-opt-symbol + '("abstract" "break" "case" "catch" "class" "const" + "continue" "debugger" "default" "delete" "do" "else" + "enum" "export" "extends" "final" "finally" "for" + "function" "goto" "if" "implements" "import" "in" + "instanceof" "interface" "native" "new" "package" + "private" "protected" "public" "return" "static" + "super" "switch" "synchronized" "throw" + "throws" "transient" "try" "typeof" "var" "void" + "volatile" "while" "with" "let")) + "Regular expression matching any JavaScript keyword.") + +(defconst espresso--basic-type-re + (espresso--regexp-opt-symbol + '("boolean" "byte" "char" "double" "float" "int" "long" + "short" "void")) + "Regular expression matching any predefined type in JavaScript.") + +(defconst espresso--constant-re + (espresso--regexp-opt-symbol '("false" "null" "undefined" + "true" "arguments" "this")) + "Regular expression matching any future reserved words in JavaScript.") + + +(defconst espresso--font-lock-keywords-1 + (list + "\\_" + (list espresso--function-heading-1-re 1 font-lock-function-name-face) + (list espresso--function-heading-2-re 1 font-lock-function-name-face)) + "Level one font lock.") + +(defconst espresso--font-lock-keywords-2 + (append espresso--font-lock-keywords-1 + (list (list espresso--keyword-re 1 font-lock-keyword-face) + (cons espresso--basic-type-re font-lock-type-face) + (cons espresso--constant-re font-lock-constant-face))) + "Level two font lock.") + + +;; Limitations with variable declarations: There seems to be no +;; sensible way to highlight variables occuring after an initialized +;; variable in a variable list. For instance, in +;; +;; var x, y = f(a, b), z +;; +;; z will not be highlighted. Also, in variable declaration lists +;; spanning several lines only variables on the first line will be +;; highlighted. To get correct fontification, every line with variable +;; declarations must contain a `var' keyword. + +(defconst espresso--font-lock-keywords-3 + `( + ;; This goes before keywords-2 so it gets used preferentially + ;; instead of the keywords in keywords-2. Don't use override + ;; because that will override syntactic fontification too, which + ;; will fontify commented-out directives as if they weren't + ;; commented out. + ,@cpp-font-lock-keywords ; from font-lock.el + + ,@espresso--font-lock-keywords-2 + + ;; variable declarations + ,(list + (concat "\\_<\\(const\\|var\\)\\_>\\|" espresso--basic-type-re) + (list (concat "\\(" espresso--name-re "\\)" + "\\s-*\\([=;].*\\|\\_.*\\|,\\|/[/*]\\|$\\)") + nil + nil + '(1 font-lock-variable-name-face))) + + ;; class instantiation + ,(list + (concat "\\_\\s-+\\(" espresso--dotted-name-re "\\)") + (list 1 'font-lock-type-face)) + + ;; instanceof + ,(list + (concat "\\_\\s-+\\(" espresso--dotted-name-re "\\)") + (list 1 'font-lock-type-face)) + + ;; formal parameters + ,(list + (concat + "\\_\\(\\s-+" espresso--name-re "\\)?\\s-*(\\s-*" + espresso--name-start-re) + (list (concat "\\(" espresso--name-re "\\)\\(\\s-*).*\\)?") + '(backward-char) + '(end-of-line) + '(1 font-lock-variable-name-face))) + + ;; continued formal parameter list + ,(list + (concat + "^\\s-*" espresso--name-re "\\s-*[,)]") + (list espresso--name-re + '(if (save-excursion (backward-char) + (espresso--inside-param-list-p)) + (forward-symbol -1) + (end-of-line)) + '(end-of-line) + '(0 font-lock-variable-name-face))) + + ;; class declarations + ,@(mapcar #'(lambda (x) + `(,x + (1 font-lock-type-face t t) + (2 font-lock-type-face t t))) + + espresso--class-decls)) + "Level three font lock.") + + +(defconst espresso--font-lock-keywords + '(espresso--font-lock-keywords-3 espresso--font-lock-keywords-1 + espresso--font-lock-keywords-2 + espresso--font-lock-keywords-3) + "See `font-lock-keywords'.") + +;; Note: Javascript cannot continue a regular expression literal +;; across lines +(defconst espresso--regexp-literal + "[=(,]\\(?:\\s-\\|\n\\)*\\(/\\)[^/*]\\(?:.*?[^\\]\\)?\\(/\\)" + "Match a regular expression literal. Match groups 1 and 2 are +the characters forming the beginning and end of the literal") + +;; we want to match regular expressions only at the beginning of +;; expressions +(defconst espresso--font-lock-syntactic-keywords + `((,espresso--regexp-literal (1 "|") (2 "|"))) + "Highlighting of regular expressions. See also the variable + `font-lock-keywords'.") + +;;; Indentation + +(defconst espresso--possibly-braceless-keyword-re + (espresso--regexp-opt-symbol + '("catch" "do" "else" "finally" "for" "if" "try" "while" "with" "let")) + "Regular expression matching keywords that are optionally + followed by an opening brace.") + +(defconst espresso--indent-operator-re + (concat "[-+*/%<>=&^|?:.]\\([^-+*/]\\|$\\)\\|" + (espresso--regexp-opt-symbol '("in" "instanceof"))) + "Regular expression matching operators that affect indentation + of continued expressions.") + + +(defun espresso--looking-at-operator-p () + "Return non-nil if text after point is an operator (that is not +a comma)." + (save-match-data + (and (looking-at espresso--indent-operator-re) + (or (not (looking-at ":")) + (save-excursion + (and (espresso--re-search-backward "[?:{]\\|\\_" nil t) + (looking-at "?"))))))) + + +(defun espresso--continued-expression-p () + "Returns non-nil if the current line continues an expression." + (save-excursion + (back-to-indentation) + (or (espresso--looking-at-operator-p) + (and (espresso--re-search-backward "\n" nil t) + (progn + (skip-chars-backward " \t") + (or (bobp) (backward-char)) + (and (> (point) (point-min)) + (save-excursion (backward-char) (not (looking-at "[/*]/"))) + (espresso--looking-at-operator-p) + (and (progn (backward-char) + (not (looking-at "++\\|--\\|/[/*]")))))))))) + + +(defun espresso--end-of-do-while-loop-p () + "Returns non-nil if word after point is `while' of a do-while +statement, else returns nil. A braceless do-while statement +spanning several lines requires that the start of the loop is +indented to the same column as the current line." + (interactive) + (save-excursion + (save-match-data + (when (looking-at "\\s-*\\_") + (if (save-excursion + (skip-chars-backward "[ \t\n]*}") + (looking-at "[ \t\n]*}")) + (save-excursion + (backward-list) (forward-symbol -1) (looking-at "\\_")) + (espresso--re-search-backward "\\_" (point-at-bol) t) + (or (looking-at "\\_") + (let ((saved-indent (current-indentation))) + (while (and (espresso--re-search-backward "^\\s-*\\_<" nil t) + (/= (current-indentation) saved-indent))) + (and (looking-at "\\s-*\\_") + (not (espresso--re-search-forward + "\\_" (point-at-eol) t)) + (= (current-indentation) saved-indent))))))))) + + +(defun espresso--ctrl-statement-indentation () + "Returns the proper indentation of the current line if it +starts the body of a control statement without braces, else +returns nil." + (save-excursion + (back-to-indentation) + (when (save-excursion + (and (not (looking-at "[{]")) + (progn + (espresso--re-search-backward "[[:graph:]]" nil t) + (or (eobp) (forward-char)) + (when (= (char-before) ?\)) (backward-list)) + (skip-syntax-backward " ") + (skip-syntax-backward "w_") + (looking-at espresso--possibly-braceless-keyword-re)) + (not (espresso--end-of-do-while-loop-p)))) + (save-excursion + (goto-char (match-beginning 0)) + (+ (current-indentation) espresso-indent-level))))) + + +(defun espresso--proper-indentation (parse-status) + "Return the proper indentation for the current line." + (save-excursion + (back-to-indentation) + (let ((ctrl-stmt-indent (espresso--ctrl-statement-indentation)) + (same-indent-p (looking-at "[]})]\\|\\_\\|\\_")) + (continued-expr-p (espresso--continued-expression-p))) + (cond (ctrl-stmt-indent) + ((eq (char-after) ?#) 0) + ((save-excursion (espresso--beginning-of-macro)) + 4) + ((nth 1 parse-status) + (goto-char (nth 1 parse-status)) + (if (looking-at "[({[]\\s-*\\(/[/*]\\|$\\)") + (progn + (skip-syntax-backward " ") + (when (= (char-before) ?\)) (backward-list)) + (back-to-indentation) + (cond (same-indent-p + (current-column)) + (continued-expr-p + (+ (current-column) (* 2 espresso-indent-level) + espresso-expr-indent-offset)) + (t + (+ (current-column) espresso-indent-level)))) + (unless same-indent-p + (forward-char) + (skip-chars-forward " \t")) + (current-column))) + (continued-expr-p (+ espresso-indent-level + espresso-expr-indent-offset)) + (t 0))))) + + +(defun espresso-indent-line () + "Indent the current line as JavaScript source text." + (interactive) + (save-restriction + (widen) + (let* ((parse-status + (save-excursion (syntax-ppss (point-at-bol)))) + (offset (- (current-column) (current-indentation)))) + + (if (nth 8 parse-status) + (indent-relative-maybe) + (indent-line-to (espresso--proper-indentation parse-status)) + (when (> offset 0) (forward-char offset)))))) + +;;; Filling + +(defun espresso-c-fill-paragraph (&optional justify) + "Fill the paragraph with c-fill-paragraph" + (interactive "*P") + + ;; FIXME: filling a single-line C-style comment into multiple lines + ;; does something horrible to the undo list + + (flet ((c-forward-sws + (&optional limit) + (espresso--forward-syntactic-ws limit)) + + (c-backward-sws + (&optional limit) + (espresso--backward-syntactic-ws limit)) + + (c-beginning-of-macro + (&optional limit) + (espresso--beginning-of-macro limit))) + + (let ((fill-paragraph-function 'c-fill-paragraph)) + (c-fill-paragraph justify)))) + +;;; Imenu + +(defun espresso--imenu-create-index () + (let ((search-re (mapconcat (lambda (x) + (concat "\\(" x "\\)")) + (list espresso--function-heading-1-re + espresso--function-heading-2-re + (concat "\\(?:" + (mapconcat + #'identity + espresso--class-decls "\\|") + "\\)") + espresso--macro-decl-re) + "\\|")) + entries parent-entries ends tmp syntax) + (save-excursion + (save-restriction + (widen) + (goto-char (point-min)) + + (while (re-search-forward search-re (point-max) t) + (goto-char (match-beginning 0)) + (setq syntax (syntax-ppss)) + (unless (or (nth 3 syntax) (nth 4 syntax)) + (while (and ends (>= (point) (car ends))) + (setq tmp (nreverse entries) + entries (pop parent-entries)) + + (unless tmp + (setq tmp (list + (cons "[empty]" (set-marker (make-marker) + (car ends)))))) + + (pop ends) + + (setcdr (car entries) tmp)) + + (cond ((and (not parent-entries) ; regular function or macro + (or (looking-at espresso--function-heading-1-re) + (looking-at espresso--macro-decl-re))) + + (push (cons (match-string-no-properties 1) + (set-marker (make-marker) (match-beginning 1))) + entries)) + + ;; does one of the espresso--class-decls regexps match? + ((let ((r espresso--class-decls)) + (while (and r (not (looking-at (car r) ))) + (setq r (cdr r))) + r) + + (push (cons + (match-string-no-properties 1) + nil) + entries) + (push entries parent-entries) + (setq entries nil) + (goto-char (match-end 1)) + (condition-case err + (forward-list) + (error nil)) + (push (point) ends)) + + + ((and parent-entries + (looking-at espresso--function-heading-2-re)) + (push (cons (match-string-no-properties 1) + (set-marker (make-marker) (match-beginning 1))) + entries)))) + + (goto-char (match-end 0))) + + (while parent-entries + (setq tmp (nreverse entries) + entries (pop parent-entries)) + (setcdr (car entries) tmp)))) + + (nreverse entries))) + +(defun espresso--which-func-joiner (parts) + (mapconcat #'identity parts ".")) + +;;; Main Function + +;;;###autoload +(defun espresso-mode () + "Major mode for editing JavaScript source text. + +Key bindings: + +\\{espresso-mode-map}" + (interactive) + (kill-all-local-variables) + + (use-local-map espresso-mode-map) + (set-syntax-table espresso-mode-syntax-table) + (set (make-local-variable 'indent-line-function) 'espresso-indent-line) + (set (make-local-variable 'beginning-of-defun-function) + 'espresso--beginning-of-defun) + (set (make-local-variable 'end-of-defun-function) + 'espresso--end-of-defun) + + (set (make-local-variable 'open-paren-in-column-0-is-defun-start) nil) + + (set (make-local-variable 'font-lock-defaults) + (list espresso--font-lock-keywords + nil nil nil nil + '(font-lock-syntactic-keywords + . espresso--font-lock-syntactic-keywords))) + + (set (make-local-variable 'parse-sexp-ignore-comments) t) + (set (make-local-variable 'parse-sexp-lookup-properties) t) + (set (make-local-variable 'which-func-imenu-joiner-function) + #'espresso--which-func-joiner) + + ;; Comments + (setq comment-start "// ") + (setq comment-end "") + (set (make-local-variable 'fill-paragraph-function) + 'espresso-c-fill-paragraph) + + ;; Imenu + (setq imenu-case-fold-search nil) + (set (make-local-variable 'imenu-create-index-function) + #'espresso--imenu-create-index) + + (setq major-mode 'espresso-mode) + (setq mode-name "Espresso") + + ;; for filling, pretend we're cc-mode + (setq c-comment-prefix-regexp "//+\\|\\**" + c-paragraph-start "$" + c-paragraph-separate "$" + c-block-comment-prefix "* " + c-line-comment-starter "//" + c-comment-start-regexp "/[*/]\\|\\s!" + comment-start-skip "\\(//+\\|/\\*+\\)\\s *") + + (let ((c-buffer-is-cc-mode t)) + (c-setup-paragraph-variables)) + + ;; Important to fontify the whole buffer syntactically! If we don't, + ;; then we might have regular expression literals that aren't marked + ;; as strings, which will screw up parse-partial-sexp, scan-lists, etc. + ;; and and produce maddening "unbalanced parenthesis" errors. When we attempt + ;; to find the error and scroll to the portion of the buffer containing the problem, + ;; JIT-lock will apply the correct syntax to the regular expresion literal and + ;; the problem will mysteriously disappear. + (font-lock-set-defaults) + + (let (font-lock-keywords) ; leaves syntactic keywords intact + (font-lock-fontify-buffer)) + + (run-mode-hooks 'espresso-mode-hook)) + + +(eval-after-load "hideshow" + '(add-to-list 'hs-special-modes-alist + '(espresso-mode "{" "}" "/[*/]" + nil hs-c-like-adjust-block-beginning))) + +(eval-after-load "folding" + (when (fboundp 'folding-add-to-marks-list) + (folding-add-to-marks-list 'espresso-mode "// {{{" "// }}}" ))) + + +;;; Emacs +(provide 'espresso-mode) +;; Local Variables: +;; outline-regexp: ";;; " +;; End: +;; espresso.el ends here diff --git a/emacs/flyspell.el b/emacs/flyspell.el new file mode 100644 index 0000000..aeaceee --- /dev/null +++ b/emacs/flyspell.el @@ -0,0 +1,2458 @@ +;;;
+;;; flyspell.el --- on-the-fly spell checker
+
+;; Copyright (C) 1998, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+;; Author: Manuel Serrano 
+;; Version: 1.7o
+;; Keywords: convenience
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;; Flyspell is a minor Emacs mode performing on-the-fly spelling
+;; checking.
+;;
+;; To enable Flyspell minor mode, type M-x flyspell-mode.
+;; This applies only to the current buffer.
+;;
+;; To enable Flyspell in text representing computer programs, type
+;; M-x flyspell-prog-mode.
+;; In that mode only text inside comments is checked.
+;;                                                                  
+;; Note: consider setting the variable ispell-parser to `tex' to
+;; avoid TeX command checking; use `(setq ispell-parser 'tex)'.
+;;                                                                  
+;; Some user variables control the behavior of flyspell.  They are
+;; those defined under the `User variables' comment.
+
+;;; Code:
+(require 'ispell)
+
+;*---------------------------------------------------------------------*/
+;*    Group ...                                                        */
+;*---------------------------------------------------------------------*/
+(defgroup flyspell nil
+  "Spell checking on the fly."
+  :tag "FlySpell"
+  :prefix "flyspell-"
+  :group 'ispell
+  :group 'processes)
+
+;*---------------------------------------------------------------------*/
+;*    Which emacs are we currently running                             */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-emacs
+  (cond
+   ((string-match "XEmacs" emacs-version)
+    'xemacs)
+   (t
+    'emacs))
+  "The type of Emacs we are currently running.")
+
+(defvar flyspell-use-local-map
+  (or (eq flyspell-emacs 'xemacs)
+      (not (string< emacs-version "20"))))
+
+;*---------------------------------------------------------------------*/
+;*    User configuration ...                                           */
+;*---------------------------------------------------------------------*/
+(defcustom flyspell-highlight-flag t
+  "*How Flyspell should indicate misspelled words.
+Non-nil means use highlight, nil means use minibuffer messages."
+  :group 'flyspell
+  :type 'boolean)
+
+(defcustom flyspell-mark-duplications-flag t
+  "*Non-nil means Flyspell reports a repeated word as an error."
+  :group 'flyspell
+  :type 'boolean)
+
+(defcustom flyspell-sort-corrections nil
+  "*Non-nil means, sort the corrections alphabetically before popping them."
+  :group 'flyspell
+  :version "21.1"
+  :type 'boolean)
+
+(defcustom flyspell-duplicate-distance -1
+  "*The maximum distance for finding duplicates of unrecognized words.
+This applies to the feature that when a word is not found in the dictionary,
+if the same spelling occurs elsewhere in the buffer,
+Flyspell uses a different face (`flyspell-duplicate-face') to highlight it.
+This variable specifies how far to search to find such a duplicate.
+-1 means no limit (search the whole buffer).
+0 means do not search for duplicate unrecognized spellings."
+  :group 'flyspell
+  :version "21.1"
+  :type 'number)
+
+(defcustom flyspell-delay 3
+  "*The number of seconds to wait before checking, after a \"delayed\" command."
+  :group 'flyspell
+  :type 'number)
+
+(defcustom flyspell-persistent-highlight t
+  "*Non-nil means misspelled words remain highlighted until corrected.
+If this variable is nil, only the most recently detected misspelled word
+is highlighted."
+  :group 'flyspell
+  :type 'boolean)
+
+(defcustom flyspell-highlight-properties t
+  "*Non-nil means highlight incorrect words even if a property exists for this word."
+  :group 'flyspell
+  :type 'boolean)
+
+(defcustom flyspell-default-delayed-commands
+  '(self-insert-command
+    delete-backward-char
+    backward-or-forward-delete-char
+    delete-char
+    scrollbar-vertical-drag
+    backward-delete-char-untabify)
+  "The standard list of delayed commands for Flyspell.
+See `flyspell-delayed-commands'."
+  :group 'flyspell
+  :version "21.1"
+  :type '(repeat (symbol)))
+
+(defcustom flyspell-delayed-commands nil
+  "List of commands that are \"delayed\" for Flyspell mode.
+After these commands, Flyspell checking is delayed for a short time,
+whose length is specified by `flyspell-delay'."
+  :group 'flyspell
+  :type '(repeat (symbol)))
+
+(defcustom flyspell-default-deplacement-commands
+  '(next-line
+    previous-line
+    scroll-up
+    scroll-down)
+  "The standard list of deplacement commands for Flyspell.
+See `flyspell-deplacement-commands'."
+  :group 'flyspell
+  :version "21.1"
+  :type '(repeat (symbol)))
+
+(defcustom flyspell-default-ignored-commands
+  '(fill-paragraph)
+  "The standard list of ignored commands for Flyspell.
+ See `flyspell-delayed-commands'."
+  :group 'flyspell
+  :version "21.3"
+  :type '(repeat (symbol)))
+ 
+ (defcustom flyspell-ignored-commands nil
+   "List of commands that are \"ignored\" for Flyspell mode.
+ The changes in the text made by these commands are ignored.  This list is meant for commands that change text in a way that does not affect individual words, such as `fill-paragraph'."
+   :group 'flyspell
+   :version "21.3"
+   :type '(repeat (symbol)))
+ 
+(defcustom flyspell-deplacement-commands nil
+  "List of commands that are \"deplacement\" for Flyspell mode.
+After these commands, Flyspell checking is performed only if the previous
+command was not the very same command."
+  :group 'flyspell
+  :version "21.1"
+  :type '(repeat (symbol)))
+
+(defcustom flyspell-issue-welcome-flag t
+  "*Non-nil means that Flyspell should display a welcome message when started."
+  :group 'flyspell
+  :type 'boolean)
+
+(defcustom flyspell-issue-message-flag t
+  "*Non-nil means that Flyspell emits messages when checking words."
+  :group 'flyspell
+  :type 'boolean)
+
+(defcustom flyspell-incorrect-hook nil
+  "*List of functions to be called when incorrect words are encountered.
+Each function is given three arguments: the beginning and the end
+of the incorrect region.  The third is either the symbol 'doublon' or the list
+of possible corrections as returned by 'ispell-parse-output'.
+
+If any of the functions return non-Nil, the word is not highlighted as
+incorrect."
+  :group 'flyspell
+  :version "21.1"
+  :type 'hook)
+
+(defcustom flyspell-default-dictionary nil
+  "A string that is the name of the default dictionary.
+This is passed to the `ispell-change-dictionary' when flyspell is started.
+If the variable `ispell-local-dictionary' or `ispell-dictionary' is non-nil
+when flyspell is started, the value of that variable is used instead
+of `flyspell-default-dictionary' to select the default dictionary.
+Otherwise, if `flyspell-default-dictionary' is nil, it means to use
+Ispell's ultimate default dictionary."
+  :group 'flyspell
+  :version "21.1"
+  :type '(choice string (const :tag "Default" nil)))
+
+(defcustom flyspell-tex-command-regexp
+  "\\(\\(begin\\|end\\)[ \t]*{\\|\\(cite[a-z*]*\\|label\\|ref\\|eqref\\|usepackage\\|documentclass\\)[ \t]*\\(\\[[^]]*\\]\\)?{[^{}]*\\)"
+  "A string that is the regular expression that matches TeX commands."
+  :group 'flyspell
+  :version "21.1"
+  :type 'string)
+
+(defcustom flyspell-check-tex-math-command nil
+  "*Non nil means check even inside TeX math environment.
+TeX math environments are discovered by the TEXMATHP that implemented
+inside the texmathp.el Emacs package.  That package may be found at:
+http://strw.leidenuniv.nl/~dominik/Tools"
+  :group 'flyspell
+  :type 'boolean)
+
+(defcustom flyspell-dictionaries-that-consider-dash-as-word-delimiter
+  '("francais" "deutsch8" "norsk")
+  "List of dictionary names that consider `-' as word delimiter."
+  :group 'flyspell
+  :version "21.1"
+  :type '(repeat (string)))
+
+(defcustom flyspell-abbrev-p
+  nil
+  "*If non-nil, add correction to abbreviation table."
+  :group 'flyspell
+  :version "21.1"
+  :type 'boolean)
+
+(defcustom flyspell-use-global-abbrev-table-p
+  nil
+  "*If non-nil, prefer global abbrev table to local abbrev table."
+  :group 'flyspell
+  :version "21.1"
+  :type 'boolean)
+  
+;;;###autoload
+(defcustom flyspell-mode-line-string " Fly"
+  "*String displayed on the modeline when flyspell is active.
+Set this to nil if you don't want a modeline indicator."
+  :group 'flyspell
+  :type '(choice string (const :tag "None" nil)))
+
+(defcustom flyspell-large-region 1000
+  "*The threshold that determines if a region is small.
+The `flyspell-region' function is invoked if the region is small, the
+word are checked one after the other using regular flyspell check
+means.  If the region is large, a new Ispell process is spawned to get
+speed.
+
+if flyspell-large-region is nil, regions are treated as small."
+  :group 'flyspell
+  :version "21.1"
+  :type '(choice number boolean))
+
+(defcustom flyspell-insert-function (function insert)
+  "*Function for inserting word by flyspell upon correction."
+  :group 'flyspell
+  :type 'function)
+
+(defcustom flyspell-before-incorrect-word-string nil
+  "String used to indicate an incorrect word starting."
+  :group 'flyspell
+  :type '(choice string (const nil)))
+
+(defcustom flyspell-after-incorrect-word-string nil
+  "String used to indicate an incorrect word ending."
+  :group 'flyspell
+  :type '(choice string (const nil)))
+
+(defcustom flyspell-use-meta-tab t
+  "*Non-nil means that flyspell uses META-TAB to correct word."
+  :group 'flyspell
+  :type 'boolean)
+
+(defcustom flyspell-auto-correct-binding
+  (cond
+   ((eq flyspell-emacs 'xemacs)
+    [(control \;)])
+   (t
+    [?\C-\;]))
+  "The key binding for flyspell auto correction."
+  :group 'flyspell)
+
+;*---------------------------------------------------------------------*/
+;*    Mode specific options                                            */
+;*    -------------------------------------------------------------    */
+;*    Mode specific options enable users to disable flyspell on        */
+;*    certain word depending of the emacs mode. For instance, when     */
+;*    using flyspell with mail-mode add the following expression       */
+;*    in your .emacs file:                                             */
+;*       (add-hook 'mail-mode                                          */
+;*    	     '(lambda () (setq flyspell-generic-check-word-p           */
+;*    			       'mail-mode-flyspell-verify)))           */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-generic-check-word-p nil
+  "Function providing per-mode customization over which words are flyspelled.
+Returns t to continue checking, nil otherwise.
+Flyspell mode sets this variable to whatever is the `flyspell-mode-predicate'
+property of the major mode name.")
+(make-variable-buffer-local 'flyspell-generic-check-word-p)
+
+;*--- mail mode -------------------------------------------------------*/
+(put 'mail-mode 'flyspell-mode-predicate 'mail-mode-flyspell-verify)
+(put 'message-mode 'flyspell-mode-predicate 'mail-mode-flyspell-verify)
+(defun mail-mode-flyspell-verify ()
+  "This function is used for `flyspell-generic-check-word-p' in Mail mode."
+  (let ((header-end (save-excursion
+		      (goto-char (point-min))
+		      (re-search-forward
+		       (concat "^"
+			       (regexp-quote mail-header-separator)
+			       "$")
+		       nil t)
+		      (point)))
+	(signature-begin (save-excursion
+			   (goto-char (point-max))
+			   (re-search-backward message-signature-separator
+					       nil t)
+			   (point))))
+    (cond ((< (point) header-end)
+	   (and (save-excursion (beginning-of-line)
+				(looking-at "^Subject:"))
+		(> (point) (match-end 0))))
+	  ((> (point) signature-begin)
+	   nil)
+	  (t
+	   (save-excursion
+	     (beginning-of-line)
+	     (not (looking-at "[>}|]\\|To:")))))))
+
+;*--- texinfo mode ----------------------------------------------------*/
+(put 'texinfo-mode 'flyspell-mode-predicate 'texinfo-mode-flyspell-verify)
+(defun texinfo-mode-flyspell-verify ()
+  "This function is used for `flyspell-generic-check-word-p' in Texinfo mode."
+  (save-excursion
+    (forward-word -1)
+    (not (looking-at "@"))))
+
+;*--- tex mode --------------------------------------------------------*/
+(put 'tex-mode 'flyspell-mode-predicate 'tex-mode-flyspell-verify)
+(defun tex-mode-flyspell-verify ()
+  "This function is used for `flyspell-generic-check-word-p' in LaTeX mode."
+  (and
+   (not (save-excursion
+	  (re-search-backward "^[ \t]*%%%[ \t]+Local" (point-min) t)))
+   (not (save-excursion
+	  (let ((this (point-marker))
+		(e (progn (end-of-line) (point-marker))))
+	    (beginning-of-line)
+	    (if (re-search-forward "\\\\\\(cite\\|label\\|ref\\){[^}]*}" e t)
+		(and (>= this (match-beginning 0))
+		     (<= this (match-end 0)) )))))))
+
+;*--- sgml mode -------------------------------------------------------*/
+(put 'sgml-mode 'flyspell-mode-predicate 'sgml-mode-flyspell-verify)
+(put 'html-mode 'flyspell-mode-predicate 'sgml-mode-flyspell-verify)
+
+(defun sgml-mode-flyspell-verify ()
+  "This function is used for `flyspell-generic-check-word-p' in SGML mode."
+  (not (save-excursion
+	 (let ((this (point-marker))
+	       (s (progn (beginning-of-line) (point-marker)))
+	       (e (progn (end-of-line) (point-marker))))
+	   (or (progn
+		 (goto-char this)
+		 (and (re-search-forward  "[^<]*>" e t)
+		      (= (match-beginning 0) this)))
+	       (progn
+		 (goto-char this)
+		 (and (re-search-backward "<[^>]*" s t)
+		      (= (match-end 0) this)))
+	       (and (progn
+		      (goto-char this)
+		      (and (re-search-forward  "[^&]*;" e t)
+			   (= (match-beginning 0) this)))
+		    (progn
+		      (goto-char this)
+		      (and (re-search-backward "&[^;]*" s t)
+			   (= (match-end 0) this)))))))))
+
+;*---------------------------------------------------------------------*/
+;*    Programming mode                                                 */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-prog-text-faces
+  '(font-lock-string-face font-lock-comment-face font-lock-doc-face)
+  "Faces corresponding to text in programming-mode buffers.")
+
+(defun flyspell-generic-progmode-verify ()
+  "Used for `flyspell-generic-check-word-p' in programming modes."
+  (let ((f (get-text-property (point) 'face)))
+    (memq f flyspell-prog-text-faces)))
+
+;;;###autoload
+(defun flyspell-prog-mode ()
+  "Turn on `flyspell-mode' for comments and strings."
+  (interactive)
+  (setq flyspell-generic-check-word-p 'flyspell-generic-progmode-verify)
+  (flyspell-mode 1)
+  (run-hooks 'flyspell-prog-mode-hook))
+
+;*---------------------------------------------------------------------*/
+;*    Overlay compatibility                                            */
+;*---------------------------------------------------------------------*/
+(autoload 'make-overlay            "overlay" "Overlay compatibility kit." t)
+(autoload 'overlayp                "overlay" "Overlay compatibility kit." t)
+(autoload 'overlays-in             "overlay" "Overlay compatibility kit." t)
+(autoload 'delete-overlay          "overlay" "Overlay compatibility kit." t)
+(autoload 'overlays-at             "overlay" "Overlay compatibility kit." t)
+(autoload 'overlay-put             "overlay" "Overlay compatibility kit." t)
+(autoload 'overlay-get             "overlay" "Overlay compatibility kit." t)
+(autoload 'previous-overlay-change "overlay" "Overlay compatibility kit." t)
+
+;*---------------------------------------------------------------------*/
+;*    The minor mode declaration.                                      */
+;*---------------------------------------------------------------------*/
+(eval-when-compile (defvar flyspell-local-mouse-map))
+
+;;;###autoload
+(defvar flyspell-mode nil)
+(make-variable-buffer-local 'flyspell-mode)
+
+(defvar flyspell-mouse-map
+  (let ((map (make-sparse-keymap)))
+    (if flyspell-use-meta-tab
+	(define-key map "\M-\t" #'flyspell-auto-correct-word))
+    (define-key map (if (featurep 'xemacs) [button2] [down-mouse-2])
+      #'flyspell-correct-word)
+    (if (not (featurep 'xemacs))
+	(define-key map [(shift down-mouse-2)] #'flyspell-correct-word))
+    (define-key map flyspell-auto-correct-binding 'flyspell-auto-correct-previous-word)
+    (define-key map [(control \,)] 'flyspell-goto-next-error)
+    (define-key map [(control \.)] 'flyspell-auto-correct-word)
+    map))
+
+;;;###autoload
+(defvar flyspell-mode-map (make-sparse-keymap))
+
+;; mouse, keyboard bindings and misc definition
+(when (or (assoc 'flyspell-mode minor-mode-map-alist)
+	  (setq minor-mode-map-alist
+		(cons (cons 'flyspell-mode flyspell-mode-map)
+		      minor-mode-map-alist)))
+  (if flyspell-use-meta-tab
+      (define-key flyspell-mode-map "\M-\t" 'flyspell-auto-correct-word))
+  (cond
+   ((eq flyspell-emacs 'xemacs)
+    (define-key flyspell-mode-map flyspell-auto-correct-binding 'flyspell-auto-correct-previous-word)
+    (define-key flyspell-mode-map [(control \,)] 'flyspell-goto-next-error)
+    (define-key flyspell-mode-map [(control \.)] 'flyspell-auto-correct-word))
+   (flyspell-use-local-map
+    (define-key flyspell-mode-map flyspell-auto-correct-binding 'flyspell-auto-correct-previous-word)
+    (define-key flyspell-mode-map [?\C-\,] 'flyspell-goto-next-error)
+    (define-key flyspell-mode-map [?\C-\.] 'flyspell-auto-correct-word))))
+
+
+;; the name of the overlay property that defines the keymap
+(defvar flyspell-overlay-keymap-property-name 'keymap)
+
+;; dash character machinery
+(defvar flyspell-consider-dash-as-word-delimiter-flag nil
+   "*Non-nil means that the `-' char is considered as a word delimiter.")
+(make-variable-buffer-local 'flyspell-consider-dash-as-word-delimiter-flag)
+(defvar flyspell-dash-dictionary nil)
+(make-variable-buffer-local 'flyspell-dash-dictionary)
+(defvar flyspell-dash-local-dictionary nil)
+(make-variable-buffer-local 'flyspell-dash-local-dictionary)
+
+;*---------------------------------------------------------------------*/
+;*    Highlighting                                                     */
+;*---------------------------------------------------------------------*/
+(defface flyspell-incorrect-face
+  (if (eq flyspell-emacs 'xemacs)
+      '((((class color)) (:foreground "OrangeRed" :bold t :underline t))
+	(t (:bold t)))
+    '((((class color)) (:foreground "OrangeRed" :weight bold :underline t))
+      (t (:weight bold))))
+  "Face used for marking a misspelled word in Flyspell."
+  :group 'flyspell)
+
+(defface flyspell-duplicate-face
+  (if (eq flyspell-emacs 'xemacs)
+      '((((class color)) (:foreground "Gold3" :bold t :underline t))
+	(t (:bold t)))
+    '((((class color)) (:foreground "Gold3" :weight bold :underline t))
+      (t (:weight bold))))
+  "Face used for marking a misspelled word that appears twice in the buffer.
+See also `flyspell-duplicate-distance'."
+  :group 'flyspell)
+
+(defvar flyspell-overlay nil)
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-mode ...                                                */
+;*---------------------------------------------------------------------*/
+;;;###autoload
+(defun flyspell-mode (&optional arg)
+  "Minor mode performing on-the-fly spelling checking.
+Ispell is automatically spawned on background for each entered words.
+The default flyspell behavior is to highlight incorrect words.
+With no argument, this command toggles Flyspell mode.
+With a prefix argument ARG, turn Flyspell minor mode on iff ARG is positive.
+  
+Bindings:
+\\[ispell-word]: correct words (using Ispell).
+\\[flyspell-auto-correct-word]: automatically correct word.
+\\[flyspell-auto-correct-previous-word]: automatically correct the last misspelled word.
+\\[flyspell-correct-word] (or down-mouse-2): popup correct words.
+
+Hooks:
+This runs `flyspell-mode-hook' after flyspell is entered.
+
+Remark:
+`flyspell-mode' uses `ispell-mode'.  Thus all Ispell options are
+valid.  For instance, a personal dictionary can be used by
+invoking `ispell-change-dictionary'.
+
+Consider using the `ispell-parser' to check your text.  For instance
+consider adding:
+\(add-hook 'tex-mode-hook (function (lambda () (setq ispell-parser 'tex))))
+in your .emacs file.
+
+\\[flyspell-region] checks all words inside a region.
+\\[flyspell-buffer] checks the whole buffer."
+  (interactive "P")
+  (let ((old-flyspell-mode flyspell-mode))
+    ;; Mark the mode as on or off.
+    (setq flyspell-mode (not (or (and (null arg) flyspell-mode)
+				 (<= (prefix-numeric-value arg) 0))))
+    ;; Do the real work.
+    (unless (eq flyspell-mode old-flyspell-mode)
+      (if flyspell-mode
+	  (flyspell-mode-on)
+	(flyspell-mode-off))
+      ;; Force modeline redisplay.
+      (set-buffer-modified-p (buffer-modified-p)))))
+
+;*---------------------------------------------------------------------*/
+;*    Autoloading                                                      */
+;*---------------------------------------------------------------------*/
+;;;###autoload
+(if (fboundp 'add-minor-mode)
+    (add-minor-mode 'flyspell-mode
+		    'flyspell-mode-line-string
+		    flyspell-mode-map
+		    nil
+		    'flyspell-mode)
+  (or (assoc 'flyspell-mode minor-mode-alist)
+      (setq minor-mode-alist
+	    (cons '(flyspell-mode flyspell-mode-line-string)
+		  minor-mode-alist)))
+
+  (or (assoc 'flyspell-mode minor-mode-map-alist)
+      (setq minor-mode-map-alist
+	    (cons (cons 'flyspell-mode flyspell-mode-map)
+		  minor-mode-map-alist))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-buffers ...                                             */
+;*    -------------------------------------------------------------    */
+;*    For remembering buffers running flyspell                         */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-buffers nil)
+ 
+;*---------------------------------------------------------------------*/
+;*    flyspell-minibuffer-p ...                                        */
+;*---------------------------------------------------------------------*/
+(defun flyspell-minibuffer-p (buffer)
+  "Is BUFFER a minibuffer?"
+  (let ((ws (get-buffer-window-list buffer t)))
+    (and (consp ws) (window-minibuffer-p (car ws)))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-version ...                                             */
+;*---------------------------------------------------------------------*/
+;;;###autoload
+(defun flyspell-version ()
+  "The flyspell version"
+  (interactive)
+  "1.7o")
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-accept-buffer-local-defs ...                            */
+;*---------------------------------------------------------------------*/
+(defun flyspell-accept-buffer-local-defs ()
+  ;; strange problem.  If buffer in current window has font-lock turned on,
+  ;; but SET-BUFFER was called to point to an invisible buffer, this ispell
+  ;; call will reset the buffer to the buffer in the current window.  However,
+  ;; it only happens at startup (fix by Albert L. Ting).
+  (let ((buf (current-buffer)))
+    (ispell-accept-buffer-local-defs)
+    (set-buffer buf))
+  (if (not (and (eq flyspell-dash-dictionary ispell-dictionary)
+		(eq flyspell-dash-local-dictionary ispell-local-dictionary)))
+      ;; the dictionary has changed
+      (progn
+	(setq flyspell-dash-dictionary ispell-dictionary)
+	(setq flyspell-dash-local-dictionary ispell-local-dictionary)
+	(if (member (or ispell-local-dictionary ispell-dictionary)
+		    flyspell-dictionaries-that-consider-dash-as-word-delimiter)
+	    (setq flyspell-consider-dash-as-word-delimiter-flag t)
+	  (setq flyspell-consider-dash-as-word-delimiter-flag nil)))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-mode-on ...                                             */
+;*---------------------------------------------------------------------*/
+(defun flyspell-mode-on ()
+  "Turn Flyspell mode on.  Do not use this; use `flyspell-mode' instead."
+  (setq ispell-highlight-face 'flyspell-incorrect-face)
+  ;; local dictionaries setup
+  (ispell-change-dictionary
+   (or ispell-local-dictionary ispell-dictionary flyspell-default-dictionary))
+  ;; we have to force ispell to accept the local definition or
+  ;; otherwise it could be too late, the local dictionary may
+  ;; be forgotten!
+  (flyspell-accept-buffer-local-defs)
+  ;; we put the `flyspell-delayed' property on some commands
+  (flyspell-delay-commands)
+  ;; we put the `flyspell-deplacement' property on some commands
+  (flyspell-deplacement-commands)
+  ;; we put the `flyspell-ignored' property on some commands
+  (flyspell-ignore-commands)
+  ;; we bound flyspell action to post-command hook
+  (if (eq flyspell-emacs 'xemacs)
+      (make-local-hook 'post-command-hook))
+  (add-hook 'post-command-hook (function flyspell-post-command-hook) t t)
+  ;; we bound flyspell action to pre-command hook
+  (if (eq flyspell-emacs 'xemacs)
+      (make-local-hook 'pre-command-hook))
+  (add-hook 'pre-command-hook (function flyspell-pre-command-hook) t t)
+  ;; we bound flyspell action to after-change hook
+  (make-local-variable 'after-change-functions)
+  (setq after-change-functions
+	(cons 'flyspell-after-change-function after-change-functions))
+  ;; set flyspell-generic-check-word-p based on the major mode
+  (let ((mode-predicate (get major-mode 'flyspell-mode-predicate)))
+    (if mode-predicate
+	(setq flyspell-generic-check-word-p mode-predicate)))
+  ;; work around the fact that the `local-map' text-property replaces the
+  ;; buffer's local map rather than shadowing it.
+  (set (make-local-variable 'flyspell-mouse-map)
+       (let ((map (copy-keymap flyspell-mouse-map)))
+	 (set-keymap-parent map (current-local-map))
+	 (if (and (eq flyspell-emacs 'emacs)
+		  (not (string< emacs-version "20")))
+	     (define-key map '[tool-bar] nil))
+	 map))
+  (set (make-local-variable 'flyspell-mode-map)
+       (let ((map (copy-keymap flyspell-mode-map)))
+ 	 (set-keymap-parent map (current-local-map))
+	 (if (and (eq flyspell-emacs 'emacs)
+		  (not (string< emacs-version "20")))
+	     (define-key map '[tool-bar] nil))
+ 	 map))
+  ;; the welcome message
+  (if (and flyspell-issue-message-flag
+	   flyspell-issue-welcome-flag
+	   (interactive-p))
+      (let ((binding (where-is-internal 'flyspell-auto-correct-word
+					nil 'non-ascii)))
+	(message
+	 (if binding
+	     (format "Welcome to flyspell. Use %s or Mouse-2 to correct words."
+		     (key-description binding))
+	   "Welcome to flyspell. Use Mouse-2 to correct words."))))
+  ;; we end with the flyspell hooks
+  (run-hooks 'flyspell-mode-hook))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-delay-commands ...                                      */
+;*---------------------------------------------------------------------*/
+(defun flyspell-delay-commands ()
+  "Install the standard set of Flyspell delayed commands."
+  (mapcar 'flyspell-delay-command flyspell-default-delayed-commands)
+  (mapcar 'flyspell-delay-command flyspell-delayed-commands))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-delay-command ...                                       */
+;*---------------------------------------------------------------------*/
+(defun flyspell-delay-command (command)
+  "Set COMMAND to be delayed, for Flyspell.
+When flyspell `post-command-hook' is invoked because a delayed command
+as been used the current word is not immediately checked.
+It will be checked only after `flyspell-delay' seconds."
+  (interactive "SDelay Flyspell after Command: ")
+  (put command 'flyspell-delayed t))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-deplacement-commands ...                                */
+;*---------------------------------------------------------------------*/
+(defun flyspell-deplacement-commands ()
+  "Install the standard set of Flyspell deplacement commands."
+  (mapcar 'flyspell-deplacement-command flyspell-default-deplacement-commands)
+  (mapcar 'flyspell-deplacement-command flyspell-deplacement-commands))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-deplacement-command ...                                 */
+;*---------------------------------------------------------------------*/
+(defun flyspell-deplacement-command (command)
+  "Set COMMAND that implement cursor movements, for Flyspell.
+When flyspell `post-command-hook' is invoked because of a deplacement command
+as been used the current word is checked only if the previous command was
+not the very same deplacement command."
+  (interactive "SDeplacement Flyspell after Command: ")
+  (put command 'flyspell-deplacement t))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-ignore-commands ...                                     */
+;*---------------------------------------------------------------------*/
+(defun flyspell-ignore-commands ()
+  "Install the standard set of Flyspell ignored commands."
+  (mapcar 'flyspell-ignore-command flyspell-default-ignored-commands)
+  (mapcar 'flyspell-ignore-command flyspell-ignored-commands))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-ignore-command ...                                      */
+;*---------------------------------------------------------------------*/
+(defun flyspell-ignore-command (command)
+  "Set COMMAND to be ignored, for Flyspell.
+When flyspell `post-command-hook' is invoked because of an
+ignored command having been used, the changes in the text made by
+that command are ignored.  This feature is meant for commands that
+change text in a way that does not affect individual words, such
+as `fill-paragraph'."  
+  (interactive "SMake Flyspell ignore changes made by Command: ")
+  (put command 'flyspell-ignored t))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-word-cache ...                                          */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-word-cache-start  nil)
+(defvar flyspell-word-cache-end    nil)
+(defvar flyspell-word-cache-word   nil)
+(defvar flyspell-word-cache-result '_)
+(make-variable-buffer-local 'flyspell-word-cache-start)
+(make-variable-buffer-local 'flyspell-word-cache-end)
+(make-variable-buffer-local 'flyspell-word-cache-word)
+(make-variable-buffer-local 'flyspell-word-cache-result)
+
+;*---------------------------------------------------------------------*/
+;*    The flyspell pre-hook, store the current position. In the        */
+;*    post command hook, we will check, if the word at this position   */
+;*    has to be spell checked.                                         */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-pre-buffer     nil)
+(defvar flyspell-pre-point      nil)
+(defvar flyspell-pre-column     nil)
+(defvar flyspell-pre-pre-buffer nil)
+(defvar flyspell-pre-pre-point  nil)
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-previous-command ...                                    */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-previous-command nil
+  "The last interactive command checked by Flyspell.")
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-pre-command-hook ...                                    */
+;*---------------------------------------------------------------------*/
+(defun flyspell-pre-command-hook ()
+  "Save the current buffer and point for Flyspell's post-command hook."
+  (interactive)
+  (setq flyspell-pre-buffer (current-buffer))
+  (setq flyspell-pre-point  (point))
+  (setq flyspell-pre-column (current-column)))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-mode-off ...                                            */
+;*---------------------------------------------------------------------*/
+;;;###autoload
+(defun flyspell-mode-off ()
+  "Turn Flyspell mode off."
+  ;; we remove the hooks
+  (remove-hook 'post-command-hook (function flyspell-post-command-hook) t)
+  (remove-hook 'pre-command-hook (function flyspell-pre-command-hook) t)
+  (setq after-change-functions (delq 'flyspell-after-change-function
+				     after-change-functions))
+  ;; we remove all the flyspell hilightings
+  (flyspell-delete-all-overlays)
+  ;; we have to erase pre cache variables
+  (setq flyspell-pre-buffer nil)
+  (setq flyspell-pre-point  nil)
+  ;; we mark the mode as killed
+  (setq flyspell-mode nil))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-check-pre-word-p ...                                    */
+;*---------------------------------------------------------------------*/
+(defun flyspell-check-pre-word-p ()
+  "Return non-nil if we should check the word before point.
+More precisely, it applies to the word that was before point
+before the current command."
+  (cond
+   ((or (not (numberp flyspell-pre-point))
+	(not (bufferp flyspell-pre-buffer))
+	(not (buffer-live-p flyspell-pre-buffer)))
+    nil)
+   ((and (eq flyspell-pre-pre-point flyspell-pre-point)
+	 (eq flyspell-pre-pre-buffer flyspell-pre-buffer))
+    nil)
+   ((or (and (= flyspell-pre-point (- (point) 1))
+	     (eq (char-syntax (char-after flyspell-pre-point)) ?w))
+	(= flyspell-pre-point (point))
+	(= flyspell-pre-point (+ (point) 1)))
+    nil)
+   ((and (symbolp this-command)
+	 (not executing-kbd-macro)
+	 (or (get this-command 'flyspell-delayed)
+	     (and (get this-command 'flyspell-deplacement)
+		  (eq flyspell-previous-command this-command)))
+	 (or (= (current-column) 0)
+	     (= (current-column) flyspell-pre-column)
+	     (eq (char-syntax (char-after flyspell-pre-point)) ?w)))
+    nil)
+   ((not (eq (current-buffer) flyspell-pre-buffer))
+    t)
+   ((not (and (numberp flyspell-word-cache-start)
+	      (numberp flyspell-word-cache-end)))
+    t)
+   (t
+    (or (< flyspell-pre-point flyspell-word-cache-start)
+	(> flyspell-pre-point flyspell-word-cache-end)))))
+
+;*---------------------------------------------------------------------*/
+;*    The flyspell after-change-hook, store the change position. In    */
+;*    the post command hook, we will check, if the word at this        */
+;*    position has to be spell checked.                                */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-changes nil)
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-after-change-function ...                               */
+;*---------------------------------------------------------------------*/
+(defun flyspell-after-change-function (start stop len)
+  "Save the current buffer and point for Flyspell's post-command hook."
+  (interactive)
+  (unless (and (symbolp this-command) (get this-command 'flyspell-ignored))
+    (setq flyspell-changes (cons (cons start stop) flyspell-changes))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-check-changed-word-p ...                                */
+;*---------------------------------------------------------------------*/
+(defun flyspell-check-changed-word-p (start stop)
+  "Return t when the changed word has to be checked.
+The answer depends of several criteria.
+Mostly we check word delimiters."
+  (cond
+   ((and (memq (char-after start) '(?\n ? )) (> stop start))
+    t)
+   ((not (numberp flyspell-pre-point))
+    t)
+   ((and (>= flyspell-pre-point start) (<= flyspell-pre-point stop))
+    nil)
+   ((let ((pos (point)))
+      (or (>= pos start) (<= pos stop) (= pos (1+ stop))))
+    nil)
+   (t
+    t)))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-check-word-p ...                                        */
+;*---------------------------------------------------------------------*/
+(defun flyspell-check-word-p ()
+  "Return t when the word at `point' has to be checked.
+The answer depends of several criteria.
+Mostly we check word delimiters."
+  (cond
+   ((<= (- (point-max) 1) (point-min))
+    ;; the buffer is not filled enough
+    nil)
+   ((and (and (> (current-column) 0)
+	      (not (eq (current-column) flyspell-pre-column)))
+	 (save-excursion
+	   (backward-char 1)
+	   (and (looking-at (flyspell-get-not-casechars))
+		(or flyspell-consider-dash-as-word-delimiter-flag
+		    (not (looking-at "\\-"))))))
+    ;; yes because we have reached or typed a word delimiter.
+    t)
+   ((symbolp this-command)
+    (cond
+     ((get this-command 'flyspell-deplacement)
+      (not (eq flyspell-previous-command this-command)))
+     ((get this-command 'flyspell-delayed)
+      ;; the current command is not delayed, that
+      ;; is that we must check the word now
+      (if (or (fboundp 'about-xemacs) (featurep 'xemacs))
+	  (sit-for flyspell-delay nil)
+	(sit-for flyspell-delay 0 nil)))
+     (t t)))
+   (t t)))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-debug-signal-no-check ...                               */
+;*---------------------------------------------------------------------*/
+(defun flyspell-debug-signal-no-check (msg obj)
+  (setq debug-on-error t)
+  (save-excursion
+    (let ((buffer (get-buffer-create "*flyspell-debug*")))
+      (set-buffer buffer)
+      (erase-buffer)
+      (insert "NO-CHECK:\n")
+      (insert (format "    %S : %S\n" msg obj)))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-debug-signal-pre-word-checked ...                       */ 
+;*---------------------------------------------------------------------*/
+(defun flyspell-debug-signal-pre-word-checked ()
+  (setq debug-on-error t)
+  (save-excursion
+    (let ((buffer (get-buffer-create "*flyspell-debug*")))
+      (set-buffer buffer)
+      (insert "PRE-WORD:\n")
+      (insert (format "  pre-point  : %S\n" flyspell-pre-point))
+      (insert (format "  pre-buffer : %S\n" flyspell-pre-buffer))
+      (insert (format "  cache-start: %S\n" flyspell-word-cache-start))
+      (insert (format "  cache-end  : %S\n" flyspell-word-cache-end))
+      (goto-char (point-max)))))
+    
+;*---------------------------------------------------------------------*/
+;*    flyspell-debug-signal-word-checked ...                           */ 
+;*---------------------------------------------------------------------*/
+(defun flyspell-debug-signal-word-checked ()
+  (setq debug-on-error t)
+  (save-excursion
+    (let ((oldbuf (current-buffer))
+	  (buffer (get-buffer-create "*flyspell-debug*"))
+	  (point  (point)))
+      (set-buffer buffer)
+      (insert "WORD:\n")
+      (insert (format "  this-cmd   : %S\n" this-command))
+      (insert (format "  delayed    : %S\n" (and (symbolp this-command)
+						 (get this-command 'flyspell-delayed))))
+      (insert (format "  ignored    : %S\n" (and (symbolp this-command)
+ 						 (get this-command 'flyspell-ignored))))
+      (insert (format "  point      : %S\n" point))
+      (insert (format "  prev-char  : [%c] %S\n"
+		      (progn
+			(set-buffer oldbuf)
+			(let ((c (if (> (point) (point-min))
+				     (save-excursion
+				       (backward-char 1)
+				       (char-after (point)))
+				   ? )))
+			  (set-buffer buffer)
+			  c))
+		      (progn
+			(set-buffer oldbuf)
+			(let ((c (if (> (point) (point-min))
+				     (save-excursion
+				       (backward-char 1)
+				       (and (and (looking-at (flyspell-get-not-casechars)) 1)
+					    (and (or flyspell-consider-dash-as-word-delimiter-flag
+						     (not (looking-at "\\-"))) 2))))))
+			  (set-buffer buffer)
+			  c))))
+      (insert (format "  because    : %S\n"
+		      (cond
+		       ((not (and (symbolp this-command)
+				  (get this-command 'flyspell-delayed)))
+			;; the current command is not delayed, that
+			;; is that we must check the word now
+			'not-delayed)
+		       ((progn
+			  (set-buffer oldbuf)
+			  (let ((c (if (> (point) (point-min))
+				       (save-excursion
+					 (backward-char 1)
+					 (and (looking-at (flyspell-get-not-casechars))
+					      (or flyspell-consider-dash-as-word-delimiter-flag
+						  (not (looking-at "\\-"))))))))
+			    (set-buffer buffer)
+			    c))
+			;; yes because we have reached or typed a word delimiter.
+			'separator)
+		       ((not (integerp flyspell-delay))
+			;; yes because the user had set up a no-delay configuration.
+			'no-delay)
+		       (t
+			'sit-for))))
+      (goto-char (point-max)))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-debug-signal-changed-checked ...                        */ 
+;*---------------------------------------------------------------------*/
+(defun flyspell-debug-signal-changed-checked ()
+  (setq debug-on-error t)
+  (save-excursion
+    (let ((buffer (get-buffer-create "*flyspell-debug*"))
+	  (point  (point)))
+      (set-buffer buffer)
+      (insert "CHANGED WORD:\n")
+      (insert (format "  point   : %S\n" point))
+      (goto-char (point-max)))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-post-command-hook ...                                   */
+;*    -------------------------------------------------------------    */
+;*    It is possible that we check several words:                      */
+;*    1- the current word is checked if the predicate                  */
+;*       FLYSPELL-CHECK-WORD-P is true                                 */
+;*    2- the word that used to be the current word before the          */
+;*       THIS-COMMAND is checked if:                                   */
+;*        a- the previous word is different from the current word      */
+;*        b- the previous word as not just been checked by the         */
+;*           previous FLYSPELL-POST-COMMAND-HOOK                       */
+;*    3- the words changed by the THIS-COMMAND that are neither the    */
+;*       previous word nor the current word                            */
+;*---------------------------------------------------------------------*/
+(defun flyspell-post-command-hook ()
+  "The `post-command-hook' used by flyspell to check a word in-the-fly."
+  (interactive)
+  (let ((command this-command))
+    (if (flyspell-check-pre-word-p)
+	(save-excursion
+	  '(flyspell-debug-signal-pre-word-checked)
+	  (set-buffer flyspell-pre-buffer)
+	  (save-excursion
+	    (goto-char flyspell-pre-point)
+	    (flyspell-word))))
+    (if (flyspell-check-word-p)
+	(progn
+	  '(flyspell-debug-signal-word-checked)
+	  (flyspell-word)
+	  ;; we remember which word we have just checked.
+	  ;; this will be used next time we will check a word
+	  ;; to compare the next current word with the word
+	  ;; that as been registered in the pre-command-hook
+	  ;; that is these variables are used within the predicate
+	  ;; FLYSPELL-CHECK-PRE-WORD-P
+	  (setq flyspell-pre-pre-buffer (current-buffer))
+	  (setq flyspell-pre-pre-point  (point)))
+      (progn
+	(setq flyspell-pre-pre-buffer nil)
+	(setq flyspell-pre-pre-point  nil)
+	;; when a word is not checked because of a delayed command
+	;; we do not disable the ispell cache.
+	(if (and (symbolp this-command) (get this-command 'flyspell-delayed))
+	    (progn
+	      (setq flyspell-word-cache-end -1)
+	      (setq flyspell-word-cache-result '_)))))
+    (while (consp flyspell-changes)
+      (let ((start (car (car flyspell-changes)))
+	    (stop  (cdr (car flyspell-changes))))
+	(if (flyspell-check-changed-word-p start stop)
+	    (save-excursion
+	      '(flyspell-debug-signal-changed-checked)
+	      (goto-char start)
+	      (flyspell-word)))
+	(setq flyspell-changes (cdr flyspell-changes))))
+    (setq flyspell-previous-command command)))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-notify-misspell ...                                     */
+;*---------------------------------------------------------------------*/
+(defun flyspell-notify-misspell (start end word poss)
+  (let ((replacements (if (stringp poss)
+			  poss
+			(if flyspell-sort-corrections
+			    (sort (car (cdr (cdr poss))) 'string<)
+			  (car (cdr (cdr poss)))))))
+    (if flyspell-issue-message-flag
+	(message (format "mispelling `%s'  %S" word replacements)))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-word-search-backward ...                                */
+;*---------------------------------------------------------------------*/
+(defun flyspell-word-search-backward (word bound)
+  (save-excursion
+    (let ((r '())
+	  p)
+      (while (and (not r) (setq p (search-backward word bound t)))
+	(let ((lw (flyspell-get-word '())))
+	  (if (and (consp lw) (string-equal (car lw) word))
+	      (setq r p)
+	    (goto-char p))))
+      r)))
+	  
+;*---------------------------------------------------------------------*/
+;*    flyspell-word-search-forward ...                                 */
+;*---------------------------------------------------------------------*/
+(defun flyspell-word-search-forward (word bound)
+  (save-excursion
+    (let ((r '())
+	  p)
+      (while (and (not r) (setq p (search-forward word bound t)))
+	(let ((lw (flyspell-get-word '())))
+	  (if (and (consp lw) (string-equal (car lw) word))
+	      (setq r p)
+	    (goto-char (1+ p)))))
+      r)))
+	  
+;*---------------------------------------------------------------------*/
+;*    flyspell-word ...                                                */
+;*---------------------------------------------------------------------*/
+(defun flyspell-word (&optional following)
+  "Spell check a word."
+  (interactive (list current-prefix-arg))
+  (if (interactive-p)
+      (setq following ispell-following-word))
+  (save-excursion
+    ;; use the correct dictionary
+    (flyspell-accept-buffer-local-defs)	
+    (let* ((cursor-location (point))
+	  (flyspell-word (flyspell-get-word following))
+	  start end poss word)
+      (if (or (eq flyspell-word nil)
+ 	      (and (fboundp flyspell-generic-check-word-p)
+ 		   (not (funcall flyspell-generic-check-word-p))))
+	  t
+	(progn
+	  ;; destructure return flyspell-word info list.
+	  (setq start (car (cdr flyspell-word))
+		end (car (cdr (cdr flyspell-word)))
+		word (car flyspell-word))
+	  ;; before checking in the directory, we check for doublons.
+	  (cond
+	   ((and (or (not (eq ispell-parser 'tex))
+		     (and (> start (point-min))
+			  (not (eq (char-after (1- start)) ?}))
+			  (not (eq (char-after (1- start)) ?\\))))
+		 flyspell-mark-duplications-flag
+		 (save-excursion
+		   (goto-char (1- start))
+		   (let ((p (flyspell-word-search-backward 
+			     word
+			     (- start (1+ (- end start))))))
+		     (and p (/= p (1- start))))))
+	    ;; yes, this is a doublon
+	    (flyspell-highlight-incorrect-region start end 'doublon)
+	    nil)
+	   ((and (eq flyspell-word-cache-start start)
+		 (eq flyspell-word-cache-end end)
+		 (string-equal flyspell-word-cache-word word))
+	    ;; this word had been already checked, we skip
+	    flyspell-word-cache-result)
+	   ((and (eq ispell-parser 'tex)
+		 (flyspell-tex-command-p flyspell-word))
+	    ;; this is a correct word (because a tex command)
+	    (flyspell-unhighlight-at start)
+	    (if (> end start)
+		(flyspell-unhighlight-at (- end 1)))
+	    t)
+	   (t
+	    ;; we setup the cache
+	    (setq flyspell-word-cache-start start)
+	    (setq flyspell-word-cache-end end)
+	    (setq flyspell-word-cache-word word)
+	    ;; now check spelling of word.
+	    (process-send-string ispell-process "%\n")
+	    ;; put in verbose mode
+	    (process-send-string ispell-process
+				 (concat "^" word "\n"))
+	    ;; we mark the ispell process so it can be killed
+	    ;; when emacs is exited without query
+	    (if (fboundp 'process-kill-without-query)
+		(process-kill-without-query ispell-process))
+	    ;; wait until ispell has processed word
+	    (while (progn
+		     (accept-process-output ispell-process)
+		     (not (string= "" (car ispell-filter)))))
+	    ;; (process-send-string ispell-process "!\n")
+	    ;; back to terse mode.
+	    (setq ispell-filter (cdr ispell-filter))
+	    (if (consp ispell-filter)
+		(setq poss (ispell-parse-output (car ispell-filter))))
+	    (let ((res (cond ((eq poss t)
+			      ;; correct
+			      (setq flyspell-word-cache-result t)
+			      (flyspell-unhighlight-at start)
+			      (if (> end start)
+				  (flyspell-unhighlight-at (- end 1)))
+			      t)
+			     ((and (stringp poss) flyspell-highlight-flag)
+			      ;; correct
+			      (setq flyspell-word-cache-result t)
+			      (flyspell-unhighlight-at start)
+			      (if (> end start)
+				  (flyspell-unhighlight-at (- end 1)))
+			      t)
+			     ((null poss)
+			      (setq flyspell-word-cache-result t)
+			      (flyspell-unhighlight-at start)
+			      (if (> end start)
+				  (flyspell-unhighlight-at (- end 1)))
+			      t)
+			     ((or (and (< flyspell-duplicate-distance 0)
+				       (or (save-excursion
+					     (goto-char start)
+					     (flyspell-word-search-backward
+					      word
+					      (point-min)))
+					   (save-excursion
+					     (goto-char end)
+					     (flyspell-word-search-forward
+					      word
+					      (point-max)))))
+				  (and (> flyspell-duplicate-distance 0)
+				       (or (save-excursion
+					     (goto-char start)
+					     (flyspell-word-search-backward
+					      word
+					      (- start
+						 flyspell-duplicate-distance)))
+					   (save-excursion
+					     (goto-char end)
+					     (flyspell-word-search-forward
+					      word
+					      (+ end
+						 flyspell-duplicate-distance))))))
+			      (setq flyspell-word-cache-result nil)
+			      (if flyspell-highlight-flag
+				  (flyspell-highlight-duplicate-region
+				   start end)
+				(message (format "duplicate `%s'" word)))
+			      nil)
+			     (t
+			      (setq flyspell-word-cache-result nil)
+			      ;; incorrect highlight the location
+			      (if flyspell-highlight-flag
+				  (flyspell-highlight-incorrect-region
+				   start end poss)
+				(flyspell-notify-misspell start end word poss))
+			      nil))))
+	      ;; return to original location
+	      (goto-char cursor-location) 
+	      (if ispell-quit (setq ispell-quit nil))
+	      res))))))))
+
+;* {*---------------------------------------------------------------------*} */
+;* {*    flyspell-tex-math-initialized ...                                *} */
+;* {*---------------------------------------------------------------------*} */
+;* (defvar flyspell-tex-math-initialized nil)                          */
+;*                                                                     */
+;* {*---------------------------------------------------------------------*} */
+;* {*    flyspell-math-tex-command-p ...                                  *} */
+;* {*    -------------------------------------------------------------    *} */
+;* {*    This function uses the texmathp package to check if (point)      *} */
+;* {*    is within a tex command. In order to avoid using                 *} */
+;* {*    condition-case each time we use the variable                     *} */
+;* {*    flyspell-tex-math-initialized to make a special case the first   *} */
+;* {*    time that function is called.                                    *} */
+;* {*---------------------------------------------------------------------*} */
+;* (defun flyspell-math-tex-command-p ()                               */
+;*   (cond                                                             */
+;*    (flyspell-check-tex-math-command                                 */
+;*     nil)                                                            */
+;*    ((eq flyspell-tex-math-initialized t)                            */
+;*     (texmathp))                                                     */
+;*    ((eq flyspell-tex-math-initialized 'error)                       */
+;*     nil)                                                            */
+;*    (t                                                               */
+;*     (setq flyspell-tex-math-initialized t)                          */
+;*     (condition-case nil                                             */
+;* 	(texmathp)                                                     */
+;*       (error (progn                                                 */
+;* 	       (setq flyspell-tex-math-initialized 'error)             */
+;* 	       nil))))))                                               */
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-math-tex-command-p ...                                  */
+;*    -------------------------------------------------------------    */
+;*    This function uses the texmathp package to check if point        */
+;*    is within a TeX math environment. `texmathp' can yield errors    */
+;*    if the document is currently not valid TeX syntax.               */
+;*---------------------------------------------------------------------*/
+(defun flyspell-math-tex-command-p ()
+  (when (fboundp 'texmathp)
+    (if flyspell-check-tex-math-command
+        nil
+      (condition-case nil
+	  (texmathp)
+	(error nil)))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-tex-command-p ...                                       */
+;*---------------------------------------------------------------------*/
+(defun flyspell-tex-command-p (word)
+  "Return t if WORD is a TeX command."
+  (or (save-excursion
+	(let ((b  (car (cdr word))))
+	  (and (re-search-backward "\\\\" (- (point) 100) t)
+	       (or (= (match-end 0) b)
+		   (and (goto-char (match-end 0))
+			(looking-at flyspell-tex-command-regexp)
+			(>= (match-end 0) b))))))
+      (flyspell-math-tex-command-p)))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-casechars-cache ...                                     */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-casechars-cache nil)
+(defvar flyspell-ispell-casechars-cache nil)
+(make-variable-buffer-local 'flyspell-casechars-cache)
+(make-variable-buffer-local 'flyspell-ispell-casechars-cache)
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-get-casechars ...                                       */
+;*---------------------------------------------------------------------*/
+(defun flyspell-get-casechars ()
+  "This function builds a string that is the regexp of word chars.
+In order to avoid one useless string construction,
+this function changes the last char of the `ispell-casechars' string."
+  (let ((ispell-casechars (ispell-get-casechars)))
+    (cond
+     ((eq ispell-parser 'tex)
+      (setq flyspell-ispell-casechars-cache ispell-casechars)
+      (setq flyspell-casechars-cache
+	    (concat (substring ispell-casechars
+			       0
+			       (- (length ispell-casechars) 1))
+		    "]"))
+      flyspell-casechars-cache)
+     (t
+      (setq flyspell-ispell-casechars-cache ispell-casechars)
+      (setq flyspell-casechars-cache ispell-casechars)
+      flyspell-casechars-cache))))
+	
+;*---------------------------------------------------------------------*/
+;*    flyspell-get-not-casechars-cache ...                             */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-not-casechars-cache nil)
+(defvar flyspell-ispell-not-casechars-cache nil)
+(make-variable-buffer-local 'flyspell-not-casechars-cache)
+(make-variable-buffer-local 'flyspell-ispell-not-casechars-cache)
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-get-not-casechars ...                                   */
+;*---------------------------------------------------------------------*/
+(defun flyspell-get-not-casechars ()
+  "This function builds a string that is the regexp of non-word chars."
+  (let ((ispell-not-casechars (ispell-get-not-casechars)))
+    (cond
+     ((eq ispell-parser 'tex)
+      (setq flyspell-ispell-not-casechars-cache ispell-not-casechars)
+      (setq flyspell-not-casechars-cache
+	    (concat (substring ispell-not-casechars
+			       0
+			       (- (length ispell-not-casechars) 1))
+		    "]"))
+      flyspell-not-casechars-cache)
+     (t
+      (setq flyspell-ispell-not-casechars-cache ispell-not-casechars)
+      (setq flyspell-not-casechars-cache ispell-not-casechars)
+      flyspell-not-casechars-cache))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-get-word ...                                            */
+;*---------------------------------------------------------------------*/
+(defun flyspell-get-word (following &optional extra-otherchars)
+  "Return the word for spell-checking according to Ispell syntax.
+If optional argument FOLLOWING is non-nil or if `flyspell-following-word'
+is non-nil when called interactively, then the following word
+\(rather than preceding\) is checked when the cursor is not over a word.
+Optional second argument contains otherchars that can be included in word
+many times.
+
+Word syntax described by `flyspell-dictionary-alist' (which see)."
+  (let* ((flyspell-casechars (flyspell-get-casechars))
+	 (flyspell-not-casechars (flyspell-get-not-casechars))
+	 (ispell-otherchars (ispell-get-otherchars))
+	 (ispell-many-otherchars-p (ispell-get-many-otherchars-p))
+	 (word-regexp (concat flyspell-casechars
+			      "+\\("
+			      (if (not (string= "" ispell-otherchars))
+				  (concat ispell-otherchars "?"))
+			      (if extra-otherchars
+				  (concat extra-otherchars "?"))
+			      flyspell-casechars
+			      "+\\)"
+			      (if (or ispell-many-otherchars-p
+				      extra-otherchars)
+				  "*" "?")))
+	 did-it-once prevpt
+	 start end word)
+    ;; find the word
+    (if (not (looking-at flyspell-casechars))
+	(if following
+	    (re-search-forward flyspell-casechars (point-max) t)
+	  (re-search-backward flyspell-casechars (point-min) t)))
+    ;; move to front of word
+    (re-search-backward flyspell-not-casechars (point-min) 'start)
+    (while (and (or (and (not (string= "" ispell-otherchars))
+			 (looking-at ispell-otherchars))
+		    (and extra-otherchars (looking-at extra-otherchars)))
+		(not (bobp))
+		(or (not did-it-once)
+		    ispell-many-otherchars-p)
+		(not (eq prevpt (point))))
+      (if (and extra-otherchars (looking-at extra-otherchars))
+	  (progn
+	    (backward-char 1)
+	    (if (looking-at flyspell-casechars)
+		(re-search-backward flyspell-not-casechars (point-min) 'move)))
+	(setq did-it-once t
+	      prevpt (point))
+	(backward-char 1)
+	(if (looking-at flyspell-casechars)
+	    (re-search-backward flyspell-not-casechars (point-min) 'move)
+	  (backward-char -1))))
+    ;; Now mark the word and save to string.
+    (if (not (re-search-forward word-regexp (point-max) t))
+	nil
+      (progn
+	(setq start (match-beginning 0)
+	      end (point)
+	      word (buffer-substring-no-properties start end))
+	(list word start end)))))
+
+(defun flyspell-get-word.old (following)
+  "Return the word for spell-checking according to Ispell syntax.
+If argument FOLLOWING is non-nil or if `ispell-following-word'
+is non-nil when called interactively, then the following word
+\(rather than preceding\) is checked when the cursor is not over a word.
+Optional second argument contains other chars that can be included in word
+many times.
+
+Word syntax described by `ispell-dictionary-alist' (which see)."
+  (let* ((flyspell-casechars (flyspell-get-casechars))
+	 (flyspell-not-casechars (flyspell-get-not-casechars))
+	 (ispell-otherchars (ispell-get-otherchars))
+	 (ispell-many-otherchars-p (ispell-get-many-otherchars-p))
+	 (word-regexp (if (string< "" ispell-otherchars)
+			  (concat flyspell-casechars
+				  "+\\("
+				  ispell-otherchars
+				  (if (> (length ispell-otherchars) 0) "?")
+				  flyspell-casechars
+				  "+\\)"
+				  (if ispell-many-otherchars-p
+				      "*" "?"))
+			(concat flyspell-casechars "+")))
+	 did-it-once
+	 start end word)
+    ;; find the word
+    (if (not (looking-at flyspell-casechars))
+	(if following
+	    (re-search-forward flyspell-casechars (point-max) t)
+	  (re-search-backward flyspell-casechars (point-min) t)))
+    ;; move to front of word
+    (re-search-backward flyspell-not-casechars (point-min) 'start)
+    (let ((pos nil))
+      (if (string< "" ispell-otherchars)
+	  (while (and (looking-at ispell-otherchars)
+		      (not (bobp))
+		      (or (not did-it-once)
+			  ispell-many-otherchars-p)
+		      (not (eq pos (point))))
+	    (setq pos (point))
+	    (setq did-it-once t)
+	    (backward-char 1)
+	    (if (looking-at flyspell-casechars)
+		(re-search-backward flyspell-not-casechars (point-min) 'move)
+	      (backward-char -1)))))
+    ;; Now mark the word and save to string.
+    (if (eq (re-search-forward word-regexp (point-max) t) nil)
+	nil
+      (progn
+	(setq start (match-beginning 0)
+	      end (point)
+	      word (buffer-substring-no-properties start end))
+	(list word start end)))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-small-region ...                                        */
+;*---------------------------------------------------------------------*/
+(defun flyspell-small-region (beg end)
+  "Flyspell text between BEG and END."
+  (save-excursion
+    (if (> beg end)
+	(let ((old beg))
+	  (setq beg end)
+	  (setq end old)))
+    (goto-char beg)
+    (let ((count 0))
+      (while (< (point) end)
+	(if (and flyspell-issue-message-flag (= count 100))
+	    (progn
+	      (message "Spell Checking...%d%%"
+		       (* 100 (/ (float (- (point) beg)) (- end beg))))
+	      (setq count 0))
+	  (setq count (+ 1 count)))
+	(flyspell-word)
+	(sit-for 0)
+	(let ((cur (point)))
+	  (forward-word 1)
+	  (if (and (< (point) end) (> (point) (+ cur 1)))
+	      (backward-char 1)))))
+    (backward-char 1)
+    (if flyspell-issue-message-flag (message "Spell Checking completed."))
+    (flyspell-word)))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-external-ispell-process ...                             */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-external-ispell-process '()
+  "The external Flyspell Ispell process.")
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-external-ispell-buffer ...                              */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-external-ispell-buffer '())
+(defvar flyspell-large-region-buffer '())
+(defvar flyspell-large-region-beg (point-min))
+(defvar flyspell-large-region-end (point-max))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-external-point-words ...                                */
+;*---------------------------------------------------------------------*/
+(defun flyspell-external-point-words ()
+  (let ((buffer flyspell-external-ispell-buffer))
+    (set-buffer buffer)
+    (beginning-of-buffer)
+    (let ((size (- flyspell-large-region-end flyspell-large-region-beg))
+	  (start flyspell-large-region-beg)
+	  (pword "")
+	  (pcount 1))
+      ;; now we are done with ispell, we have to find the word in
+      ;; the initial buffer
+      (while (< (point) (- (point-max) 1))
+	;; we have to fetch the incorrect word
+	(if (re-search-forward "\\([^\n]+\\)\n" (point-max) t)
+	    (let ((word (match-string 1)))
+	      (if (string= word pword)
+		  (setq pcount (1+ pcount))
+		(progn
+		  (setq pword word)
+		  (setq pcount 1)))
+	      (goto-char (match-end 0))
+	      (if flyspell-issue-message-flag
+		  (message "Spell Checking...%d%% [%s]"
+			   (* 100 (/ (float (point)) (point-max)))
+			   word))
+	      (set-buffer flyspell-large-region-buffer)
+	      (goto-char flyspell-large-region-beg)
+	      (let ((keep t)
+		    (n 0))
+		(while (and (or (< n pcount) keep)
+			    (search-forward word flyspell-large-region-end t))
+		  (progn
+		    (goto-char (- (point) 1))
+		    (setq n (1+ n))
+		    (setq keep (flyspell-word))))
+		(if (= n pcount)
+		    (setq flyspell-large-region-beg (point))))
+	      (set-buffer buffer))
+	  (goto-char (point-max)))))
+    ;; we are done
+    (if flyspell-issue-message-flag (message "Spell Checking completed."))
+    ;; ok, we are done with pointing out incorrect words, we just
+    ;; have to kill the temporary buffer
+    (kill-buffer flyspell-external-ispell-buffer)
+    (setq flyspell-external-ispell-buffer nil)))
+  
+;*---------------------------------------------------------------------*/
+;*    flyspell-process-localwords ...                                  */
+;*    -------------------------------------------------------------    */
+;*    This function is used to prevent checking words declared         */
+;*    explictitly correct on large regions.                            */
+;*---------------------------------------------------------------------*/
+(defun flyspell-process-localwords ()
+  "Parse Localwords in the buffer and remove them from the mispellings
+buffer before flyspell attempts to check them."
+  (let (localwords
+	(current-buffer curbuf)
+	(mispellings-buffer buffer)
+	(ispell-casechars (ispell-get-casechars)))
+    ;; Get localwords from the original buffer
+    (save-excursion
+      (set-buffer current-buffer)
+;*       (flyspell-delete-all-overlays)                                */
+      (beginning-of-buffer)
+      ;; Localwords parsing stolen form ispell.el
+      (while (search-forward ispell-words-keyword nil t)
+	(let ((end (save-excursion (end-of-line) (point)))
+	      string)
+	  ;; buffer-local words separated by a space, and can contain
+	  ;; any character other than a space.  Not rigorous enough.
+	  (while (re-search-forward " *\\([^ ]+\\)" end t)
+	    (setq string (buffer-substring-no-properties (match-beginning 1)
+							 (match-end 1)))
+	    ;; This can fail when string contains a word with illegal chars.
+	    ;; Error handling needs to be added between ispell and emacs.
+	    (if (and (< 1 (length string))     
+		     (equal 0 (string-match ispell-casechars string)))
+		(setq localwords (add-to-list 'localwords string)))))))
+    ;; Remove localwords matches
+    (set-buffer mispellings-buffer)
+    (while localwords
+      (beginning-of-buffer)
+      (delete-matching-lines (concat "^" (car localwords) "$"))
+      (setq localwords (cdr localwords)))
+    (end-of-buffer)))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-large-region ...                                        */
+;*---------------------------------------------------------------------*/
+(defun flyspell-large-region (beg end)
+  (let* ((curbuf  (current-buffer))
+	 (buffer  (get-buffer-create "*flyspell-region*")))
+    (setq flyspell-external-ispell-buffer buffer)
+    (setq flyspell-large-region-buffer curbuf)
+    (setq flyspell-large-region-beg beg)
+    (setq flyspell-large-region-end end)
+    (set-buffer buffer)
+    (erase-buffer)
+    ;; this is done, we can start checking...
+    (if flyspell-issue-message-flag (message "Checking region..."))
+    (set-buffer curbuf)
+    (let ((c (apply 'call-process-region beg
+		    end
+		    ispell-program-name
+		    nil
+		    buffer
+		    nil
+		    (if (boundp 'ispell-list-command)
+			ispell-list-command
+		      "-l")
+		    (let (args)
+		      ;; Local dictionary becomes the global dictionary in use.
+		      (if ispell-local-dictionary
+			  (setq ispell-dictionary ispell-local-dictionary))
+		      (setq args (ispell-get-ispell-args))
+		      (if ispell-dictionary ; use specified dictionary
+			  (setq args
+				(append (list "-d" ispell-dictionary) args)))
+		      (if ispell-personal-dictionary ; use specified pers dict
+			  (setq args
+				(append args
+					(list "-p"
+					      (expand-file-name
+					       ispell-personal-dictionary)))))
+		      (setq args (append args ispell-extra-args))
+		      args))))
+      (if (= c 0)
+	  (progn
+	    (flyspell-process-localwords)
+	    (with-current-buffer curbuf
+              (flyspell-delete-region-overlays beg end))
+	    (flyspell-external-point-words))
+	(error "Can't check region...")))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-region ...                                              */
+;*    -------------------------------------------------------------    */
+;*    Because `ispell -a' is too slow, it is not possible to use       */
+;*    it on large region. Then, when ispell is invoked on a large      */
+;*    text region, a new `ispell -l' process is spawned. The           */
+;*    pointed out words are then searched in the region a checked with */
+;*    regular flyspell means.                                          */
+;*---------------------------------------------------------------------*/
+;;;###autoload
+(defun flyspell-region (beg end)
+  "Flyspell text between BEG and END."
+  (interactive "r")
+  (if (= beg end)
+      ()
+    (save-excursion
+      (if (> beg end)
+	  (let ((old beg))
+	    (setq beg end)
+	    (setq end old)))
+      (if (and flyspell-large-region (> (- end beg) flyspell-large-region))
+	  (flyspell-large-region beg end)
+	(flyspell-small-region beg end)))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-buffer ...                                              */
+;*---------------------------------------------------------------------*/
+;;;###autoload
+(defun flyspell-buffer ()
+  "Flyspell whole buffer."
+  (interactive)
+  (flyspell-region (point-min) (point-max)))
+
+;*---------------------------------------------------------------------*/
+;*    old next error position ...                                      */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-old-buffer-error nil)
+(defvar flyspell-old-pos-error nil)
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-goto-next-error ...                                     */
+;*---------------------------------------------------------------------*/
+(defun flyspell-goto-next-error ()
+  "Go to the next previously detected error.
+In general FLYSPELL-GOTO-NEXT-ERROR must be used after
+FLYSPELL-BUFFER."
+  (interactive)
+  (let ((pos (point))
+	(max (point-max)))
+    (if (and (eq (current-buffer) flyspell-old-buffer-error)
+	     (eq pos flyspell-old-pos-error))
+	(progn
+	  (if (= flyspell-old-pos-error max)
+	      ;; goto beginning of buffer
+	      (progn
+		(message "Restarting from beginning of buffer")
+		(goto-char (point-min)))
+	    (forward-word 1))
+	  (setq pos (point))))
+    ;; seek the next error
+    (while (and (< pos max)
+		(let ((ovs (overlays-at pos))
+		      (r '()))
+		  (while (and (not r) (consp ovs))
+		    (if (flyspell-overlay-p (car ovs))
+			(setq r t)
+		      (setq ovs (cdr ovs))))
+		  (not r)))
+      (setq pos (1+ pos)))
+    ;; save the current location for next invocation
+    (setq flyspell-old-pos-error pos)
+    (setq flyspell-old-buffer-error (current-buffer))
+    (goto-char pos)
+    (if (= pos max)
+	(message "No more miss-spelled word!"))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-overlay-p ...                                           */
+;*---------------------------------------------------------------------*/
+(defun flyspell-overlay-p (o)
+  "A predicate that return true iff O is an overlay used by flyspell."
+  (and (overlayp o) (overlay-get o 'flyspell-overlay)))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-delete-region-overlays ...                              */
+;*---------------------------------------------------------------------*/
+(defun flyspell-delete-region-overlays (beg end)
+  "Delete overlays used by flyspell in a given region."
+  (let ((l (overlays-in beg end)))
+    (while (consp l)
+      (progn
+        (if (flyspell-overlay-p (car l))
+            (delete-overlay (car l)))
+        (setq l (cdr l))))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-delete-all-overlays ...                                 */
+;*    -------------------------------------------------------------    */
+;*    Remove all the overlays introduced by flyspell.                  */
+;*---------------------------------------------------------------------*/
+(defun flyspell-delete-all-overlays ()
+  "Delete all the overlays used by flyspell."
+  (flyspell-delete-region-overlays (point-min) (point-max)))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-unhighlight-at ...                                      */
+;*---------------------------------------------------------------------*/
+(defun flyspell-unhighlight-at (pos)
+  "Remove the flyspell overlay that are located at POS."
+  (if flyspell-persistent-highlight
+      (let ((overlays (overlays-at pos)))
+	(while (consp overlays)
+	  (if (flyspell-overlay-p (car overlays))
+	      (delete-overlay (car overlays)))
+	  (setq overlays (cdr overlays))))
+    (if (flyspell-overlay-p flyspell-overlay)
+	(delete-overlay flyspell-overlay))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-properties-at-p ...                                     */
+;*    -------------------------------------------------------------    */
+;*    Is there an highlight properties at position pos?                */
+;*---------------------------------------------------------------------*/
+(defun flyspell-properties-at-p (pos)
+  "Return t if there is a text property at POS, not counting `local-map'.
+If variable `flyspell-highlight-properties' is set to nil,
+text with properties are not checked.  This function is used to discover
+if the character at POS has any other property."
+  (let ((prop (text-properties-at pos))
+	(keep t))
+    (while (and keep (consp prop))
+      (if (and (eq (car prop) 'local-map) (consp (cdr prop)))
+	  (setq prop (cdr (cdr prop)))
+	(setq keep nil)))
+    (consp prop)))
+
+;*---------------------------------------------------------------------*/
+;*    make-flyspell-overlay ...                                        */
+;*---------------------------------------------------------------------*/
+(defun make-flyspell-overlay (beg end face mouse-face)
+  "Allocate an overlay to highlight an incorrect word.
+BEG and END specify the range in the buffer of that word.
+FACE and MOUSE-FACE specify the `face' and `mouse-face' properties
+for the overlay."
+  (let ((flyspell-overlay (make-overlay beg end nil t nil)))
+    (overlay-put flyspell-overlay 'face face)
+    (overlay-put flyspell-overlay 'mouse-face mouse-face)
+    (overlay-put flyspell-overlay 'flyspell-overlay t)
+    (overlay-put flyspell-overlay 'evaporate t)
+    (overlay-put flyspell-overlay 'help-echo "mouse-2: correct word at point")
+    (if flyspell-use-local-map
+        (overlay-put flyspell-overlay
+                     flyspell-overlay-keymap-property-name
+                     flyspell-mouse-map))
+    (when (eq face 'flyspell-incorrect-face)
+      (and (stringp flyspell-before-incorrect-word-string)
+           (overlay-put flyspell-overlay 'before-string
+                        flyspell-before-incorrect-word-string))
+      (and (stringp flyspell-after-incorrect-word-string)
+           (overlay-put flyspell-overlay 'after-string
+                        flyspell-after-incorrect-word-string)))
+    flyspell-overlay))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-highlight-incorrect-region ...                          */
+;*---------------------------------------------------------------------*/
+(defun flyspell-highlight-incorrect-region (beg end poss)
+  "Set up an overlay on a misspelled word, in the buffer from BEG to END."
+  (unless (run-hook-with-args-until-success
+           'flyspell-incorrect-hook beg end poss)
+    (if (or flyspell-highlight-properties (not (flyspell-properties-at-p beg)))
+        (progn
+	  ;; we cleanup all the overlay that are in the region, not
+	  ;; beginning at the word start position
+	  (if (< (1+ beg) end)
+	      (let ((os (overlays-in (1+ beg) end)))
+		(while (consp os)
+		  (if (flyspell-overlay-p (car os))
+		      (delete-overlay (car os)))
+		  (setq os (cdr os)))))
+          ;; we cleanup current overlay at the same position
+          (if (and (not flyspell-persistent-highlight)
+                   (overlayp flyspell-overlay))
+              (delete-overlay flyspell-overlay)
+            (let ((os (overlays-at beg)))
+              (while (consp os)
+                (if (flyspell-overlay-p (car os))
+                    (delete-overlay (car os)))
+                (setq os (cdr os)))))
+          ;; now we can use a new overlay
+          (setq flyspell-overlay
+                (make-flyspell-overlay beg end
+				       'flyspell-incorrect-face
+				       'highlight))))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-highlight-duplicate-region ...                          */
+;*---------------------------------------------------------------------*/
+(defun flyspell-highlight-duplicate-region (beg end)
+  "Set up an overlay on a duplicated word, in the buffer from BEG to END."
+  (if (or flyspell-highlight-properties (not (flyspell-properties-at-p beg)))
+      (progn
+	;; we cleanup current overlay at the same position
+	(if (and (not flyspell-persistent-highlight)
+		 (overlayp flyspell-overlay))
+	    (delete-overlay flyspell-overlay)
+	  (let ((overlays (overlays-at beg)))
+	    (while (consp overlays)
+	      (if (flyspell-overlay-p (car overlays))
+		  (delete-overlay (car overlays)))
+	      (setq overlays (cdr overlays)))))
+	;; now we can use a new overlay
+	(setq flyspell-overlay
+	      (make-flyspell-overlay beg end
+				     'flyspell-duplicate-face
+				     'highlight)))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-auto-correct-cache ...                                  */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-auto-correct-pos nil)
+(defvar flyspell-auto-correct-region nil)
+(defvar flyspell-auto-correct-ring nil)
+(defvar flyspell-auto-correct-word nil)
+(make-variable-buffer-local 'flyspell-auto-correct-pos)
+(make-variable-buffer-local 'flyspell-auto-correct-region)
+(make-variable-buffer-local 'flyspell-auto-correct-ring)
+(make-variable-buffer-local 'flyspell-auto-correct-word)
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-check-previous-highlighted-word ...                     */
+;*---------------------------------------------------------------------*/
+(defun flyspell-check-previous-highlighted-word (&optional arg)
+  "Correct the closer misspelled word.
+This function scans a mis-spelled word before the cursor. If it finds one
+it proposes replacement for that word. With prefix arg, count that many
+misspelled words backwards."
+  (interactive)
+  (let ((pos1 (point))
+	(pos  (point))
+	(arg  (if (or (not (numberp arg)) (< arg 1)) 1 arg))
+	ov ovs)
+    (if (catch 'exit
+	  (while (and (setq pos (previous-overlay-change pos))
+		      (not (= pos pos1)))
+	    (setq pos1 pos)
+	    (if (> pos (point-min))
+		(progn
+		  (setq ovs (overlays-at (1- pos)))
+		  (while (consp ovs)
+		    (setq ov (car ovs))
+		    (setq ovs (cdr ovs))
+		    (if (and (overlay-get ov 'flyspell-overlay)
+			     (= 0 (setq arg (1- arg))))
+			(throw 'exit t)))))))
+	(save-excursion
+	  (goto-char pos)
+	  (ispell-word))
+      (error "No word to correct before point"))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-display-next-corrections ...                            */
+;*---------------------------------------------------------------------*/
+(defun flyspell-display-next-corrections (corrections)
+  (let ((string "Corrections:")
+	(l corrections)
+	(pos '()))
+    (while (< (length string) 80)
+      (if (equal (car l) flyspell-auto-correct-word)
+	  (setq pos (cons (+ 1 (length string)) pos)))
+      (setq string (concat string " " (car l)))
+      (setq l (cdr l)))
+    (while (consp pos)
+      (let ((num (car pos)))
+	(put-text-property num
+			   (+ num (length flyspell-auto-correct-word))
+			   'face
+			   'flyspell-incorrect-face
+			   string))
+      (setq pos (cdr pos)))
+    (if (fboundp 'display-message)
+	(display-message 'no-log string)
+      (message string))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-abbrev-table ...                                        */
+;*---------------------------------------------------------------------*/
+(defun flyspell-abbrev-table ()
+  (if flyspell-use-global-abbrev-table-p
+      global-abbrev-table
+    local-abbrev-table))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-define-abbrev ...                                       */
+;*---------------------------------------------------------------------*/
+(defun flyspell-define-abbrev (name expansion)
+  (let ((table (flyspell-abbrev-table)))
+    (when table
+      (define-abbrev table name expansion))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-auto-correct-word ...                                   */
+;*---------------------------------------------------------------------*/
+(defun flyspell-auto-correct-word ()
+  "Correct the current word.
+This command proposes various successive corrections for the current word."
+  (interactive)
+  (let ((pos     (point))
+	(old-max (point-max)))
+    ;; use the correct dictionary
+    (flyspell-accept-buffer-local-defs)
+    (if (and (eq flyspell-auto-correct-pos pos)
+	     (consp flyspell-auto-correct-region))
+	;; we have already been using the function at the same location
+	(let* ((start (car flyspell-auto-correct-region))
+	       (len   (cdr flyspell-auto-correct-region)))
+	  (flyspell-unhighlight-at start)
+	  (delete-region start (+ start len))
+	  (setq flyspell-auto-correct-ring (cdr flyspell-auto-correct-ring))
+	  (let* ((word (car flyspell-auto-correct-ring))
+		 (len  (length word)))
+	    (rplacd flyspell-auto-correct-region len)
+	    (goto-char start)
+	    (if flyspell-abbrev-p
+		(if (flyspell-already-abbrevp (flyspell-abbrev-table)
+					      flyspell-auto-correct-word)
+		    (flyspell-change-abbrev (flyspell-abbrev-table)
+					    flyspell-auto-correct-word
+					    word)
+		  (flyspell-define-abbrev flyspell-auto-correct-word word)))
+	    (funcall flyspell-insert-function word)
+	    (flyspell-word)
+	    (flyspell-display-next-corrections flyspell-auto-correct-ring))
+	  (flyspell-ajust-cursor-point pos (point) old-max)
+	  (setq flyspell-auto-correct-pos (point)))
+      ;; fetch the word to be checked
+      (let ((word (flyspell-get-word nil)))
+	(setq flyspell-auto-correct-region nil)
+	(if (consp word)
+	    (let ((start (car (cdr word)))
+		  (end (car (cdr (cdr word))))
+		  (word (car word))
+		  poss)
+	      (setq flyspell-auto-correct-word word)
+	      ;; now check spelling of word.
+	      (process-send-string ispell-process "%\n") ;put in verbose mode
+	      (process-send-string ispell-process (concat "^" word "\n"))
+	      ;; wait until ispell has processed word
+	      (while (progn
+		       (accept-process-output ispell-process)
+		       (not (string= "" (car ispell-filter)))))
+	      (setq ispell-filter (cdr ispell-filter))
+	      (if (consp ispell-filter)
+		  (setq poss (ispell-parse-output (car ispell-filter))))
+	      (cond
+	       ((or (eq poss t) (stringp poss))
+		;; don't correct word
+		t)
+	       ((null poss)
+		;; ispell error
+		(error "Ispell: error in Ispell process"))
+	       (t
+		;; the word is incorrect, we have to propose a replacement
+		(let ((replacements (if flyspell-sort-corrections
+					(sort (car (cdr (cdr poss))) 'string<)
+				      (car (cdr (cdr poss))))))
+		  (if (consp replacements)
+		      (progn
+			(let ((replace (car replacements)))
+			  (let ((new-word replace))
+			    (if (not (equal new-word (car poss)))
+				(progn
+				  ;; the save the current replacements
+				  (setq flyspell-auto-correct-region
+					(cons start (length new-word)))
+				  (let ((l replacements))
+				    (while (consp (cdr l))
+				      (setq l (cdr l)))
+				    (rplacd l (cons (car poss) replacements)))
+				  (setq flyspell-auto-correct-ring
+					replacements)
+				  (flyspell-unhighlight-at start)
+				  (delete-region start end)
+				  (funcall flyspell-insert-function new-word)
+				  (if flyspell-abbrev-p
+				      (if (flyspell-already-abbrevp
+					   (flyspell-abbrev-table) word)
+					  (flyspell-change-abbrev
+					   (flyspell-abbrev-table)
+					   word
+					   new-word)
+					(flyspell-define-abbrev word
+								new-word)))
+				  (flyspell-word)
+				  (flyspell-display-next-corrections
+				   (cons new-word flyspell-auto-correct-ring))
+				  (flyspell-ajust-cursor-point pos
+							       (point)
+							       old-max))))))))))
+	      (ispell-pdict-save t)))
+	(setq flyspell-auto-correct-pos (point))))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-auto-correct-previous-pos ...                           */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-auto-correct-previous-pos nil
+  "Holds the start of the first incorrect word before point.")
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-auto-correct-previous-hook ...                          */
+;*---------------------------------------------------------------------*/
+(defun flyspell-auto-correct-previous-hook () 
+  "Hook to track successive calls to `flyspell-auto-correct-previous-word'.
+Sets flyspell-auto-correct-previous-pos to nil"
+  (interactive) 
+  (remove-hook 'pre-command-hook (function flyspell-auto-correct-previous-hook) t)
+  (unless (eq this-command (function flyspell-auto-correct-previous-word))
+    (setq flyspell-auto-correct-previous-pos nil)))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-auto-correct-previous-word ...                          */
+;*---------------------------------------------------------------------*/
+(defun flyspell-auto-correct-previous-word (position) 
+  "*Auto correct the first mispelled word that occurs before point."
+  (interactive "d")
+
+  (add-hook 'pre-command-hook 
+	    (function flyspell-auto-correct-previous-hook) t t)
+
+  (save-excursion
+    (unless flyspell-auto-correct-previous-pos
+      ;; only reset if a new overlay exists
+      (setq flyspell-auto-correct-previous-pos nil)
+      
+      (let ((overlay-list (overlays-in (point-min) position))
+	    (new-overlay 'dummy-value))
+	
+	;; search for previous (new) flyspell overlay
+	(while (and new-overlay
+		    (or (not (flyspell-overlay-p new-overlay))
+			;; check if its face has changed
+			(not (eq (get-char-property 
+				  (overlay-start new-overlay) 'face) 
+				 'flyspell-incorrect-face))))
+	  (setq new-overlay (car-safe overlay-list))
+	  (setq overlay-list (cdr-safe overlay-list)))
+	
+	;; if nothing new exits new-overlay should be nil
+	(if new-overlay;; the length of the word may change so go to the start
+	    (setq flyspell-auto-correct-previous-pos 
+		  (overlay-start new-overlay)))))
+
+    (when flyspell-auto-correct-previous-pos
+      (save-excursion
+	(goto-char flyspell-auto-correct-previous-pos)
+	(let ((ispell-following-word t));; point is at start
+	  (if (numberp flyspell-auto-correct-previous-pos)
+	      (goto-char flyspell-auto-correct-previous-pos))
+	  (flyspell-auto-correct-word))
+	;; the point may have moved so reset this
+	(setq flyspell-auto-correct-previous-pos (point))))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-correct-word ...                                        */
+;*---------------------------------------------------------------------*/
+(defun flyspell-correct-word (event)
+  "Pop up a menu of possible corrections for a misspelled word.
+The word checked is the word at the mouse position."
+  (interactive "e")
+  ;; use the correct dictionary
+  (flyspell-accept-buffer-local-defs)
+  ;; retain cursor location (I don't know why but save-excursion here fails).
+  (let ((save (point)))
+    (mouse-set-point event)
+    (let ((cursor-location (point))
+	  (word (flyspell-get-word nil))
+	  (case-fold-search nil))
+      (if (consp word)
+	  (let ((start (car (cdr word)))
+		(end (car (cdr (cdr word))))
+		(word (car word))
+		poss replace)
+	    ;; now check spelling of word.
+	    (process-send-string ispell-process "%\n") ;put in verbose mode
+	    (process-send-string ispell-process (concat "^" word "\n"))
+	    ;; wait until ispell has processed word
+	    (while (progn
+		     (accept-process-output ispell-process)
+		     (not (string= "" (car ispell-filter)))))
+	    (setq ispell-filter (cdr ispell-filter))
+	    (if (consp ispell-filter)
+		(setq poss (ispell-parse-output (car ispell-filter))))
+	    (cond
+	     ((or (eq poss t) (stringp poss))
+	      ;; don't correct word
+	      t)
+	     ((null poss)
+	      ;; ispell error
+	      (error "Ispell: error in Ispell process"))
+	     ((string-match "GNU" (emacs-version))
+	      ;; the word is incorrect, we have to propose a replacement
+	      (setq replace (flyspell-emacs-popup event poss word))
+	      (cond ((eq replace 'ignore)
+		     (goto-char save)
+		     nil)
+		    ((eq replace 'save)
+		     (goto-char save)
+		     (process-send-string ispell-process
+					  (concat "*" word "\n"))
+		     (flyspell-unhighlight-at cursor-location)
+		     (setq ispell-pdict-modified-p '(t)))
+		    ((or (eq replace 'buffer) (eq replace 'session))
+		     (process-send-string ispell-process
+					  (concat "@" word "\n"))
+		     (if (null ispell-pdict-modified-p)
+			 (setq ispell-pdict-modified-p
+			       (list ispell-pdict-modified-p)))
+		     (flyspell-unhighlight-at cursor-location)
+		     (goto-char save)
+		     (if (eq replace 'buffer)
+			 (ispell-add-per-file-word-list word)))
+		    (replace
+		     (flyspell-unhighlight-at cursor-location)
+		     (let ((new-word (if (atom replace)
+					 replace
+				       (car replace)))
+			   (cursor-location
+			    (+ (- (length word) (- end start))
+			       cursor-location)))
+		       (if (not (equal new-word (car poss)))
+			   (let ((old-max (point-max)))
+			     (delete-region start end)
+			     (funcall flyspell-insert-function new-word)
+			     (if flyspell-abbrev-p
+				 (flyspell-define-abbrev word new-word))
+			     (flyspell-ajust-cursor-point save
+							  cursor-location
+							  old-max)))))
+		    (t
+		     (goto-char save)
+		     nil)))
+	     ((eq flyspell-emacs 'xemacs)
+	      (flyspell-xemacs-popup
+	       event poss word cursor-location start end save)
+	      (goto-char save)))
+	    (ispell-pdict-save t))))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-xemacs-correct ...                                      */
+;*---------------------------------------------------------------------*/
+(defun flyspell-xemacs-correct (replace poss word cursor-location start end save)
+  "The xemacs popup menu callback."
+  (cond ((eq replace 'ignore)
+	 nil)
+	((eq replace 'save)
+	 (process-send-string ispell-process (concat "*" word "\n"))
+	 (process-send-string ispell-process "#\n")
+	 (flyspell-unhighlight-at cursor-location)
+	 (setq ispell-pdict-modified-p '(t)))
+	((or (eq replace 'buffer) (eq replace 'session))
+	 (process-send-string ispell-process (concat "@" word "\n"))
+	 (flyspell-unhighlight-at cursor-location)
+	 (if (null ispell-pdict-modified-p)
+	     (setq ispell-pdict-modified-p
+		   (list ispell-pdict-modified-p)))
+	 (if (eq replace 'buffer)
+	     (ispell-add-per-file-word-list word)))
+	(replace
+	 (let ((old-max (point-max))
+	       (new-word (if (atom replace)
+			     replace
+			   (car replace)))
+	       (cursor-location (+ (- (length word) (- end start))
+				   cursor-location)))
+	   (if (not (equal new-word (car poss)))
+	       (progn
+		 (delete-region start end)
+		 (goto-char start)
+		 (funcall flyspell-insert-function new-word)
+		 (if flyspell-abbrev-p
+		     (flyspell-define-abbrev word new-word))))
+	   (flyspell-ajust-cursor-point save cursor-location old-max)))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-ajust-cursor-point ...                                  */
+;*---------------------------------------------------------------------*/
+(defun flyspell-ajust-cursor-point (save cursor-location old-max)
+  (if (>= save cursor-location)
+      (let ((new-pos (+ save (- (point-max) old-max))))
+	(goto-char (cond
+		    ((< new-pos (point-min))
+		     (point-min))
+		    ((> new-pos (point-max))
+		     (point-max))
+		    (t new-pos))))
+    (goto-char save)))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-emacs-popup ...                                         */
+;*---------------------------------------------------------------------*/
+(defun flyspell-emacs-popup (event poss word)
+  "The Emacs popup menu."
+  (if (not event)
+      (let* ((mouse-pos  (mouse-position))
+	     (mouse-pos  (if (nth 1 mouse-pos)
+			     mouse-pos
+			   (set-mouse-position (car mouse-pos)
+				 	       (/ (frame-width) 2) 2)
+			   (unfocus-frame)
+			   (mouse-position))))
+	(setq event (list (list (car (cdr mouse-pos))
+				(1+ (cdr (cdr mouse-pos))))
+			  (car mouse-pos)))))
+  (let* ((corrects   (if flyspell-sort-corrections
+			 (sort (car (cdr (cdr poss))) 'string<)
+		       (car (cdr (cdr poss)))))
+	 (cor-menu   (if (consp corrects)
+			 (mapcar (lambda (correct)
+				   (list correct correct))
+				 corrects)
+		       '()))
+	 (affix      (car (cdr (cdr (cdr poss)))))
+	 (base-menu  (let ((save (if (consp affix)
+				     (list
+				      (list (concat "Save affix: " (car affix))
+					    'save)
+				      '("Accept (session)" session)
+				      '("Accept (buffer)" buffer))
+				   '(("Save word" save)
+				     ("Accept (session)" session)
+				     ("Accept (buffer)" buffer)))))
+		       (if (consp cor-menu)
+			   (append cor-menu (cons "" save))
+			 save)))
+	 (menu       (cons "flyspell correction menu" base-menu)))
+    (car (x-popup-menu event
+		       (list (format "%s [%s]" word (or ispell-local-dictionary
+							ispell-dictionary))
+			     menu)))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-xemacs-popup ...                                        */
+;*---------------------------------------------------------------------*/
+(defun flyspell-xemacs-popup (event poss word cursor-location start end save)
+  "The XEmacs popup menu."
+  (let* ((corrects   (if flyspell-sort-corrections
+			 (sort (car (cdr (cdr poss))) 'string<)
+		       (car (cdr (cdr poss)))))
+	 (cor-menu   (if (consp corrects)
+			 (mapcar (lambda (correct)
+				   (vector correct
+					   (list 'flyspell-xemacs-correct
+						 correct
+						 (list 'quote poss)
+						 word
+						 cursor-location
+						 start
+						 end
+						 save)
+					   t))
+				 corrects)
+		       '()))
+	 (affix      (car (cdr (cdr (cdr poss)))))
+	 (menu       (let ((save (if (consp affix)
+				     (vector
+				      (concat "Save affix: " (car affix))
+				      (list 'flyspell-xemacs-correct
+					    ''save
+					    (list 'quote poss)
+					    word
+					    cursor-location
+					    start
+					    end
+					    save)
+				      t)
+				   (vector
+				    "Save word"
+				    (list 'flyspell-xemacs-correct
+					  ''save
+					  (list 'quote poss)
+					  word
+					  cursor-location
+					  start
+					  end
+					  save)
+				    t)))
+			   (session (vector "Accept (session)"
+					    (list 'flyspell-xemacs-correct
+						  ''session
+						  (list 'quote poss)
+						  word
+						  cursor-location
+						  start
+						  end
+						  save)
+					    t))
+			   (buffer  (vector "Accept (buffer)"
+					    (list 'flyspell-xemacs-correct
+						  ''buffer
+						  (list 'quote poss)
+						  word
+						  cursor-location
+						  start
+						  end
+						  save)
+					    t)))
+		       (if (consp cor-menu)
+			   (append cor-menu (list "-" save session buffer))
+			 (list save session buffer)))))
+    (popup-menu (cons (format "%s [%s]" word (or ispell-local-dictionary
+						 ispell-dictionary))
+		      menu))))
+
+;*---------------------------------------------------------------------*/
+;*    Some example functions for real autocorrecting                   */
+;*---------------------------------------------------------------------*/
+(defun flyspell-maybe-correct-transposition (beg end poss)
+  "Check replacements for transposed characters.
+
+If the text between BEG and END is equal to a correction suggested by
+Ispell, after transposing two adjacent characters, correct the text,
+and return t.
+
+The third arg POSS is either the symbol 'doublon' or a list of
+possible corrections as returned by 'ispell-parse-output'.
+
+This function is meant to be added to 'flyspell-incorrect-hook'."
+  (when (consp poss)    
+    (catch 'done
+      (save-excursion
+        (goto-char (1+ beg))
+        (while (< (point) end)
+          (transpose-chars 1)
+          (when (member (buffer-substring beg end) (car (cdr (cdr poss))))
+            (throw 'done t))
+          (transpose-chars -1)
+          (forward-char))
+        nil))))
+
+(defun flyspell-maybe-correct-doubling (beg end poss)
+  "Check replacements for doubled characters.
+
+If the text between BEG and END is equal to a correction suggested by
+Ispell, after removing a pair of doubled characters, correct the text,
+and return t.
+
+The third arg POSS is either the symbol 'doublon' or a list of
+possible corrections as returned by 'ispell-parse-output'.
+
+This function is meant to be added to 'flyspell-incorrect-hook'."
+  (when (consp poss) 
+    (catch 'done
+      (save-excursion
+        (let ((last (char-after beg))
+              this)
+          (goto-char (1+ beg))          
+          (while (< (point) end)
+            (setq this (char-after))
+            (if (not (char-equal this last))
+                (forward-char)
+              (delete-char 1)
+              (when (member (buffer-substring beg (1- end)) (car (cdr (cdr poss))))
+                (throw 'done t))
+              ;; undo
+              (insert-char this 1))            
+            (setq last this))
+          nil)))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-already-abbrevp ...                                     */
+;*---------------------------------------------------------------------*/
+(defun flyspell-already-abbrevp (table word)
+  (let ((sym (abbrev-symbol word table)))
+    (and sym (symbolp sym))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-change-abbrev ...                                       */
+;*---------------------------------------------------------------------*/
+(defun flyspell-change-abbrev (table old new)
+  (set (abbrev-symbol old table) new))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-auto-correct-previous-word advice ...                   */
+;*---------------------------------------------------------------------*/
+(defadvice flyspell-auto-correct-previous-word
+  (around easymacs-flyspell-auto-correct)
+  "Correct current word if misspelled, else previous
+    misspelling.  Protect against accidentally changing a word
+    that cannot be seen, because it is somewhere off the screen."
+  (let ((top) (bot))
+    (save-excursion
+      (move-to-window-line 0)
+      (setq top (point))
+      (move-to-window-line -1)
+      (setq bot (point)))
+    (save-restriction
+      (narrow-to-region top bot)
+      (save-excursion
+	(re-search-forward "\\s \\|\\'" nil t)
+	(overlay-recenter (point))
+	ad-do-it))))
+
+(ad-activate 'flyspell-auto-correct-previous-word)
+
+(provide 'flyspell)
+;;; flyspell.el ends here
+;;; 
diff --git a/emacs/gambit.el b/emacs/gambit.el new file mode 100644 index 0000000..404d160 --- /dev/null +++ b/emacs/gambit.el @@ -0,0 +1,649 @@ +;;; -*- Mode:Emacs-Lisp -*- +;;; gambit.el --- Run Gambit in an [X]Emacs buffer + +;; Copyright (c) 1997-2004 Marc Feeley & Michael Sperber + +;; Authors: Marc Feeley +;; Mike Sperber +;; Keywords: processes, lisp + +;; To use this package, make sure this file is accessible from your +;; load-path and that the following lines are in your ".emacs" file: +;; +;; (autoload 'gambit-inferior-mode "gambit" "Hook Gambit mode into cmuscheme.") +;; (autoload 'gambit-mode "gambit" "Hook Gambit mode into scheme.") +;; (add-hook 'inferior-scheme-mode-hook (function gambit-inferior-mode)) +;; (add-hook 'scheme-mode-hook (function gambit-mode)) +;; (setq scheme-program-name "gsi -:t") +;; +;; Alternatively, if you don't mind always loading this package, +;; you can simply add this line to your ".emacs" file: +;; +;; (require 'gambit) +;; +;; You can then start Gambit with "M-x run-scheme". +;; +;; When Gambit signals an error, Emacs will intercept the location +;; information in the error message and automatically open a buffer +;; highlighting the error. +;; +;; The continuation of the error can be inspected with the "C-c [" +;; (crawl towards older frames) and "C-c ]" (crawl towards newer +;; frames). For each new frame visited, Emacs will highlight the +;; expression associated with the frame. +;; +;; "C-c c", "C-c s" and "C-c l" can be used to send the commands +;; ",c", ",s" and ",l" respectively to Gambit. This is convenient for +;; single-stepping a program. +;; +;; "C-c _" can be used to delete the last popup window that was +;; created to highlight a Scheme expression. + +;;;---------------------------------------------------------------------------- + +;; User overridable parameters. + +(defvar scheme-program-name "gsi -:d-") + +(defvar gambit-repl-command-prefix "\C-c" + "Emacs keybinding prefix for Gambit REPL's commands.") + +(defvar gambit-highlight-color "gold" + "Color of the overlay for highlighting Scheme expressions.") + +(defvar gambit-highlight-face + (let ((face 'gambit-highlight-face)) + (condition-case nil + (progn + (make-face face) + (if (x-display-color-p) + (set-face-background face gambit-highlight-color) + (progn + ;(make-face-bold face) + (set-face-underline-p face t)))) + (error (setq face nil))) + face) + "Face of overlay for highlighting Scheme expressions.") + +(defvar gambit-new-window-height 6 + "Height of a window opened to highlight a Scheme expression.") + +(defvar gambit-move-to-highlighted (not gambit-highlight-face) + "Flag to move to window opened to highlight a Scheme expression.") + +;;;---------------------------------------------------------------------------- + +;; These must be loaded first because we redefine some of the +;; functions they contain. + +(require 'scheme) +(require 'cmuscheme) + +;;;---------------------------------------------------------------------------- + +(defun gambit-indent-function (indent-point state) + (let ((normal-indent (current-column))) + (goto-char (1+ (elt state 1))) + (parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t) + (if (and (elt state 2) + (not (looking-at "\\sw\\|\\s_"))) + ;; car of form doesn't seem to be a a symbol + (progn + (if (not (> (save-excursion (forward-line 1) (point)) + calculate-lisp-indent-last-sexp)) + (progn (goto-char calculate-lisp-indent-last-sexp) + (beginning-of-line) + (parse-partial-sexp (point) + calculate-lisp-indent-last-sexp 0 t))) + ;; Indent under the list or under the first sexp on the same + ;; line as calculate-lisp-indent-last-sexp. Note that first + ;; thing on that line has to be complete sexp since we are + ;; inside the innermost containing sexp. + (backward-prefix-chars) + (current-column)) + (let ((function (buffer-substring (point) + (progn (forward-sexp 1) (point)))) + method) + (setq method (or (gambit-indent-method function) + (get (intern-soft function) 'scheme-indent-function) + (get (intern-soft function) 'scheme-indent-hook))) + (cond ((or (eq method 'defun) + (and (null method) + (> (length function) 3) + (string-match "\\`def" function))) + (lisp-indent-defform state indent-point)) + ((integerp method) + (lisp-indent-specform method state + indent-point normal-indent)) + (method + (funcall method state indent-point normal-indent))))))) + +(defun gambit-indent-method (function) + (let ((method nil) + (alist gambit-indent-regexp-alist)) + (while (and (not method) (not (null alist))) + (let* ((regexp (car alist)) + (x (string-match (car regexp) function))) + (if x + (setq method (cdr regexp))) + (setq alist (cdr alist)))) + method)) + +(set lisp-indent-function 'gambit-indent-function) + +(defvar gambit-indent-regexp-alist + '( + ("^declare$" . defun) + ("^##declare$" . defun) + ("^##define" . defun) + ("^macro-check" . defun) + ("^macro-force-vars$" . defun) + ("^macro-number-dispatch$" . defun) + )) + +;;;---------------------------------------------------------------------------- + +;; Portable functions for FSF Emacs and Xemacs. + +(defun window-top-edge (window) + (if (fboundp 'window-edges) + (car (cdr (window-edges window))) + (car (cdr (window-pixel-edges window))))) + +;; Xemacs calls its overlays "extents", so we have to use them to emulate +;; overlays on Xemacs. Some versions of Xemacs have the portability package +;; "overlays.el" for this, so we could simply do: +;; +;; (condition-case nil ; load "overlay.el" if we have it +;; (require 'overlay) +;; (error nil)) +;; +;; Unfortunately some versions of Xemacs don't have this package so +;; we explicitly define an interface to extents. + +(if (not (fboundp 'make-overlay)) + (defun make-overlay (start end) + (make-extent start end))) + +(if (not (fboundp 'overlay-put)) + (defun overlay-put (overlay prop val) + (set-extent-property overlay prop val))) + +(if (not (fboundp 'move-overlay)) + (defun move-overlay (overlay start end buffer) + (set-extent-endpoints overlay start end buffer))) + +;;;---------------------------------------------------------------------------- + +;; Redefine the function scheme-send-region from `cmuscheme' so +;; that we can keep track of all text sent to Gambit's stdin. + +(defun scheme-send-region (start end) + "Send the current region to the inferior Scheme process." + (interactive "r") + (scheme-send-string (buffer-substring start end))) + +(defun scheme-send-string (str) + "Send a string to the inferior Scheme process." + (let* ((clean-str (gambit-string-terminate-with-newline str)) + (proc (scheme-proc)) + (pmark (process-mark proc)) + (buffer (get-buffer scheme-buffer)) + (old-buffer (current-buffer))) + (set-buffer buffer) + (goto-char pmark) + (set-marker comint-last-input-start (point)) + (insert clean-str) + (set-marker pmark (point)) + (gambit-input-sender proc clean-str) + (set-buffer old-buffer))) + +(defun gambit-input-sender (proc str) + (let ((clean-str (gambit-string-terminate-with-newline str))) + (gambit-register-input clean-str) + (gambit-make-read-only (current-buffer) (point-max)) + (gambit-unhighlight) + (comint-send-string proc clean-str))) + +(defun gambit-register-input (str) + (let ((marker (make-marker))) + (set-marker marker comint-last-input-start) + (setq gambit-input-line-marker-alist + (cons (cons gambit-input-line-count + marker) + gambit-input-line-marker-alist)) + (setq gambit-input-line-count + (+ gambit-input-line-count + (gambit-string-count-lines str))))) + +(defun gambit-make-read-only (buffer end) + ' ; disable read-only interaction, cause it doesn't work! + (progn + (put-text-property 1 end 'front-sticky '(read-only) buffer) + (put-text-property 1 end 'rear-nonsticky '(read-only) buffer) + (put-text-property 1 end 'read-only t buffer))) + +;;;---------------------------------------------------------------------------- + +(defun gambit-load-file (file-name) + "Load a Scheme file FILE-NAME into the inferior Scheme process." + (interactive (comint-get-source "Load Scheme file: " scheme-prev-l/c-dir/file + scheme-source-modes t)) ; T because LOAD + ; needs an exact name + (comint-check-source file-name) ; Check to see if buffer needs saved. + (setq scheme-prev-l/c-dir/file (cons (file-name-directory file-name) + (file-name-nondirectory file-name))) + (scheme-send-string (concat "(load \"" file-name "\"\)\n"))) + +(defun gambit-compile-file (file-name) + "Compile a Scheme file FILE-NAME in the inferior Scheme process." + (interactive (comint-get-source "Compile Scheme file: " + scheme-prev-l/c-dir/file + scheme-source-modes + nil)) ; NIL because COMPILE doesn't + ; need an exact name. + (comint-check-source file-name) ; Check to see if buffer needs saved. + (setq scheme-prev-l/c-dir/file (cons (file-name-directory file-name) + (file-name-nondirectory file-name))) + (scheme-send-string (concat "(compile-file \"" file-name "\"\)\n"))) + +;;;---------------------------------------------------------------------------- + +;; Buffer local variables of the Gambit inferior process(es). + +(defvar gambit-input-line-count nil + "Line number as seen by the Gambit process.") + +(defvar gambit-input-line-marker-alist nil + "Alist of line numbers of input blocks and markers.") + +(defvar gambit-last-output-marker nil + "Points to the last character output by the Gambit process.") + +;;;---------------------------------------------------------------------------- + +;; Utilities + +(defun gambit-string-count-lines (str) + "Returns number of complete lines in string." + (let ((n 0) + (start 0)) + (while (string-match "\n" str start) + (setq n (+ n 1)) + (setq start (match-end 0))) + n)) + +(defun gambit-string-terminate-with-newline (str) + "Adds a newline at end of string if it doesn't already have one." + (let ((len (length str))) + (if (or (= len 0) + (not (equal (aref str (- len 1)) ?\n))) + (concat str "\n") + str))) + +;;;---------------------------------------------------------------------------- + +;; Define keys for single stepping and continuation crawling. + +(defun gambit-step-continuation () + (interactive) + (scheme-send-string "#||#,s;")) + +(defun gambit-leap-continuation () + (interactive) + (scheme-send-string "#||#,l;")) + +(defun gambit-continue () + (interactive) + (scheme-send-string "#||#,c;")) + +(defun gambit-environment () + (interactive) + (scheme-send-string "#||#,e;")) + +(defun gambit-backtrace () + (interactive) + (scheme-send-string "#||#,b;")) + +(defun gambit-crawl-backtrace-newer () + (interactive) + (scheme-send-string "#||#,-;")) + +(defun gambit-crawl-backtrace-older () + (interactive) + (scheme-send-string "#||#,+;")) + +(defun gambit-kill-last-popup () + (interactive) + (let ((windows gambit-popups)) + (while (not (null windows)) + (let ((window (car windows))) + (setq windows (cdr windows)) + (if (and window + (window-live-p window)) + (progn + (setq gambit-popups windows) + (setq windows nil) + (delete-window window))))))) + +(defun gambit-add-popup (popup) + (setq gambit-popups + (cons popup (gambit-gc-popups gambit-popups)))) + +(defun gambit-gc-popups (popups) + (cond ((null popups) + '()) + ((window-live-p (car popups)) + (cons (car popups) (gambit-gc-popups (cdr popups)))) + (t + (gambit-gc-popups (cdr popups))))) + +(defvar gambit-popups nil) + +;;;---------------------------------------------------------------------------- + +;; Procedures to intercept and process the location information output +;; by Gambit. + +(defun gambit-output-filter (str) + (let* ((buffer + (current-buffer)) + (output-marker + (process-mark (get-buffer-process buffer))) + (locat + (if (string-match "\n" str) ; match only after end of line is seen + (let* ((end + (save-excursion + (goto-char output-marker) + (beginning-of-line) + (point))) + (start + (save-excursion + (goto-char (+ gambit-last-output-marker 1)) + (beginning-of-line) + (point)))) + (gambit-extract-location + (buffer-substring start end))) + nil))) + (gambit-make-read-only buffer output-marker) + (set-marker gambit-last-output-marker (- output-marker 1)) + (let* ((windows + (gambit-windows-displaying-buffer buffer)) + (initially-selected-window + (selected-window))) + (if (not (null windows)) + (save-excursion + (set-buffer buffer) + (select-window (car windows)) + (goto-char output-marker) + (if (not (pos-visible-in-window-p)) + (recenter -1)) + (select-window initially-selected-window)))) + (if locat + (gambit-highlight-location locat)))) + +(defun gambit-extract-location (str) + (let ((location nil) + (alist gambit-location-regexp-alist)) + (while (and (not location) (not (null alist))) + (let* ((regexp (car alist)) + (x (string-match (car regexp) str))) + (if x + (let* ((pos1 (nth 1 regexp)) + (pos2 (nth 2 regexp)) + (pos3 (nth 3 regexp)) + (name (substring str + (match-beginning pos1) + (match-end pos1))) + (line (substring str + (match-beginning pos2) + (match-end pos2))) + (column (substring str + (match-beginning pos3) + (match-end pos3)))) + (setq location (list (read name) (read line) (read column))))) + (setq alist (cdr alist)))) + location)) + +(defvar gambit-location-regexp-alist + '(("\\(\\\"\\(\\\\\\\\\\|\\\\\"\\|[^\\\"\n]\\)+\\\"\\)@\\([0-9]+\\)\\.\\([0-9]+\\)[^0-9]" 1 3 4) + ("\\((console)\\)@\\([0-9]+\\)\\.\\([0-9]+\\)[^0-9]" 1 2 3) + ("\\((stdin)\\)@\\([0-9]+\\)\\.\\([0-9]+\\)[^0-9]" 1 2 3))) + +(defun gambit-closest-non-following (line alist) + (let ((closest nil)) + (while (not (null alist)) + (let ((x (car alist))) + (if (and (<= (car x) line) + (or (not closest) + (> (car x) (car closest)))) + (setq closest x)) + (setq alist (cdr alist)))) + closest)) + +(defun gambit-highlight-location (locat) + + ; invariant: the current buffer is the Scheme buffer + + (let ((name (car locat)) + (line (car (cdr locat))) + (column (car (cdr (cdr locat))))) + (cond ((or (equal name '(console)) + (equal name '(stdin))) + (let ((closest + (gambit-closest-non-following + line + gambit-input-line-marker-alist))) + (if closest + (let ((n (- line (car closest)))) + (gambit-highlight-expression + (current-buffer) + (save-excursion + (goto-char (cdr closest)) + (if (> n 0) (forward-line n)) + (forward-char (- column 1)) + (point))))))) + ((stringp name) + (let ((buffer (find-file-noselect name))) + (if buffer + (gambit-highlight-expression + buffer + (save-excursion + (set-buffer buffer) + (goto-line line) + (forward-char (- column 1)) + (point))))))))) + +(defun gambit-highlight-expression (location-buffer pos) + +"Highlight the expression at a specific location in a buffer. + +The location buffer is the one that contains the location to +highlight and `pos' points to the first character of the +expression in the buffer. If the location buffer is not visible +then we must display it in a window. We also have to make sure +the highlighted expression is visible, which may require the +window to be scrolled. + +Our approach is simple: if the location buffer is not visible or +it is the Scheme buffer and it is only displayed in the selected +window, then we split one of the windows in 2 and use the bottom +window to display the location buffer. The window chosen is +preferentially the topmost window displaying the Scheme buffer, +otherwise it is the selected window. Before we do the split, we +enlarge the window if it is too small." + + (let* ((location-windows + (gambit-windows-displaying-buffer location-buffer)) + (initially-selected-window + (selected-window))) + + ; "location-windows" is the list of windows containing + ; the location buffer. + + (if (or (null location-windows) + (and (eq location-buffer (get-buffer scheme-buffer)) + (eq initially-selected-window (car location-windows)) + (null (cdr location-windows)))) + + (let* ((scheme-windows + (gambit-windows-displaying-buffer (get-buffer scheme-buffer))) + (window-to-split + (if (null scheme-windows) + initially-selected-window + (car scheme-windows))) + (height + (window-height window-to-split))) + (select-window window-to-split) + (if (< height (* 2 gambit-new-window-height)) + (enlarge-window + (- (* 2 gambit-new-window-height) + height))) + (let ((bottom-window + (split-window + window-to-split + (- (window-height window-to-split) + gambit-new-window-height)))) + (gambit-add-popup bottom-window) + (select-window bottom-window) + (switch-to-buffer location-buffer))) + + (select-window (car (reverse location-windows)))) + + ; Highlight the expression in the location buffer. + + (save-excursion + (set-buffer (window-buffer (selected-window))) + (goto-char pos) + (if (not (pos-visible-in-window-p)) + (recenter (- (/ (window-height) 2) 1))) + (gambit-highlight-region + location-buffer + pos + (progn + (condition-case nil + (forward-sexp) ; we assume this uses the same syntax as Gambit + (error ; if forward-sexp fails with this condition name + (forward-char 1))) + (point))) + (goto-char pos)) + + (if (not (eq initially-selected-window (selected-window))) + (progn + (goto-char pos) + (if (not gambit-move-to-highlighted) + (select-window initially-selected-window)))))) + +(defun gambit-windows-displaying-buffer (buffer) + (let ((windows '())) + (walk-windows (function + (lambda (w) + (if (eq buffer (window-buffer w)) + (setq windows (cons w windows))))) + t + 'visible) + (sort windows + (function + (lambda (w1 w2) + (< (window-top-edge w1) + (window-top-edge w2))))))) + +(defvar gambit-highlight-overlay + (let ((ovl (make-overlay (point-min) (point-min)))) + (overlay-put ovl 'face gambit-highlight-face) + ovl) + "Overlay for highlighting Scheme expressions.") + +(defun gambit-highlight-region (buffer start end) + (if gambit-highlight-overlay + (move-overlay gambit-highlight-overlay start end buffer))) + +(defun gambit-unhighlight () + (gambit-highlight-region (get-buffer scheme-buffer) 1 1)) + +;;;---------------------------------------------------------------------------- + +(defun gambit-install-comment-syntax () + "Configure #| ... |# comments." + ;; XEmacs 19 and beyond use 8-bit modify-syntax-entry flags. + ;; Emacs 19 uses a 1-bit flag. We will have to set up our + ;; syntax tables differently to handle this. + ;; Stolen from CC Mode. + (let ((table (copy-syntax-table)) + entry) + (modify-syntax-entry ?a ". 12345678" table) + (cond + ;; XEmacs 19, and beyond Emacs 19.34 + ((arrayp table) + (setq entry (aref table ?a)) + ;; In Emacs, table entries are cons cells + (if (consp entry) (setq entry (car entry)))) + ;; XEmacs 20 + ((fboundp 'get-char-table) (setq entry (get-char-table ?a table))) + ;; before and including Emacs 19.34 + ((and (fboundp 'char-table-p) + (char-table-p table)) + (setq entry (car (char-table-range table [?a])))) + ;; incompatible + (t (error "Gambit mode is incompatible with this version of Emacs"))) + (if (= (logand (lsh entry -16) 255) 255) + (progn + ;; XEmacs 19 & 20 + (modify-syntax-entry ?# "(#58" scheme-mode-syntax-table) + (modify-syntax-entry ?| ". 67" scheme-mode-syntax-table)) + ;; Emacs 19 & 20 + (modify-syntax-entry ?# "_ 14" scheme-mode-syntax-table) + (modify-syntax-entry ?| "\" 23" scheme-mode-syntax-table)))) + +(defun gambit-extend-mode-map (map) + (define-key map [(f8)] 'gambit-continue) + (define-key map [(f9)] 'gambit-crawl-backtrace-newer) + (define-key map [(f10)] 'gambit-crawl-backtrace-older) + (define-key map [(f11)] 'gambit-step-continuation) + (define-key map [(f12)] 'gambit-leap-continuation) + + (define-key map "\C-c\C-l" 'gambit-load-file) + (define-key map "\C-c\C-k" 'gambit-compile-file) + + (let ((prefix gambit-repl-command-prefix)) + (define-key map (concat prefix "c") 'gambit-continue) + (define-key map (concat prefix "]") 'gambit-crawl-backtrace-newer) + (define-key map (concat prefix "[") 'gambit-crawl-backtrace-older) + (define-key map (concat prefix "s") 'gambit-step-continuation) + (define-key map (concat prefix "l") 'gambit-leap-continuation) + (define-key map (concat prefix "_") 'gambit-kill-last-popup))) + +(defun gambit-inferior-mode () + + (gambit-install-comment-syntax) + (gambit-extend-mode-map inferior-scheme-mode-map) + + (make-local-variable 'gambit-input-line-count) + (setq gambit-input-line-count 1) + + (make-local-variable 'gambit-input-line-marker-alist) + (setq gambit-input-line-marker-alist '()) + + (make-local-variable 'gambit-last-output-marker) + (setq gambit-last-output-marker (make-marker)) + (set-marker gambit-last-output-marker 0) + + (setq comint-input-sender (function gambit-input-sender)) + + (add-hook 'comint-output-filter-functions + (function gambit-output-filter) + t + t)) ; hook is buffer-local + +(defun gambit-mode () + (gambit-install-comment-syntax) + (gambit-extend-mode-map scheme-mode-map)) + +;;(autoload 'gambit-inferior-mode "gambit" "Hook Gambit mode into cmuscheme.") +;;(autoload 'gambit-mode "gambit" "Hook Gambit mode into scheme.") +(add-hook 'inferior-scheme-mode-hook (function gambit-inferior-mode)) +(add-hook 'scheme-mode-hook (function gambit-mode)) + +(provide 'gambit) + +;;;---------------------------------------------------------------------------- diff --git a/emacs/gist.el b/emacs/gist.el new file mode 100644 index 0000000..163e9af --- /dev/null +++ b/emacs/gist.el @@ -0,0 +1,346 @@ +;; gist.el --- Emacs integration for gist.github.com + +;; Author: Christian Neukirchen +;; Maintainer: Chris Wanstrath +;; Contributors: +;; Will Farrington +;; Michael Ivey +;; Phil Hagelberg +;; Dan McKinley +;; Version: 0.4 +;; Created: 21 Jul 2008 +;; Keywords: gist git github paste pastie pastebin + +;; This file is NOT part of GNU Emacs. + +;; This is free software; you can redistribute it and/or modify it under +;; the terms of the GNU General Public License as published by the Free +;; Software Foundation; either version 2, or (at your option) any later +;; version. +;; +;; This is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +;; for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +;; MA 02111-1307, USA. + +;;; Commentary: + +;; Uses your local GitHub config if it can find it. +;; See http://github.com/blog/180-local-github-config + +;;; Code: + +(eval-when-compile (require 'cl)) +(require 'xml) + +(defvar github-user nil + "If non-nil, will be used as your GitHub username without checking +git-config(1).") +(defvar github-token nil + "If non-nil, will be used as your GitHub token without checking +git-config(1).") + +(defvar gist-view-gist nil + "If non-nil, automatically use `browse-url' to view gists after they're +posted.") + +(defvar gist-supported-modes-alist '((action-script-mode . "as") + (c-mode . "c") + (c++-mode . "cpp") + (clojure-mode . "clj") + (common-lisp-mode . "lisp") + (css-mode . "css") + (diff-mode . "diff") + (emacs-lisp-mode . "el") + (erlang-mode . "erl") + (haskell-mode . "hs") + (html-mode . "html") + (io-mode . "io") + (java-mode . "java") + (javascript-mode . "js") + (jde-mode . "java") + (js2-mode . "js") + (lua-mode . "lua") + (ocaml-mode . "ml") + (objective-c-mode . "m") + (perl-mode . "pl") + (php-mode . "php") + (python-mode . "py") + (ruby-mode . "rb") + (text-mode . "txt") + (scala-mode . "scala") + (sql-mode . "sql") + (scheme-mode . "scm") + (smalltalk-mode . "st") + (sh-mode . "sh") + (tcl-mode . "tcl") + (tex-mode . "tex") + (xml-mode . "xml"))) + + + +(defun* gist-request (url callback &optional params) + "Makes a request to `url' asynchronously, notifying `callback' when +complete. The github parameters are included in the request. Optionally +accepts additional POST `params' as a list of (key . value) conses." + (github-with-auth-info login token + (let ((url-request-data (gist-make-query-string + `(("login" . ,login) + ("token" . ,token) ,@params))) + (url-max-redirecton 5) + (url-request-method "POST")) + (url-retrieve url callback)))) + +;;;###autoload +(defun gist-region (begin end &optional private &optional callback) + "Post the current region as a new paste at gist.github.com +Copies the URL into the kill ring. + +With a prefix argument, makes a private paste." + (interactive "r\nP") + (let* ((file (or (buffer-file-name) (buffer-name))) + (name (file-name-nondirectory file)) + (ext (or (cdr (assoc major-mode gist-supported-modes-alist)) + (file-name-extension file) + "txt"))) + (gist-request + "http://gist.github.com/gists" + (or callback 'gist-created-callback) + `(,@(if private '(("action_button" . "private"))) + ("file_ext[gistfile1]" . ,(concat "." ext)) + ("file_name[gistfile1]" . ,name) + ("file_contents[gistfile1]" . ,(buffer-substring begin end)))))) + +(defun gist-created-callback (status) + (let ((location (cadr status))) + (message "Paste created: %s" location) + (when gist-view-gist + (browse-url location)) + (kill-new location) + (kill-buffer (current-buffer)))) + +(defun gist-make-query-string (params) + "Returns a query string constructed from PARAMS, which should be +a list with elements of the form (KEY . VALUE). KEY and VALUE +should both be strings." + (mapconcat + (lambda (param) + (concat (url-hexify-string (car param)) "=" + (url-hexify-string (cdr param)))) + params "&")) + +;;;###autoload +(defun gist-region-private (begin end) + "Post the current region as a new private paste at gist.github.com +Copies the URL into the kill ring." + (interactive "r") + (gist-region begin end t)) + +(defun github-config (key) + "Returns a GitHub specific value from the global Git config." + (let ((strip (lambda (string) + (if (> (length string) 0) + (substring string 0 (- (length string) 1))))) + (git (executable-find "git"))) + (funcall strip (shell-command-to-string + (concat git " config --global github." key))))) + +(defun github-set-config (key value) + "Sets a GitHub specific value to the global Git config." + (let ((git (executable-find "git"))) + (shell-command-to-string + (format git " config --global github.%s %s" key value)))) + +(defun github-auth-info () + "Returns the user's GitHub authorization information. +Searches for a GitHub username and token in the global git config, +and returns (USERNAME . TOKEN). If nothing is found, prompts +for the info then sets it to the git config." + (interactive) + + ;; If we've been called within a scope that already has this + ;; defined, don't take the time to get it again. + (if (boundp '*github-auth-info*) + *github-auth-info* + + (let* ((user (or github-user (github-config "user"))) + (token (or github-token (github-config "token")))) + + (when (not user) + (setq user (read-string "GitHub username: ")) + (github-set-config "user" user)) + + (when (not token) + (setq token (read-string "GitHub API token: ")) + (github-set-config "token" token)) + + (cons user token)))) + +(defmacro github-with-auth-info (login token &rest body) + "Binds the github authentication credentials to `login' and `token'. +The credentials are retrieved at most once within the body of this macro." + (declare (indent 2)) + `(let ((*github-auth-info* (github-auth-info))) + (destructuring-bind (,login . ,token) *github-auth-info* + ,@body))) + +;;;###autoload +(defun gist-buffer (&optional private) + "Post the current buffer as a new paste at gist.github.com. +Copies the URL into the kill ring. + +With a prefix argument, makes a private paste." + (interactive "P") + (gist-region (point-min) (point-max) private)) + +;;;###autoload +(defun gist-buffer-private () + "Post the current buffer as a new private paste at gist.github.com. +Copies the URL into the kill ring." + (interactive) + (gist-region-private (point-min) (point-max))) + +;;;###autoload +(defun gist-region-or-buffer (&optional private) + "Post either the current region, or if mark is not set, the current buffer as a new paste at gist.github.com +Copies the URL into the kill ring. + +With a prefix argument, makes a private paste." + (interactive "P") + (condition-case nil + (gist-region (point) (mark) private) + (mark-inactive (gist-buffer private)))) + +;;;###autoload +(defun gist-region-or-buffer-private () + "Post either the current region, or if mark is not set, the current buffer as a new private paste at gist.github.com +Copies the URL into the kill ring." + (interactive) + (condition-case nil + (gist-region-private (point) (mark)) + (mark-inactive (gist-buffer-private)))) + +(defvar gist-fetch-url "http://gist.github.com/%d.txt" + "Raw Gist content URL format") + +;;;###autoload +(defun gist-list () + "Displays a list of all of the current user's gists in a new buffer." + (interactive) + (message "Retrieving list of your gists...") + (github-with-auth-info login token + (gist-request + (format "http://gist.github.com/api/v1/xml/gists/%s" login) + 'gist-lists-retrieved-callback))) + +(defun gist-lists-retrieved-callback (status) + "Called when the list of gists has been retrieved. Parses the result +and displays the list." + (goto-char (point-min)) + (search-forward " element." + (let* ((children (xml-node-children node))) + (car (xml-node-children (assq sym children))))) + +(defun gist-xml-cleanup (xml-list) + "Removes empty strings or whitespace nodes from the `xml-list'. +Borrowed from rss.el." + (mapcar 'gist-xml-cleanup-node xml-list)) + +(defun gist-xml-cleanup-node (node) + "Recursively removes whitespace and empty strings from the given xml `node'. +Borrowed from rss.el." + (apply 'list + (xml-node-name node) + (xml-node-attributes node) + (let (new) + (dolist (child (xml-node-children node)) + (if (stringp child) + (or (string-match "\\`[ \t\n]+\\'" child) + (push child new)) + (push (gist-xml-cleanup-node child) new))) + (nreverse new)))) + +;;;###autoload +(defun gist-fetch (id) + "Fetches a Gist and inserts it into a new buffer +If the Gist already exists in a buffer, switches to it" + (interactive "nGist ID: ") + + (let* ((gist-buffer-name (format "*gist %d*" id)) + (gist-buffer (get-buffer gist-buffer-name))) + (if (bufferp gist-buffer) + (switch-to-buffer-other-window gist-buffer) + (progn + (message "Fetching Gist %d..." id) + (setq gist-buffer + (url-retrieve-synchronously (format gist-fetch-url id))) + (with-current-buffer gist-buffer + (rename-buffer gist-buffer-name t) + (goto-char (point-min)) + (search-forward-regexp "\n\n") + (delete-region (point-min) (point)) + (set-buffer-modified-p nil)) + (switch-to-buffer-other-window gist-buffer))))) + +(provide 'gist) +;;; gist.el ends here. \ No newline at end of file diff --git a/emacs/graphviz-dot-mode.el b/emacs/graphviz-dot-mode.el new file mode 100644 index 0000000..ebaa1aa --- /dev/null +++ b/emacs/graphviz-dot-mode.el @@ -0,0 +1,919 @@ +;;; graphviz-dot-mode.el --- Mode for the dot-language used by graphviz (att). + +;; Copyright (C) 2002 - 2005 Pieter Pareit + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2 of +;; the License, or (at your option) any later version. + +;; This program is distributed in the hope that it will be +;; useful, but WITHOUT ANY WARRANTY; without even the implied +;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +;; PURPOSE. See the GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public +;; License along with this program; if not, write to the Free +;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +;; MA 02111-1307 USA + +;; Authors: Pieter Pareit +;; Rubens Ramos +;; Maintainer: Pieter Pareit +;; Homepage: http://users.skynet.be/ppareit/projects/graphviz-dot-mode/graphviz-dot-mode.html +;; Created: 28 Oct 2002 +;; Last modified: 24 Feb 2005 +;; Version: 0.3.4 +;; Keywords: mode dot dot-language dotlanguage graphviz graphs att + +;;; Commentary: +;; Use this mode for editing files in the dot-language (www.graphviz.org and +;; http://www.research.att.com/sw/tools/graphviz/). +;; +;; To use graphviz-dot-mode, add +;; (load-file "PATH_TO_FILE/graphviz-dot-mode.el") +;; to your ~/.emacs(.el) or ~/.xemacs/init.el +;; +;; The graphviz-dot-mode will do font locking, indentation, preview of graphs +;; and eases compilation/error location. There is support for both GNU Emacs +;; and XEmacs. +;; +;; Font locking is automatic, indentation uses the same commands as +;; other modes, tab, M-j and C-M-q. Insertion of comments uses the +;; same commands as other modes, M-; . You can compile a file using +;; M-x compile or C-c c, after that M-x next-error will also work. +;; There is support for viewing an generated image with C-c p. + +;;; Todo: +;; * cleanup the mess of graphviz-dot-compilation-parse-errors +;; * electric indentation is fundamentally broken, because +;; {...} are also used for record nodes. You could argue, I suppose, that +;; many diagrams don't need those, but it would be worth having a note (and +;; it makes sense that the default is now for electric indentation to be +;; off). + +;;; History: + +;; Version 0.3.4 bug fixes +;; 24/02/2005: * fixed a bug in graphviz-dot-preview +;; Version 0.3.3 bug fixes +;; 13/02/2005: Reuben Thomas +;; * add graphviz-dot-indent-width +;; Version 0.3.2 bug fixes +;; 25/03/2004: Rubens Ramos +;; * semi-colons and brackets are added when electric +;; behaviour is disabled. +;; * electric characters do not behave electrically inside +;; comments or strings. +;; * default for electric-braces is disabled now (makes more +;; sense I guess). +;; * using read-from-minibuffer instead of read-shell-command +;; for emacs. +;; * Fixed test for easymenu, so that it works on older +;; versions of XEmacs. +;; * Fixed indentation error when trying to indent last brace +;; of an empty graph. +;; * region-active-p does not exist in emacs (21.2 at least), +;; so removed from code +;; * Added uncomment menu option +;; Version 0.3.1 bug fixes +;; 03/03/2004: * backward-word needs argument for older emacs +;; Version 0.3 added features and fixed bugs +;; 10/01/2004: fixed a bug in graphviz-dot-indent-graph +;; 08/01/2004: Rubens Ramos +;; * added customization support +;; * Now it works on XEmacs and Emacs +;; * Added support to use an external Viewer +;; * Now things do not break when dot mode is entered +;; when there is no buffer name, but the side effect is +;; that in this case, the compilation command is not +;; correct. +;; * Preview works on XEmacs and emacs. +;; * Electric indentation on newline +;; * Minor changes to indentation +;; * Added keyword completion (but could be A LOT better) +;; * There are still a couple of ugly hacks. Look for 'RR'. +;; Version 0.2 added features +;; 11/11/2002: added preview support. +;; 10/11/2002: indent a graph or subgraph at once with C-M-q. +;; 08/11/2002: relaxed rules for indentation, the may now be extra chars +;; after beginning of graph (comment's for example). +;; Version 0.1.2 bug fixes and naming issues +;; 06/11/2002: renamed dot-font-lock-defaults to dot-font-lock-keywords. +;; added some documentation to dot-colors. +;; provided a much better way to handle my max-specpdl-size +;; problem. +;; added an extra autoload cookie (hope this helps, as I don't +;; yet use autoload myself) +;; Version 0.1.1 bug fixes +;; 06/11/2002: added an missing attribute, for font-locking to work. +;; fixed the regex generating, so that it only recognizes +;; whole words +;; 05/11/2002: there can now be extra white space chars after an '{'. +;; 04/11/2002: Why I use max-specpdl-size is now documented, and old value +;; gets restored. +;; Version 0.1 initial release +;; 02/11/2002: implemented parser for *compilation* of a .dot file. +;; 01/11/2002: implemented compilation of an .dot file. +;; 31/10/2002: added syntax-table to the mode. +;; 30/10/2002: implemented indentation code. +;; 29/10/2002: implemented all of font-lock. +;; 28/10/2002: derived graphviz-dot-mode from fundamental-mode, started +;; implementing font-lock. + +;;; Code: + +(defconst graphviz-dot-mode-version "0.3.3" + "Version of `graphviz-dot-mode.el'.") + +(defgroup graphviz nil + "Major mode for editing Graphviz Dot files" + :group 'tools) + +(defun graphviz-dot-customize () + "Run \\[customize-group] for the `graphviz' group." + (interactive) + (customize-group 'graphviz)) + +(defvar graphviz-dot-mode-abbrev-table nil + "Abbrev table in use in Graphviz Dot mode buffers.") +(define-abbrev-table 'graphviz-dot-mode-abbrev-table ()) + +(defcustom graphviz-dot-dot-program "dot" + "*Location of the dot program. This is used by `compile'." + :type 'string + :group 'graphviz) + +(defcustom graphviz-dot-view-command "doted %s" + "*External program to run on the buffer. You can use `%s' in this string, +and it will be substituted by the buffer name." + :type 'string + :group 'graphviz) + +(defcustom graphviz-dot-view-edit-command nil + "*Whether to allow the user to edit the command to run an external +viewer." + :type 'boolean + :group 'graphviz) + +(defcustom graphviz-dot-save-before-view t + "*If not nil, M-x graphviz-dot-view saves the current buffer before running +the command." + :type 'boolean + :group 'graphviz) + +(defcustom graphviz-dot-auto-indent-on-newline t + "*If not nil, `electric-graphviz-dot-terminate-line' is executed in a line is terminated." + :type 'boolean + :group 'graphviz) + +(defcustom graphviz-dot-indent-width default-tab-width + "*Indentation width in Graphviz Dot mode buffers." + :type 'integer + :group 'graphviz) + +(defcustom graphviz-dot-auto-indent-on-braces nil + "*If not nil, `electric-graphviz-dot-open-brace' and `electric-graphviz-dot-close-brace' are executed when { or } are typed" + :type 'boolean + :group 'graphviz) + +(defcustom graphviz-dot-auto-indent-on-semi t + "*If not nil, `electric-graphviz-dot-semi' is executed when semicolon is typed" + :type 'boolean + :group 'graphviz) + +(defcustom graphviz-dot-preview-extension "png" + "*The extension to use for the compilation and preview commands. The format +for the compilation command is +`dot -T file.dot > file.'." + :type 'string + :group 'graphviz) + +(defcustom graphviz-dot-toggle-completions nil + "*Non-nil means that repeated use of \ +\\\\[graphviz-dot-complete-word] will toggle the possible +completions in the minibuffer. Normally, when there is more than one possible +completion, a buffer will display all completions." + :type 'boolean + :group 'graphviz) + +(defcustom graphviz-dot-delete-completions nil + "*Non-nil means that the completion buffer is automatically deleted when a +key is pressed." + :type 'boolean + :group 'graphviz) + +(defcustom graphviz-dot-attr-keywords + '("graph" "digraph" "subgraph" "node" "edge" "strict" "rankdir" + "size" "page" "Damping" "Epsilon" "URL" "arrowhead" "arrowsize" + "arrowtail" "bb" "bgcolor" "bottomlabel" "center" "clusterrank" + "color" "comment" "compound" "concentrate" "constraint" "decorate" + "dim" "dir" "distortion" "fillcolor" "fixedsize" "fontcolor" + "fontname" "fontpath" "fontsize" "group" "headURL" "headlabel" + "headport" "height" "label" "labelangle" "labeldistance" "labelfloat" + "labelfontcolor" "labelfontname" "labelfontsize" "labeljust" + "labelloc" "layer" "layers" "len" "lhead" "lp" "ltail" "margin" + "maxiter" "mclimit" "minlen" "model" "nodesep" "normalize" "nslimit" + "nslimit1" "ordering" "orientation" "overlap" "pack" "pagedir" + "pencolor" "peripheries" "pin" "pos" "quantum" "rank" "ranksep" + "ratio" "rects" "regular" "remincross" "rotate" "samehead" "sametail" + "samplepoint" "searchsize" "sep" "shape" "shapefile" "showboxes" + "sides" "skew" "splines" "start" "style" "stylesheet" "tailURL" + "taillabel" "tailport" "toplabel" "vertices" "voro_margin" "weight" + "z") + "*Keywords for attribute names in a graph. This is used by the auto +completion code. The actual completion tables are built when the mode +is loaded, so changes to this are not immediately visible." + :type '(repeat (string :tag "Keyword")) + :group 'graphviz) + +(defcustom graphviz-dot-value-keywords + '("true" "false" "normal" "inv" "dot" "invdot" "odot" "invodot" + "none" "tee" "empty" "invempty" "diamond" "odiamond" "box" "obox" + "open" "crow" "halfopen" "local" "global" "none" "forward" "back" + "both" "none" "BL" "BR" "TL" "TR" "RB" "RT" "LB" "LT" ":n" ":ne" ":e" + ":se" ":s" ":sw" ":w" ":nw" "same" "min" "source" "max" "sink" "LR" + "box" "polygon" "ellipse" "circle" "point" "egg" "triangle" + "plaintext" "diamond" "trapezium" "parallelogram" "house" "hexagon" + "octagon" "doublecircle" "doubleoctagon" "tripleoctagon" "invtriangle" + "invtrapezium" "invhouse" "Mdiamond" "Msquare" "Mcircle" "record" + "Mrecord" "dashed" "dotted" "solid" "invis" "bold" "filled" + "diagonals" "rounded" ) + "*Keywords for attribute values. This is used by the auto completion +code. The actual completion tables are built when the mode is loaded, +so changes to this are not immediately visible." + :type '(repeat (string :tag "Keyword")) + :group 'graphviz) + +;;; Font-locking: +(defvar graphviz-dot-colors-list + '(aliceblue antiquewhite antiquewhite1 antiquewhite2 + antiquewhite3 antiquewhite4 aquamarine aquamarine1 + aquamarine2 aquamarine3 aquamarine4 azure azure1 + azure2 azure3 azure4 beige bisque bisque1 bisque2 + bisque3 bisque4 black blanchedalmond blue blue1 + blue2 blue3 blue4 blueviolet brown brown1 brown2 + brown3 brown4 burlywood burlywood1 burlywood2 + burlywood3 burlywood4 cadetblue cadetblue1 + cadetblue2 cadetblue3 cadetblue4 chartreuse + chartreuse1 chartreuse2 chartreuse3 chartreuse4 + chocolate chocolate1 chocolate2 chocolate3 chocolate4 + coral coral1 coral2 coral3 coral4 cornflowerblue + cornsilk cornsilk1 cornsilk2 cornsilk3 cornsilk4 + crimson cyan cyan1 cyan2 cyan3 cyan4 darkgoldenrod + darkgoldenrod1 darkgoldenrod2 darkgoldenrod3 + darkgoldenrod4 darkgreen darkkhaki darkolivegreen + darkolivegreen1 darkolivegreen2 darkolivegreen3 + darkolivegreen4 darkorange darkorange1 darkorange2 + darkorange3 darkorange4 darkorchid darkorchid1 + darkorchid2 darkorchid3 darkorchid4 darksalmon + darkseagreen darkseagreen1 darkseagreen2 + darkseagreen3 darkseagreen4 darkslateblue + darkslategray darkslategray1 darkslategray2 + darkslategray3 darkslategray4 darkslategrey + darkturquoise darkviolet deeppink deeppink1 + deeppink2 deeppink3 deeppink4 deepskyblue + deepskyblue1 deepskyblue2 deepskyblue3 deepskyblue4 + dimgray dimgrey dodgerblue dodgerblue1 dodgerblue2 + dodgerblue3 dodgerblue4 firebrick firebrick1 + firebrick2 firebrick3 firebrick4 floralwhite + forestgreen gainsboro ghostwhite gold gold1 gold2 + gold3 gold4 goldenrod goldenrod1 goldenrod2 + goldenrod3 goldenrod4 gray gray0 gray1 gray10 gray100 + gray11 gray12 gray13 gray14 gray15 gray16 gray17 + gray18 gray19 gray2 gray20 gray21 gray22 gray23 + gray24 gray25 gray26 gray27 gray28 gray29 gray3 + gray30 gray31 gray32 gray33 gray34 gray35 gray36 + gray37 gray38 gray39 gray4 gray40 gray41 gray42 + gray43 gray44 gray45 gray46 gray47 gray48 gray49 + gray5 gray50 gray51 gray52 gray53 gray54 gray55 + gray56 gray57 gray58 gray59 gray6 gray60 gray61 + gray62 gray63 gray64 gray65 gray66 gray67 gray68 + gray69 gray7 gray70 gray71 gray72 gray73 gray74 + gray75 gray76 gray77 gray78 gray79 gray8 gray80 + gray81 gray82 gray83 gray84 gray85 gray86 gray87 + gray88 gray89 gray9 gray90 gray91 gray92 gray93 + gray94 gray95 gray96 gray97 gray98 gray99 green + green1 green2 green3 green4 greenyellow grey grey0 + grey1 grey10 grey100 grey11 grey12 grey13 grey14 + grey15 grey16 grey17 grey18 grey19 grey2 grey20 + grey21 grey22 grey23 grey24 grey25 grey26 grey27 + grey28 grey29 grey3 grey30 grey31 grey32 grey33 + grey34 grey35 grey36 grey37 grey38 grey39 grey4 + grey40 grey41 grey42 grey43 grey44 grey45 grey46 + grey47 grey48 grey49 grey5 grey50 grey51 grey52 + grey53 grey54 grey55 grey56 grey57 grey58 grey59 + grey6 grey60 grey61 grey62 grey63 grey64 grey65 + grey66 grey67 grey68 grey69 grey7 grey70 grey71 + grey72 grey73 grey74 grey75 grey76 grey77 grey78 + grey79 grey8 grey80 grey81 grey82 grey83 grey84 + grey85 grey86 grey87 grey88 grey89 grey9 grey90 + grey91 grey92 grey93 grey94 grey95 grey96 grey97 + grey98 grey99 honeydew honeydew1 honeydew2 honeydew3 + honeydew4 hotpink hotpink1 hotpink2 hotpink3 hotpink4 + indianred indianred1 indianred2 indianred3 indianred4 + indigo ivory ivory1 ivory2 ivory3 ivory4 khaki khaki1 + khaki2 khaki3 khaki4 lavender lavenderblush + lavenderblush1 lavenderblush2 lavenderblush3 + lavenderblush4 lawngreen lemonchiffon lemonchiffon1 + lemonchiffon2 lemonchiffon3 lemonchiffon4 lightblue + lightblue1 lightblue2 lightblue3 lightblue4 + lightcoral lightcyan lightcyan1 lightcyan2 lightcyan3 + lightcyan4 lightgoldenrod lightgoldenrod1 + lightgoldenrod2 lightgoldenrod3 lightgoldenrod4 + lightgoldenrodyellow lightgray lightgrey lightpink + lightpink1 lightpink2 lightpink3 lightpink4 + lightsalmon lightsalmon1 lightsalmon2 lightsalmon3 + lightsalmon4 lightseagreen lightskyblue lightskyblue1 + lightskyblue2 lightskyblue3 lightskyblue4 + lightslateblue lightslategray lightslategrey + lightsteelblue lightsteelblue1 lightsteelblue2 + lightsteelblue3 lightsteelblue4 lightyellow + lightyellow1 lightyellow2 lightyellow3 lightyellow4 + limegreen linen magenta magenta1 magenta2 magenta3 + magenta4 maroon maroon1 maroon2 maroon3 maroon4 + mediumaquamarine mediumblue mediumorchid + mediumorchid1 mediumorchid2 mediumorchid3 + mediumorchid4 mediumpurple mediumpurple1 + mediumpurple2 mediumpurple3 mediumpurple4 + mediumseagreen mediumslateblue mediumspringgreen + mediumturquoise mediumvioletred midnightblue + mintcream mistyrose mistyrose1 mistyrose2 mistyrose3 + mistyrose4 moccasin navajowhite navajowhite1 + navajowhite2 navajowhite3 navajowhite4 navy navyblue + oldlace olivedrab olivedrap olivedrab1 olivedrab2 + olivedrap3 oragne palegoldenrod palegreen palegreen1 + palegreen2 palegreen3 palegreen4 paleturquoise + paleturquoise1 paleturquoise2 paleturquoise3 + paleturquoise4 palevioletred palevioletred1 + palevioletred2 palevioletred3 palevioletred4 + papayawhip peachpuff peachpuff1 peachpuff2 + peachpuff3 peachpuff4 peru pink pink1 pink2 pink3 + pink4 plum plum1 plum2 plum3 plum4 powderblue + purple purple1 purple2 purple3 purple4 red red1 red2 + red3 red4 rosybrown rosybrown1 rosybrown2 rosybrown3 + rosybrown4 royalblue royalblue1 royalblue2 royalblue3 + royalblue4 saddlebrown salmon salmon1 salmon2 salmon3 + salmon4 sandybrown seagreen seagreen1 seagreen2 + seagreen3 seagreen4 seashell seashell1 seashell2 + seashell3 seashell4 sienna sienna1 sienna2 sienna3 + sienna4 skyblue skyblue1 skyblue2 skyblue3 skyblue4 + slateblue slateblue1 slateblue2 slateblue3 slateblue4 + slategray slategray1 slategray2 slategray3 slategray4 + slategrey snow snow1 snow2 snow3 snow4 springgreen + springgreen1 springgreen2 springgreen3 springgreen4 + steelblue steelblue1 steelblue2 steelblue3 steelblue4 + tan tan1 tan2 tan3 tan4 thistle thistle1 thistle2 + thistle3 thistle4 tomato tomato1 tomato2 tomato3 + tomato4 transparent turquoise turquoise1 turquoise2 + turquoise3 turquoise4 violet violetred violetred1 + violetred2 violetred3 violetred4 wheat wheat1 wheat2 + wheat3 wheat4 white whitesmoke yellow yellow1 yellow2 + yellow3 yellow4 yellowgreen) + "Possible color constants in the dot language. +The list of constant is available at http://www.research.att.com/~erg/graphviz\ +/info/colors.html") + + +(defvar graphviz-dot-color-keywords + (mapcar 'symbol-name graphviz-dot-colors-list)) + +(defvar graphviz-attr-keywords + (mapcar '(lambda (elm) (cons elm 0)) graphviz-dot-attr-keywords)) + +(defvar graphviz-value-keywords + (mapcar '(lambda (elm) (cons elm 0)) graphviz-dot-value-keywords)) + +(defvar graphviz-color-keywords + (mapcar '(lambda (elm) (cons elm 0)) graphviz-dot-color-keywords)) + +;;; Key map +(defvar graphviz-dot-mode-map () + "Keymap used in Graphviz Dot mode.") + +(if graphviz-dot-mode-map + () + (let ((map (make-sparse-keymap))) + (define-key map "\r" 'electric-graphviz-dot-terminate-line) + (define-key map "{" 'electric-graphviz-dot-open-brace) + (define-key map "}" 'electric-graphviz-dot-close-brace) + (define-key map ";" 'electric-graphviz-dot-semi) + (define-key map "\M-\t" 'graphviz-dot-complete-word) + (define-key map "\C-\M-q" 'graphviz-dot-indent-graph) + (define-key map "\C-cp" 'graphviz-dot-preview) + (define-key map "\C-cc" 'compile) + (define-key map "\C-cv" 'graphviz-dot-view) + (define-key map "\C-c\C-c" 'comment-region) + (define-key map "\C-c\C-u" 'graphviz-dot-uncomment-region) + (setq graphviz-dot-mode-map map) + )) + +;;; Syntax table +(defvar graphviz-dot-mode-syntax-table nil + "Syntax table for `graphviz-dot-mode'.") + +(if graphviz-dot-mode-syntax-table + () + (let ((st (make-syntax-table))) + (modify-syntax-entry ?/ ". 124b" st) + (modify-syntax-entry ?* ". 23" st) + (modify-syntax-entry ?\n "> b" st) + (modify-syntax-entry ?= "." st) + (modify-syntax-entry ?_ "_" st) + (modify-syntax-entry ?- "_" st) + (modify-syntax-entry ?> "." st) + (modify-syntax-entry ?[ "(" st) + (modify-syntax-entry ?] ")" st) + (modify-syntax-entry ?\" "\"" st) + (setq graphviz-dot-mode-syntax-table st) + )) + +(defvar graphviz-dot-font-lock-keywords + `(("\\(:?di\\|sub\\)?graph \\(\\sw+\\)" + (2 font-lock-function-name-face)) + (,(regexp-opt graphviz-dot-value-keywords 'words) + . font-lock-reference-face) + ;; to build the font-locking for the colors, + ;; we need more room for max-specpdl-size, + ;; after that we take the list of symbols, + ;; convert them to a list of strings, and make + ;; an optimized regexp from them + (,(let ((max-specpdl-size (max max-specpdl-size 1200))) + (regexp-opt graphviz-dot-color-keywords)) + . font-lock-string-face) + (,(concat + (regexp-opt graphviz-dot-attr-keywords 'words) + "[ \\t\\n]*=") + ;; RR - ugly, really, but I dont know why xemacs does not work + ;; if I change the next car to "1"... + (0 font-lock-variable-name-face))) + "Keyword highlighting specification for `graphviz-dot-mode'.") + +;;;###autoload +(defun graphviz-dot-mode () + "Major mode for the dot language. \\ +TAB indents for graph lines. + +\\[graphviz-dot-indent-graph]\t- Indentaion function. +\\[graphviz-dot-preview]\t- Previews graph in a buffer. +\\[graphviz-dot-view]\t- Views graph in an external viewer. +\\[graphviz-dot-indent-line]\t- Indents current line of code. +\\[graphviz-dot-complete-word]\t- Completes the current word. +\\[electric-graphviz-dot-terminate-line]\t- Electric newline. +\\[electric-graphviz-dot-open-brace]\t- Electric open braces. +\\[electric-graphviz-dot-close-brace]\t- Electric close braces. +\\[electric-graphviz-dot-semi]\t- Electric semi colons. + +Variables specific to this mode: + + graphviz-dot-dot-program (default `dot') + Location of the dot program. + graphviz-dot-view-command (default `doted %s') + Command to run when `graphviz-dot-view' is executed. + graphviz-dot-view-edit-command (default nil) + If the user should be asked to edit the view command. + graphviz-dot-save-before-view (default t) + Automatically save current buffer berore `graphviz-dot-view'. + graphviz-dot-preview-extension (default `png') + File type to use for `graphviz-dot-preview'. + graphviz-dot-auto-indent-on-newline (default t) + Whether to run `electric-graphviz-dot-terminate-line' when + newline is entered. + graphviz-dot-auto-indent-on-braces (default t) + Whether to run `electric-graphviz-dot-open-brace' and + `electric-graphviz-dot-close-brace' when braces are + entered. + graphviz-dot-auto-indent-on-semi (default t) + Whether to run `electric-graphviz-dot-semi' when semi colon + is typed. + graphviz-dot-toggle-completions (default nil) + If completions should be displayed in the buffer instead of a + completion buffer when \\[graphviz-dot-complete-word] is + pressed repeatedly. + +This mode can be customized by running \\[graphviz-dot-customize]. + +Turning on Graphviz Dot mode calls the value of the variable +`graphviz-dot-mode-hook' with no args, if that value is non-nil." + (interactive) + (kill-all-local-variables) + (use-local-map graphviz-dot-mode-map) + (setq major-mode 'graphviz-dot-mode) + (setq mode-name "dot") + (setq local-abbrev-table graphviz-dot-mode-abbrev-table) + (set-syntax-table graphviz-dot-mode-syntax-table) + (set (make-local-variable 'indent-line-function) 'graphviz-dot-indent-line) + (set (make-local-variable 'comment-start) "//") + (set (make-local-variable 'comment-start-skip) "/\\*+ *\\|//+ *") + (set (make-local-variable 'font-lock-defaults) + '(graphviz-dot-font-lock-keywords)) + ;; RR - If user is running this in the scratch buffer, there is no + ;; buffer file name... + (if (buffer-file-name) + (set (make-local-variable 'compile-command) + (concat graphviz-dot-dot-program + " -T" graphviz-dot-preview-extension " " + buffer-file-name + " > " + (file-name-sans-extension + buffer-file-name) + "." graphviz-dot-preview-extension))) + (set (make-local-variable 'compilation-parse-errors-function) + 'graphviz-dot-compilation-parse-errors) + (if dot-menu + (easy-menu-add dot-menu)) + (run-hooks 'graphviz-dot-mode-hook) + ) + +;;;; Menu definitions + +(defvar dot-menu nil + "Menu for Graphviz Dot Mode. +This menu will get created automatically if you have the `easymenu' +package. Note that the latest X/Emacs releases contain this package.") + +(and (condition-case nil + (require 'easymenu) + (error nil)) + (easy-menu-define + dot-menu graphviz-dot-mode-map "Graphviz Mode menu" + '("Graphviz" + ["Indent Graph" graphviz-dot-indent-graph t] + ["Comment Out Region" comment-region (mark)] + ["Uncomment Region" graphviz-dot-uncomment-region (mark)] + "-" + ["Compile" compile t] + ["Preview" graphviz-dot-preview + (and (buffer-file-name) + (not (buffer-modified-p)))] + ["External Viewer" graphviz-dot-view (buffer-file-name)] + "-" + ["Customize..." graphviz-dot-customize t] + ))) + +;;;; Compilation + +;; note on graphviz-dot-compilation-parse-errors: +;; It would nicer if we could just use compilation-error-regexp-alist +;; to do that, 3 options: +;; - still write dot-compilation-parse-errors, don't build +;; a return list, but modify the *compilation* buffer +;; in a way compilation-error-regexp-alist recognizes the +;; format. +;; to do that, I should globally change compilation-parse-function +;; to this function, and call the old value of comp..-parse-fun.. +;; to provide the return value. +;; two drawbacks are that, every compilation would be run through +;; this function (performance) and that in autoload there would +;; be a chance that this function would not yet be known. +;; - let the compilation run through a filter that would +;; modify the output of dot or neato: +;; dot -Tpng input.dot | filter +;; drawback: ugly, extra work for user, extra decency ... +;; no-option +;; - modify dot and neato !!! (PP:15/02/2005 seems to have happend, +;; so version 0.4.0 should clean this mess up!) +(defun graphviz-dot-compilation-parse-errors (limit-search find-at-least) + "Parse the current buffer for dot errors. +See variable `compilation-parse-errors-functions' for interface." + (interactive) + (save-excursion + (set-buffer "*compilation*") + (goto-char (point-min)) + (setq compilation-error-list nil) + (let (buffer-of-error) + (while (not (eobp)) + (cond + ((looking-at "^dot\\( -[^ ]+\\)* \\(.*\\)") + (setq buffer-of-error (find-file-noselect + (buffer-substring-no-properties + (nth 4 (match-data t)) + (nth 5 (match-data t)))))) + ((looking-at ".*:.*line \\([0-9]+\\)") + (let ((line-of-error + (string-to-number (buffer-substring-no-properties + (nth 2 (match-data t)) + (nth 3 (match-data t)))))) + (setq compilation-error-list + (cons + (cons + (point-marker) + (save-excursion + (set-buffer buffer-of-error) + (goto-line line-of-error) + (beginning-of-line) + (point-marker))) + compilation-error-list)))) + (t t)) + (forward-line 1)) ))) + +;;;; +;;;; Indentation +;;;; +(defun graphviz-dot-uncomment-region (begin end) + "Uncomments a region of code." + (interactive "r") + (comment-region begin end '(4))) + +(defun graphviz-dot-indent-line () + "Indent current line of dot code." + (interactive) + (if (bolp) + (graphviz-dot-real-indent-line) + (save-excursion + (graphviz-dot-real-indent-line)))) + +(defun graphviz-dot-real-indent-line () + "Indent current line of dot code." + (beginning-of-line) + (cond + ((bobp) + ;; simple case, indent to 0 + (indent-line-to 0)) + ((looking-at "^[ \t]*}[ \t]*$") + ;; block closing, deindent relative to previous line + (indent-line-to (save-excursion + (forward-line -1) + (max 0 (- (current-indentation) graphviz-dot-indent-width))))) + ;; other cases need to look at previous lines + (t + (indent-line-to (save-excursion + (forward-line -1) + (cond + ((looking-at "\\(^.*{[^}]*$\\)") + ;; previous line opened a block + ;; indent to that line + (+ (current-indentation) graphviz-dot-indent-width)) + ((and (not (looking-at ".*\\[.*\\].*")) + (looking-at ".*\\[.*")) ; TODO:PP : can be 1 regex + ;; previous line started filling + ;; attributes, intend to that start + (search-forward "[") + (current-column)) + ((and (not (looking-at ".*\\[.*\\].*")) + (looking-at ".*\\].*")) ; TODO:PP : " + ;; previous line stopped filling + ;; attributes, find the line that started + ;; filling them and indent to that line + (while (or (looking-at ".*\\[.*\\].*") + (not (looking-at ".*\\[.*"))) ; TODO:PP : " + (forward-line -1)) + (current-indentation)) + (t + ;; default case, indent the + ;; same as previous line + (current-indentation)) ))) ))) + +(defun graphviz-dot-indent-graph () + "Indent the graph/digraph/subgraph where point is at. +This will first teach the beginning of the graph were point is at, and +then indent this and each subgraph in it." + (interactive) + (save-excursion + ;; position point at start of graph + (while (not (or (looking-at "\\(^.*{[^}]*$\\)") (bobp))) + (forward-line -1)) + ;; bracket { one +; bracket } one - + (let ((bracket-count 0)) + (while + (progn + (cond + ;; update bracket-count + ((looking-at "\\(^.*{[^}]*$\\)") + (setq bracket-count (+ bracket-count 1))) + ;; update bracket-count + ((looking-at "^[ \t]*}[ \t]*$") + (setq bracket-count (- bracket-count 1)))) + ;; indent this line and move on + (graphviz-dot-indent-line) + (forward-line 1) + ;; as long as we are not completed or at end of buffer + (and (> bracket-count 0) (not (eobp)))))))) + +;;;; +;;;; Electric indentation +;;;; +(defun graphviz-dot-comment-or-string-p () + (let ((state (parse-partial-sexp (point-min) (point)))) + (or (nth 4 state) (nth 3 state)))) + +(defun graphviz-dot-newline-and-indent () + (save-excursion + (beginning-of-line) + (skip-chars-forward " \t") + (graphviz-dot-indent-line)) + (delete-horizontal-space) + (newline) + (graphviz-dot-indent-line)) + +(defun electric-graphviz-dot-terminate-line () + "Terminate line and indent next line." + (interactive) + (if graphviz-dot-auto-indent-on-newline + (graphviz-dot-newline-and-indent) + (newline))) + +(defun electric-graphviz-dot-open-brace () + "Terminate line and indent next line." + (interactive) + (insert "{") + (if (and graphviz-dot-auto-indent-on-braces + (not (graphviz-dot-comment-or-string-p))) + (graphviz-dot-newline-and-indent))) + +(defun electric-graphviz-dot-close-brace () + "Terminate line and indent next line." + (interactive) + (insert "}") + (if (and graphviz-dot-auto-indent-on-braces + (not (graphviz-dot-comment-or-string-p))) + (progn + (save-excursion + (beginning-of-line) + (skip-chars-forward " \t") + (graphviz-dot-indent-line)) + (newline) + (graphviz-dot-indent-line)))) + +(defun electric-graphviz-dot-semi () + "Terminate line and indent next line." + (interactive) + (insert ";") + (if (and graphviz-dot-auto-indent-on-semi + (not (graphviz-dot-comment-or-string-p))) + (graphviz-dot-newline-and-indent))) + +;;;; +;;;; Preview +;;;; +(defun graphviz-dot-preview () + "Shows an example of the current dot file in an emacs buffer. +This assumes that we are running GNU Emacs or XEmacs under a windowing system. +See `image-file-name-extensions' for customizing the files that can be +loaded in GNU Emacs, and `image-formats-alist' for XEmacs." + (interactive) + ;; unsafe to compile ourself, ask it to the user + (if (buffer-modified-p) + (message "Buffer needs to be compiled.") + (if (string-match "XEmacs" emacs-version) + ;; things are easier in XEmacs... + (find-file-other-window (concat (file-name-sans-extension + buffer-file-name) + "." graphviz-dot-preview-extension)) + ;; run through all the extensions for images + (let ((l image-file-name-extensions)) + (while + (let ((f (concat (file-name-sans-extension (buffer-file-name)) + "." + (car l)))) + ;; see if a file matches, might be best also to check + ;; if file is up to date TODO:PP + (if (file-exists-p f) + (progn (auto-image-file-mode 1) + ;; OK, this is ugly, I would need to + ;; know how I can reload a file in an existing buffer + (if (get-buffer "*preview*") + (kill-buffer "*preview*")) + (set-buffer (find-file-noselect f)) + (rename-buffer "*preview*") + (display-buffer (get-buffer "*preview*")) + ;; stop iterating + '()) + ;; will stop iterating when l is nil + (setq l (cdr l))))) + ;; each extension tested and nothing found, let user know + (when (eq l '()) + (message "No image found.")))))) + +;;;; +;;;; View +;;;; +(defun graphviz-dot-view () + "Runs an external viewer. This creates an external process every time it +is executed. If `graphviz-dot-save-before-view' is set, the current +buffer is saved before the command is executed." + (interactive) + (let ((cmd (if graphviz-dot-view-edit-command + (if (string-match "XEmacs" emacs-version) + (read-shell-command "View command: " + (format graphviz-dot-view-command + (buffer-file-name))) + (read-from-minibuffer "View command: " + (format graphviz-dot-view-command + (buffer-file-name)))) + (format graphviz-dot-view-command (buffer-file-name))))) + (if graphviz-dot-save-before-view + (save-buffer)) + (setq novaproc (start-process-shell-command + (downcase mode-name) nil cmd)) + (message (format "Executing `%s'..." cmd)))) + +;;;; +;;;; Completion +;;;; +(defvar graphviz-dot-str nil) +(defvar graphviz-dot-all nil) +(defvar graphviz-dot-pred nil) +(defvar graphviz-dot-buffer-to-use nil) +(defvar graphviz-dot-flag nil) + +(defun graphviz-dot-get-state () + "Returns the syntax state of the current point." + (let ((state (parse-partial-sexp (point-min) (point)))) + (cond + ((nth 4 state) 'comment) + ((nth 3 state) 'string) + ((not (nth 1 state)) 'out) + (t (save-excursion + (skip-chars-backward "^[,=\\[]{};") + (backward-char) + (cond + ((looking-at "[\\[,]{};") 'attribute) + ((looking-at "=") (progn + (backward-word 1) + (if (looking-at "[a-zA-Z]*color") + 'color + 'value))) + (t 'other))))))) + +(defun graphviz-dot-get-keywords () + "Return possible completions for a word" + (let ((state (graphviz-dot-get-state))) + (cond + ((equal state 'comment) ()) + ((equal state 'string) ()) + ((equal state 'out) graphviz-attr-keywords) + ((equal state 'value) graphviz-value-keywords) + ((equal state 'color) graphviz-color-keywords) + ((equal state 'attribute) graphviz-attr-keywords) + (t graphviz-attr-keywords)))) + +(defvar graphviz-dot-last-word-numb 0) +(defvar graphviz-dot-last-word-shown nil) +(defvar graphviz-dot-last-completions nil) + +(defun graphviz-dot-complete-word () + "Complete word at current point." + (interactive) + (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point))) + (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point))) + (graphviz-dot-str (buffer-substring b e)) + (allcomp (if (and graphviz-dot-toggle-completions + (string= graphviz-dot-last-word-shown + graphviz-dot-str)) + graphviz-dot-last-completions + (all-completions graphviz-dot-str + (graphviz-dot-get-keywords)))) + (match (if graphviz-dot-toggle-completions + "" (try-completion + graphviz-dot-str (mapcar '(lambda (elm) + (cons elm 0)) allcomp))))) + ;; Delete old string + (delete-region b e) + + ;; Toggle-completions inserts whole labels + (if graphviz-dot-toggle-completions + (progn + ;; Update entry number in list + (setq graphviz-dot-last-completions allcomp + graphviz-dot-last-word-numb + (if (>= graphviz-dot-last-word-numb (1- (length allcomp))) + 0 + (1+ graphviz-dot-last-word-numb))) + (setq graphviz-dot-last-word-shown + (elt allcomp graphviz-dot-last-word-numb)) + ;; Display next match or same string if no match was found + (if (not (null allcomp)) + (insert "" graphviz-dot-last-word-shown) + (insert "" graphviz-dot-str) + (message "(No match)"))) + ;; The other form of completion does not necessarily do that. + + ;; Insert match if found, or the original string if no match + (if (or (null match) (equal match 't)) + (progn (insert "" graphviz-dot-str) + (message "(No match)")) + (insert "" match)) + ;; Give message about current status of completion + (cond ((equal match 't) + (if (not (null (cdr allcomp))) + (message "(Complete but not unique)") + (message "(Sole completion)"))) + ;; Display buffer if the current completion didn't help + ;; on completing the label. + ((and (not (null (cdr allcomp))) (= (length graphviz-dot-str) + (length match))) + (with-output-to-temp-buffer "*Completions*" + (display-completion-list allcomp)) + ;; Wait for a keypress. Then delete *Completion* window + (momentary-string-display "" (point)) + (if graphviz-dot-delete-completions + (delete-window + (get-buffer-window (get-buffer "*Completions*")))) + ))))) + +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.dot\\'" . graphviz-dot-mode)) + +;;; graphviz-dot-mode.el ends here + diff --git a/emacs/highlight-parentheses.el b/emacs/highlight-parentheses.el new file mode 100644 index 0000000..8df50ab --- /dev/null +++ b/emacs/highlight-parentheses.el @@ -0,0 +1,157 @@ +;;; highlight-parentheses.el --- highlight surrounding parentheses +;; +;; Copyright (C) 2007, 2009 Nikolaj Schumacher +;; +;; Author: Nikolaj Schumacher +;; Version: 1.0.1 +;; Keywords: faces, matching +;; URL: http://nschum.de/src/emacs/highlight-parentheses/ +;; Compatibility: GNU Emacs 22.x, GNU Emacs 23.x +;; +;; This file is NOT part of GNU Emacs. +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License +;; as published by the Free Software Foundation; either version 2 +;; of the License, or (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . +;; +;;; Commentary: +;; +;; Add the following to your .emacs file: +;; (require 'highlight-parentheses) +;; +;; Enable `highlight-parentheses-mode'. +;; +;;; Change Log: +;; +;; 2009-03-19 (1.0.1) +;; Added setter for color variables. +;; +;; 2007-07-30 (1.0) +;; Added background highlighting and faces. +;; +;; 2007-05-15 (0.9.1) +;; Support for defcustom. +;; +;; 2007-04-26 (0.9) +;; Initial Release. +;; +;;; Code: + +(eval-when-compile (require 'cl)) + +(defgroup highlight-parentheses nil + "Highlight surrounding parentheses" + :group 'faces + :group 'matching) + +(defun hl-paren-set (variable value) + (set variable value) + (when (fboundp 'hl-paren-color-update) + (hl-paren-color-update))) + +(defcustom hl-paren-colors + '("firebrick1" "IndianRed1" "IndianRed3" "IndianRed4") + "*List of colors for the highlighted parentheses. +The list starts with the the inside parentheses and moves outwards." + :type '(repeat color) + :set 'hl-paren-set + :group 'highlight-parentheses) + +(defcustom hl-paren-background-colors nil + "*List of colors for the background highlighted parentheses. +The list starts with the the inside parentheses and moves outwards." + :type '(repeat color) + :set 'hl-paren-set + :group 'highlight-parentheses) + +(defface hl-paren-face nil + "*Face used for highlighting parentheses. +Color attributes might be overriden by `hl-paren-colors' and +`hl-paren-background-colors'." + :group 'highlight-parentheses) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defvar hl-paren-overlays nil + "This buffers currently active overlays.") +(make-variable-buffer-local 'hl-paren-overlays) + +(defvar hl-paren-last-point 0 + "The last point for which parentheses were highlighted. +This is used to prevent analyzing the same context over and over.") +(make-variable-buffer-local 'hl-paren-last-point) + +(defun hl-paren-highlight () + "Highlight the parentheses around point." + (unless (= (point) hl-paren-last-point) + (setq hl-paren-last-point (point)) + (let ((overlays hl-paren-overlays) + pos1 pos2 + (pos (point))) + (save-excursion + (condition-case err + (while (and (setq pos1 (cadr (syntax-ppss pos1))) + (cddr overlays)) + (move-overlay (pop overlays) pos1 (1+ pos1)) + (when (setq pos2 (scan-sexps pos1 1)) + (move-overlay (pop overlays) (1- pos2) pos2) + )) + (error nil)) + (goto-char pos)) + (dolist (ov overlays) + (move-overlay ov 1 1))))) + +;;;###autoload +(define-minor-mode highlight-parentheses-mode + "Minor mode to highlight the surrounding parentheses." + nil " hl-p" nil + (if highlight-parentheses-mode + (progn + (hl-paren-create-overlays) + (add-hook 'post-command-hook 'hl-paren-highlight nil t)) + (mapc 'delete-overlay hl-paren-overlays) + (kill-local-variable 'hl-paren-overlays) + (kill-local-variable 'hl-paren-point) + (remove-hook 'post-command-hook 'hl-paren-highlight t))) + +;;; overlays ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun hl-paren-create-overlays () + (let ((fg hl-paren-colors) + (bg hl-paren-background-colors) + attributes) + (while (or fg bg) + (setq attributes (face-attr-construct 'hl-paren-face)) + (when (car fg) + (setq attributes (plist-put attributes :foreground (car fg)))) + (pop fg) + (when (car bg) + (setq attributes (plist-put attributes :background (car bg)))) + (pop bg) + (dotimes (i 2) ;; front and back + (push (make-overlay 0 0) hl-paren-overlays) + (overlay-put (car hl-paren-overlays) 'face attributes))) + (setq hl-paren-overlays (nreverse hl-paren-overlays)))) + +(defun hl-paren-color-update () + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + (when hl-paren-overlays + (mapc 'delete-overlay hl-paren-overlays) + (setq hl-paren-overlays nil) + (hl-paren-create-overlays) + (let ((hl-paren-last-point -1)) ;; force update + (hl-paren-highlight)))))) + +(provide 'highlight-parentheses) + +;;; highlight-parentheses.el ends here diff --git a/emacs/javascript.el b/emacs/javascript.el new file mode 100644 index 0000000..33d852f --- /dev/null +++ b/emacs/javascript.el @@ -0,0 +1,707 @@ +;;; javascript.el --- Major mode for editing JavaScript source text + +;; Copyright (C) 2006 Karl Landström + +;; Author: Karl Landström +;; Maintainer: Karl Landström +;; Version: 2.0 Beta 8 +;; Date: 2006-12-26 +;; Keywords: languages, oop + +;; This file is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; This file is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: +;; +;; The main features of this JavaScript mode are syntactic +;; highlighting (enabled with `font-lock-mode' or +;; `global-font-lock-mode'), automatic indentation and filling of +;; comments. +;; +;; This package has (only) been tested with GNU Emacs 21.4 (the latest +;; stable release). +;; +;; Installation: +;; +;; Put this file in a directory where Emacs can find it (`C-h v +;; load-path' for more info). Then add the following lines to your +;; Emacs initialization file: +;; +;; (add-to-list 'auto-mode-alist '("\\.js\\'" . javascript-mode)) +;; (autoload 'javascript-mode "javascript" nil t) +;; +;; General Remarks: +;; +;; This mode assumes that block comments are not nested inside block +;; comments and that strings do not contain line breaks. +;; +;; Exported names start with "javascript-" whereas private names start +;; with "js-". +;; +;; Changes: +;; +;; See javascript.el.changelog. + +;;; Code: + +(require 'cc-mode) +(require 'font-lock) +(require 'newcomment) + +(defgroup javascript nil + "Customization variables for `javascript-mode'." + :tag "JavaScript" + :group 'languages) + +(defcustom javascript-indent-level 4 + "Number of spaces for each indentation step." + :type 'integer + :group 'javascript) + +(defcustom javascript-auto-indent-flag t + "Automatic indentation with punctuation characters. If non-nil, the +current line is indented when certain punctuations are inserted." + :type 'boolean + :group 'javascript) + + +;; --- Keymap --- + +(defvar javascript-mode-map nil + "Keymap used in JavaScript mode.") + +(unless javascript-mode-map + (setq javascript-mode-map (make-sparse-keymap))) + +(when javascript-auto-indent-flag + (mapc (lambda (key) + (define-key javascript-mode-map key 'javascript-insert-and-indent)) + '("{" "}" "(" ")" ":" ";" ","))) + +(defun javascript-insert-and-indent (key) + "Run command bound to key and indent current line. Runs the command +bound to KEY in the global keymap and indents the current line." + (interactive (list (this-command-keys))) + (call-interactively (lookup-key (current-global-map) key)) + (indent-according-to-mode)) + + +;; --- Syntax Table And Parsing --- + +(defvar javascript-mode-syntax-table + (let ((table (make-syntax-table))) + (c-populate-syntax-table table) + + ;; The syntax class of underscore should really be `symbol' ("_") + ;; but that makes matching of tokens much more complex as e.g. + ;; "\\" matches part of e.g. "_xyz" and "xyz_abc". Defines + ;; it as word constituent for now. + (modify-syntax-entry ?_ "w" table) + + table) + "Syntax table used in JavaScript mode.") + + +(defun js-re-search-forward-inner (regexp &optional bound count) + "Auxiliary function for `js-re-search-forward'." + (let ((parse) + (saved-point (point-min))) + (while (> count 0) + (re-search-forward regexp bound) + (setq parse (parse-partial-sexp saved-point (point))) + (cond ((nth 3 parse) + (re-search-forward + (concat "\\([^\\]\\|^\\)" (string (nth 3 parse))) + (save-excursion (end-of-line) (point)) t)) + ((nth 7 parse) + (forward-line)) + ((or (nth 4 parse) + (and (eq (char-before) ?\/) (eq (char-after) ?\*))) + (re-search-forward "\\*/")) + (t + (setq count (1- count)))) + (setq saved-point (point)))) + (point)) + + +(defun js-re-search-forward (regexp &optional bound noerror count) + "Search forward but ignore strings and comments. Invokes +`re-search-forward' but treats the buffer as if strings and +comments have been removed." + (let ((saved-point (point)) + (search-expr + (cond ((null count) + '(js-re-search-forward-inner regexp bound 1)) + ((< count 0) + '(js-re-search-backward-inner regexp bound (- count))) + ((> count 0) + '(js-re-search-forward-inner regexp bound count))))) + (condition-case err + (eval search-expr) + (search-failed + (goto-char saved-point) + (unless noerror + (error (error-message-string err))))))) + + +(defun js-re-search-backward-inner (regexp &optional bound count) + "Auxiliary function for `js-re-search-backward'." + (let ((parse) + (saved-point (point-min))) + (while (> count 0) + (re-search-backward regexp bound) + (when (and (> (point) (point-min)) + (save-excursion (backward-char) (looking-at "/[/*]"))) + (forward-char)) + (setq parse (parse-partial-sexp saved-point (point))) + (cond ((nth 3 parse) + (re-search-backward + (concat "\\([^\\]\\|^\\)" (string (nth 3 parse))) + (save-excursion (beginning-of-line) (point)) t)) + ((nth 7 parse) + (goto-char (nth 8 parse))) + ((or (nth 4 parse) + (and (eq (char-before) ?/) (eq (char-after) ?*))) + (re-search-backward "/\\*")) + (t + (setq count (1- count)))))) + (point)) + + +(defun js-re-search-backward (regexp &optional bound noerror count) + "Search backward but ignore strings and comments. Invokes +`re-search-backward' but treats the buffer as if strings and +comments have been removed." + (let ((saved-point (point)) + (search-expr + (cond ((null count) + '(js-re-search-backward-inner regexp bound 1)) + ((< count 0) + '(js-re-search-forward-inner regexp bound (- count))) + ((> count 0) + '(js-re-search-backward-inner regexp bound count))))) + (condition-case err + (eval search-expr) + (search-failed + (goto-char saved-point) + (unless noerror + (error (error-message-string err))))))) + + +(defun js-continued-var-decl-list-p () + "Return non-nil if point is inside a continued variable declaration +list." + (interactive) + (let ((start (save-excursion (js-re-search-backward "\\" nil t)))) + (and start + (save-excursion (re-search-backward "\n" start t)) + (not (save-excursion + (js-re-search-backward + ";\\|[^, \t][ \t]*\\(/[/*]\\|$\\)" start t)))))) + + +;; --- Font Lock --- + +(defun js-inside-param-list-p () + "Return non-nil if point is inside a function parameter list." + (condition-case err + (save-excursion + (up-list -1) + (and (looking-at "(") + (progn (backward-word 1) + (or (looking-at "function") + (progn (backward-word 1) (looking-at "function")))))) + (error nil))) + + +(defconst js-function-heading-1-re + "^[ \t]*function[ \t]+\\(\\w+\\)" + "Regular expression matching the start of a function header.") + +(defconst js-function-heading-2-re + "^[ \t]*\\(\\w+\\)[ \t]*:[ \t]*function\\>" + "Regular expression matching the start of a function entry in + an associative array.") + +(defconst js-keyword-re + (regexp-opt '("abstract" "break" "case" "catch" "class" "const" + "continue" "debugger" "default" "delete" "do" "else" + "enum" "export" "extends" "final" "finally" "for" + "function" "goto" "if" "implements" "import" "in" + "instanceof" "interface" "native" "new" "package" + "private" "protected" "public" "return" "static" + "super" "switch" "synchronized" "this" "throw" + "throws" "transient" "try" "typeof" "var" "void" + "volatile" "while" "with" + "let") 'words) + "Regular expression matching any JavaScript keyword.") + +(defconst js-basic-type-re + (regexp-opt '("boolean" "byte" "char" "double" "float" "int" "long" + "short" "void") 'words) + "Regular expression matching any predefined type in JavaScript.") + +(defconst js-constant-re + (regexp-opt '("false" "null" "true") 'words) + "Regular expression matching any future reserved words in JavaScript.") + + +(defconst js-font-lock-keywords-1 + (list + "\\" + (list js-function-heading-1-re 1 font-lock-function-name-face) + (list js-function-heading-2-re 1 font-lock-function-name-face) + (list "[=(][ \t]*\\(/.*?[^\\]/\\w*\\)" 1 font-lock-string-face)) + "Level one font lock.") + +(defconst js-font-lock-keywords-2 + (append js-font-lock-keywords-1 + (list (list js-keyword-re 1 font-lock-keyword-face) + (cons js-basic-type-re font-lock-type-face) + (cons js-constant-re font-lock-constant-face))) + "Level two font lock.") + + +;; Limitations with variable declarations: There seems to be no +;; sensible way to highlight variables occuring after an initialized +;; variable in a variable list. For instance, in +;; +;; var x, y = f(a, b), z +;; +;; z will not be highlighted. + +(defconst js-font-lock-keywords-3 + (append + js-font-lock-keywords-2 + (list + + ;; variable declarations + (list + (concat "\\<\\(const\\|var\\)\\>\\|" js-basic-type-re) + (list "\\(\\w+\\)[ \t]*\\([=;].*\\|,\\|/[/*]\\|$\\)" + nil + nil + '(1 font-lock-variable-name-face))) + + ;; continued variable declaration list + (list + (concat "^[ \t]*\\w+[ \t]*\\([,;=]\\|/[/*]\\|$\\)") + (list "\\(\\w+\\)[ \t]*\\([=;].*\\|,\\|/[/*]\\|$\\)" + '(if (save-excursion (backward-char) (js-continued-var-decl-list-p)) + (backward-word 1) + (end-of-line)) + '(end-of-line) + '(1 font-lock-variable-name-face))) + + ;; formal parameters + (list + (concat "\\\\([ \t]+\\w+\\)?[ \t]*([ \t]*\\w") + (list "\\(\\w+\\)\\([ \t]*).*\\)?" + '(backward-char) + '(end-of-line) + '(1 font-lock-variable-name-face))) + + ;; continued formal parameter list + (list + (concat "^[ \t]*\\w+[ \t]*[,)]") + (list "\\w+" + '(if (save-excursion (backward-char) (js-inside-param-list-p)) + (backward-word 1) + (end-of-line)) + '(end-of-line) + '(0 font-lock-variable-name-face))))) + "Level three font lock.") + +(defconst js-font-lock-keywords + '(js-font-lock-keywords-3 js-font-lock-keywords-1 js-font-lock-keywords-2 + js-font-lock-keywords-3) + "See `font-lock-keywords'.") + + +;; --- Indentation --- + +(defconst js-possibly-braceless-keyword-re + (regexp-opt + '("catch" "do" "else" "finally" "for" "if" "try" "while" "with" "let") + 'words) + "Regular expression matching keywords that are optionally + followed by an opening brace.") + +(defconst js-indent-operator-re + (concat "[-+*/%<>=&^|?:.]\\([^-+*/]\\|$\\)\\|" + (regexp-opt '("in" "instanceof") 'words)) + "Regular expression matching operators that affect indentation + of continued expressions.") + + +(defun js-looking-at-operator-p () + "Return non-nil if text after point is an operator (that is not +a comma)." + (save-match-data + (and (looking-at js-indent-operator-re) + (or (not (looking-at ":")) + (save-excursion + (and (js-re-search-backward "[?:{]\\|\\" nil t) + (looking-at "?"))))))) + + +(defun js-continued-expression-p () + "Returns non-nil if the current line continues an expression." + (save-excursion + (back-to-indentation) + (or (js-looking-at-operator-p) + (and (js-re-search-backward "\n" nil t) + (progn + (skip-chars-backward " \t") + (backward-char) + (and (> (point) (point-min)) + (save-excursion (backward-char) (not (looking-at "[/*]/"))) + (js-looking-at-operator-p) + (and (progn (backward-char) + (not (looking-at "++\\|--\\|/[/*]")))))))))) + + +(defun js-end-of-do-while-loop-p () + "Returns non-nil if word after point is `while' of a do-while +statement, else returns nil. A braceless do-while statement +spanning several lines requires that the start of the loop is +indented to the same column as the current line." + (interactive) + (save-excursion + (save-match-data + (when (looking-at "\\s-*\\") + (if (save-excursion + (skip-chars-backward "[ \t\n]*}") + (looking-at "[ \t\n]*}")) + (save-excursion + (backward-list) (backward-word 1) (looking-at "\\")) + (js-re-search-backward "\\" (point-at-bol) t) + (or (looking-at "\\") + (let ((saved-indent (current-indentation))) + (while (and (js-re-search-backward "^[ \t]*\\<" nil t) + (/= (current-indentation) saved-indent))) + (and (looking-at "[ \t]*\\") + (not (js-re-search-forward + "\\" (point-at-eol) t)) + (= (current-indentation) saved-indent))))))))) + + +(defun js-ctrl-statement-indentation () + "Returns the proper indentation of the current line if it +starts the body of a control statement without braces, else +returns nil." + (save-excursion + (back-to-indentation) + (when (save-excursion + (and (not (looking-at "[{]")) + (progn + (js-re-search-backward "[[:graph:]]" nil t) + (forward-char) + (when (= (char-before) ?\)) (backward-list)) + (skip-syntax-backward " ") + (skip-syntax-backward "w") + (looking-at js-possibly-braceless-keyword-re)) + (not (js-end-of-do-while-loop-p)))) + (save-excursion + (goto-char (match-beginning 0)) + (+ (current-indentation) javascript-indent-level))))) + + +(defun js-proper-indentation (parse-status) + "Return the proper indentation for the current line." + (save-excursion + (back-to-indentation) + (let ((ctrl-stmt-indent (js-ctrl-statement-indentation)) + (same-indent-p (looking-at "[]})]\\|\\\\|\\")) + (continued-expr-p (js-continued-expression-p))) + (cond (ctrl-stmt-indent) + ((js-continued-var-decl-list-p) + (js-re-search-backward "\\" nil t) + (+ (current-indentation) javascript-indent-level)) + ((nth 1 parse-status) + (goto-char (nth 1 parse-status)) + (if (looking-at "[({[][ \t]*\\(/[/*]\\|$\\)") + (progn + (skip-syntax-backward " ") + (when (= (char-before) ?\)) (backward-list)) + (back-to-indentation) + (cond (same-indent-p + (current-column)) + (continued-expr-p + (+ (current-column) (* 2 javascript-indent-level))) + (t + (+ (current-column) javascript-indent-level)))) + (unless same-indent-p + (forward-char) + (skip-chars-forward " \t")) + (current-column))) + (continued-expr-p javascript-indent-level) + (t 0))))) + + +(defun javascript-indent-line () + "Indent the current line as JavaScript source text." + (interactive) + (let ((parse-status + (save-excursion (parse-partial-sexp (point-min) (point-at-bol)))) + (offset (- (current-column) (current-indentation)))) + (when (not (nth 8 parse-status)) + (indent-line-to (js-proper-indentation parse-status)) + (when (> offset 0) (forward-char offset))))) + + +;; --- Filling --- + +;; FIXME: It should be possible to use the more sofisticated function +;; `c-fill-paragraph' in `cc-cmds.el' instead. However, just setting +;; `fill-paragraph-function' to `c-fill-paragraph' does not work; +;; inside `c-fill-paragraph', `fill-paragraph-function' evaluates to +;; nil!? + +(defun js-backward-paragraph () + "Move backward to start of paragraph. Postcondition: Point is at +beginning of buffer or the previous line contains only whitespace." + (forward-line -1) + (while (not (or (bobp) (looking-at "^[ \t]*$"))) + (forward-line -1)) + (when (not (bobp)) (forward-line 1))) + + +(defun js-forward-paragraph () + "Move forward to end of paragraph. Postcondition: Point is at +end of buffer or the next line contains only whitespace." + (forward-line 1) + (while (not (or (eobp) (looking-at "^[ \t]*$"))) + (forward-line 1)) + (when (not (eobp)) (backward-char 1))) + + +(defun js-fill-block-comment-paragraph (parse-status justify) + "Fill current paragraph as a block comment. PARSE-STATUS is the +result of `parse-partial-regexp' from beginning of buffer to +point. JUSTIFY has the same meaning as in `fill-paragraph'." + (let ((offset (save-excursion + (goto-char (nth 8 parse-status)) (current-indentation)))) + (save-excursion + (save-restriction + (narrow-to-region (save-excursion + (goto-char (nth 8 parse-status)) (point-at-bol)) + (save-excursion + (goto-char (nth 8 parse-status)) + (re-search-forward "*/"))) + (narrow-to-region (save-excursion + (js-backward-paragraph) + (when (looking-at "^[ \t]*$") (forward-line 1)) + (point)) + (save-excursion + (js-forward-paragraph) + (when (looking-at "^[ \t]*$") (backward-char)) + (point))) + (goto-char (point-min)) + (while (not (eobp)) + (delete-horizontal-space) + (forward-line 1)) + (let ((fill-column (- fill-column offset)) + (fill-paragraph-function nil)) + (fill-paragraph justify)) + + ;; In Emacs 21.4 as opposed to CVS Emacs 22, + ;; `fill-paragraph' seems toadd a newline at the end of the + ;; paragraph. Remove it! + (goto-char (point-max)) + (when (looking-at "^$") (backward-delete-char 1)) + + (goto-char (point-min)) + (while (not (eobp)) + (indent-to offset) + (forward-line 1)))))) + + +(defun js-sline-comment-par-start () + "Return point at the beginning of the line where the current +single-line comment paragraph starts." + (save-excursion + (beginning-of-line) + (while (and (not (bobp)) + (looking-at "^[ \t]*//[ \t]*[[:graph:]]")) + (forward-line -1)) + (unless (bobp) (forward-line 1)) + (point))) + + +(defun js-sline-comment-par-end () + "Return point at end of current single-line comment paragraph." + (save-excursion + (beginning-of-line) + (while (and (not (eobp)) + (looking-at "^[ \t]*//[ \t]*[[:graph:]]")) + (forward-line 1)) + (unless (bobp) (backward-char)) + (point))) + + +(defun js-sline-comment-offset (line) + "Return the column at the start of the current single-line +comment paragraph." + (save-excursion + (goto-line line) + (re-search-forward "//" (point-at-eol)) + (goto-char (match-beginning 0)) + (current-column))) + + +(defun js-sline-comment-text-offset (line) + "Return the column at the start of the text of the current +single-line comment paragraph." + (save-excursion + (goto-line line) + (re-search-forward "//[ \t]*" (point-at-eol)) + (current-column))) + + +(defun js-at-empty-sline-comment-p () + "Return non-nil if inside an empty single-line comment." + (and (save-excursion + (beginning-of-line) + (not (looking-at "^.*//.*[[:graph:]]"))) + (save-excursion + (re-search-backward "//" (point-at-bol) t)))) + + +(defun js-fill-sline-comments (parse-status justify) + "Fill current paragraph as a sequence of single-line comments. +PARSE-STATUS is the result of `parse-partial-regexp' from +beginning of buffer to point. JUSTIFY has the same meaning as in +`fill-paragraph'." + (when (not (js-at-empty-sline-comment-p)) + (let* ((start (js-sline-comment-par-start)) + (start-line (1+ (count-lines (point-min) start))) + (end (js-sline-comment-par-end)) + (offset (js-sline-comment-offset start-line)) + (text-offset (js-sline-comment-text-offset start-line))) + (save-excursion + (save-restriction + (narrow-to-region start end) + (goto-char (point-min)) + (while (re-search-forward "^[ \t]*//[ \t]*" nil t) + (replace-match "") + (forward-line 1)) + (let ((fill-paragraph-function nil) + (fill-column (- fill-column text-offset))) + (fill-paragraph justify)) + + ;; In Emacs 21.4 as opposed to CVS Emacs 22, + ;; `fill-paragraph' seems toadd a newline at the end of the + ;; paragraph. Remove it! + (goto-char (point-max)) + (when (looking-at "^$") (backward-delete-char 1)) + + (goto-char (point-min)) + (while (not (eobp)) + (indent-to offset) + (insert "//") + (indent-to text-offset) + (forward-line 1))))))) + + +(defun js-trailing-comment-p (parse-status) + "Return non-nil if inside a trailing comment. PARSE-STATUS is +the result of `parse-partial-regexp' from beginning of buffer to +point." + (save-excursion + (when (nth 4 parse-status) + (goto-char (nth 8 parse-status)) + (skip-chars-backward " \t") + (not (bolp))))) + + +(defun js-block-comment-p (parse-status) + "Return non-nil if inside a block comment. PARSE-STATUS is the +result of `parse-partial-regexp' from beginning of buffer to +point." + (save-excursion + (save-match-data + (when (nth 4 parse-status) + (goto-char (nth 8 parse-status)) + (looking-at "/\\*"))))) + + +(defun javascript-fill-paragraph (&optional justify) + "If inside a comment, fill the current comment paragraph. +Trailing comments are ignored." + (interactive) + (let ((parse-status (parse-partial-sexp (point-min) (point)))) + (when (and (nth 4 parse-status) + (not (js-trailing-comment-p parse-status))) + (if (js-block-comment-p parse-status) + (js-fill-block-comment-paragraph parse-status justify) + (js-fill-sline-comments parse-status justify)))) + t) + + +;; --- Imenu --- + +(defconst js-imenu-generic-expression + (list + (list + nil + "function\\s-+\\(\\w+\\)\\s-*(" + 1)) + "Regular expression matching top level procedures. Used by imenu.") + + +;; --- Main Function --- + +;;;###autoload +(defun javascript-mode () + "Major mode for editing JavaScript source text. + +Key bindings: + +\\{javascript-mode-map}" + (interactive) + (kill-all-local-variables) + + (use-local-map javascript-mode-map) + (set-syntax-table javascript-mode-syntax-table) + (set (make-local-variable 'indent-line-function) 'javascript-indent-line) + (set (make-local-variable 'font-lock-defaults) (list js-font-lock-keywords)) + + (set (make-local-variable 'parse-sexp-ignore-comments) t) + + ;; Comments + (setq comment-start "// ") + (setq comment-end "") + (set (make-local-variable 'fill-paragraph-function) + 'javascript-fill-paragraph) + + ;; Make c-mark-function work + (setq c-nonsymbol-token-regexp "!=\\|%=\\|&[&=]\\|\\*[/=]\\|\\+[+=]\\|-[=-]\\|/[*/=]\\|<\\(?:<=\\|[<=]\\)\\|==\\|>\\(?:>\\(?:>=\\|[=>]\\)\\|[=>]\\)\\|\\^=\\||[=|]\\|[]!%&(-,./:-?[{-~^-]" + c-stmt-delim-chars "^;{}?:" + c-syntactic-ws-end "[ \n \f/]" + c-syntactic-eol "\\(\\s \\|/\\*\\([^*\n ]\\|\\*[^/\n ]\\)*\\*/\\)*\\(\\(/\\*\\([^*\n ]\\|\\*[^/\n ]\\)*\\|\\\\\\)?$\\|//\\)") + + ;; Imenu + (setq imenu-case-fold-search nil) + (set (make-local-variable 'imenu-generic-expression) + js-imenu-generic-expression) + + (setq major-mode 'javascript-mode) + (setq mode-name "JavaScript") + (run-hooks 'javascript-mode-hook)) + + +(provide 'javascript-mode) +;;; javascript.el ends here diff --git a/emacs/lacarte.el b/emacs/lacarte.el new file mode 100644 index 0000000..98e543e --- /dev/null +++ b/emacs/lacarte.el @@ -0,0 +1,605 @@ +;;; lacarte.el --- Execute menu items as commands, with completion. +;; +;; Filename: lacarte.el +;; Description: Execute menu items as commands, with completion. +;; Author: Drew Adams +;; Maintainer: Drew Adams +;; Copyright (C) 2005-2010, Drew Adams, all rights reserved. +;; Created: Fri Aug 12 17:18:02 2005 +;; Version: 22.0 +;; Last-Updated: Fri Jun 25 21:05:15 2010 (-0700) +;; By: dradams +;; Update #: 632 +;; URL: http://www.emacswiki.org/cgi-bin/wiki/lacarte.el +;; Keywords: menu-bar, menu, command, help, abbrev, minibuffer, keys, +;; completion, matching, local, internal, extensions, +;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x +;; +;; Features that might be required by this library: +;; +;; None +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; Q. When is a menu not a menu? A. When it's a la carte. +;; +;; Library La Carte lets you execute menu items as commands, with +;; completion. You can use it as an alternative to standard library +;; `tmm.el'. +;; +;; Type a menu item. Completion is available. Completion candidates +;; are of the form menu > submenu > subsubmenu > ... > menu item. +;; For example: +;; +;; File > Open Recent > Cleanup list +;; File > Open Recent > Edit list... +;; +;; When you choose a menu-item candidate, the corresponding command +;; is executed. +;; +;; Put this in your init file (~/.emacs): +;; +;; (require 'lacarte) +;; +;; Suggested key bindings: +;; +;; (global-set-key [?\e ?\M-x] 'lacarte-execute-command) +;; (global-set-key [?\M-`] 'lacarte-execute-menu-command) +;; (global-set-key [f10] 'lacarte-execute-menu-command) +;; +;; (The latter two replace standard bindings for `tmm-menubar'. On +;; MS Windows, `f10' is normally bound to `menu-bar-open', which uses +;; the Windows native keyboard access to menus.) +;; +;; To really take advantage of La Carte, use it together with +;; Icicles. Icicles is not required to be able to use La Carte, but +;; it enhances the functionality of `lacarte.el' considerably. +;; (Note: `lacarte.el' was originally called `icicles-menu.el'.) +;; +;; If you use MS Windows keyboard accelerators, consider using +;; `lacarte-remove-w32-keybd-accelerators' as the value of +;; `lacarte-convert-menu-item-function'. It removes any unescaped +;; `&' characters (indicating an accelerator) from the menu items. +;; One library that adds keyboard accelerators to your menu items is +;; `menuacc.el', by Lennart Borgman (< l e n n a r t . b o r g m a n +;; @ g m a i l . c o m >). +;; +;; +;; Commands defined here: +;; +;; `lacarte-execute-command', `lacarte-execute-menu-command'. +;; +;; Options defined here: `lacarte-convert-menu-item-function'. +;; +;; Non-interactive functions defined here: +;; +;; `lacarte-escape-w32-accel', `lacarte-get-a-menu-item-alist', +;; `lacarte-get-a-menu-item-alist-1', +;; `lacarte-get-overall-menu-item-alist', `lacarte-menu-first-p', +;; `lacarte-remove-w32-keybd-accelerators'. +;; +;; Internal variables defined here: +;; +;; `lacarte-history', `lacarte-menu-items-alist'. +;; +;; +;; Getting Started +;; --------------- +;; +;; In your init file (`~/.emacs'), bind `ESC M-x' as suggested above: +;; +;; (global-set-key [?\e ?\M-x] 'lacarte-execute-command) +;; +;; Type `ESC M-x' (or `ESC ESC x', which is the same thing). You are +;; prompted for a command or menu command to execute. Just start +;; typing its name. Each menu item's full name, for completion, has +;; its parent menu names as prefixes. +;; +;; ESC M-x +;; Command: +;; Command: t [TAB] +;; Command: Tools > +;; Command: Tools > Compa [TAB] +;; Command: Tools > Compare (Ediff) > Two F [TAB] +;; Command: Tools > Compare (Ediff) > Two Files... [RET] +;; +;; +;; Not Just for Wimps and Noobs Anymore +;; ------------------------------------ +;; +;; *You* don't use menus. Nah, they're too slow! Only newbies and +;; wimps use menus. Well not any more. Use the keyboard to access +;; any menu item, without knowing where it is or what its full name +;; is. Type just part of its name and use completion to get the +;; rest: the complete path and item name. +;; +;; +;; Commands and Menu Commands +;; -------------------------- +;; +;; You can bind either `lacarte-execute-menu-command' or +;; `lacarte-execute-command' to a key such as `ESC M-x'. +;; +;; `lacarte-execute-menu-command' uses only menu commands. +;; `lacarte-execute-command' lets you choose among ordinary Emacs +;; commands, in addition to menu commands. You can use a prefix arg +;; with `lacarte-execute-command' to get the same effect as +;; `lacarte-execute-menu-command'. +;; +;; Use `lacarte-execute-command' if you don't care whether a command +;; is on a menu. Then, if you want a command that affects a buffer, +;; just type `buf'. This is especially useful if you use Icicles - +;; see below. +;; +;; By default, in Icicle mode, `ESC M-x' is bound to +;; `lacarte-execute-command', and `M-`' is bound to +;; `lacarte-execute-menu-command'. +;; +;; +;; Icicles Enhances Dining A La Carte +;; ---------------------------------- +;; +;; Use Icicles with La Carte to get more power and convenience. +;; +;; It is Icicles that lets you choose menu items a la carte, in fact. +;; That is, you can access them directly, wherever they might be in +;; the menu hierachy. Without Icicles, you are limited to choosing +;; items by their menu-hierarchy prefixes, and you must complete the +;; entire menu prefix to the item, from the top of the menu on down. +;; With Icicles, you can directly match any parts of a menu item and +;; its hierarchy path. Icicles is here: +;; http://www.emacswiki.org/cgi-bin/wiki/Icicles. +;; +;; Type any part of a menu-item, then use the Page Up and Page Down +;; keys (`prior' and `next') to cycle through all menu commands that +;; contain the text you typed somewhere in their name. You can match +;; within any menu or within all menus; that is, you can match any +;; part(s) of the menu-hierachy prefix. +;; +;; You can use `S-TAB' to show and choose from all such "apropos +;; completions", just as you normally use `TAB' to show all prefix +;; completions (that is, ordinary completions). Vanilla, prefix +;; completion is still available using `TAB', and you can cycle +;; through the prefix completions using the arrow keys. +;; +;; You can use Icicles "progressive completion" to match multiple +;; parts of a menu item separately, in any order. For example, if +;; you want a menu command that has to do with buffers and +;; highlighting, type `buf M-SPC hig S-TAB'. +;; +;; Icicles apropos completion also lets you type a regular expression +;; (regexp) - it is matched against all of the possible menu items. +;; So, for instance, you could type `^e.+buff [next] [next]...' to +;; quickly cycle to menu command `Edit > Go To > Goto End of Buffer'. +;; Or type `.*print.*buf S-TAB' to choose from the list of all menu +;; commands that match `print' followed somewhere by `buf'. +;; +;; If you know how to use regexps, you can easily and quickly get to +;; a menu command you want, or at least narrow the list of candidates +;; for completion and cycling. +;; +;; Additional benefits of using Icicles with La Carte: +;; +;; * When you cycle to a candidate menu item, or you complete to one +;; (entirely), the Emacs command associated with the menu item is +;; shown in the mode line of buffer `*Completions*'. +;; +;; * You can use `M-h' to complete your minibuffer input against +;; commands, including menu-item commands, that you have entered +;; previously. You can also use the standard history keys +;; (e.g. `M-p', `M-r') to access these commands. +;; +;; +;; Menu Organization Helps You Find a Command +;; ------------------------------------------ +;; +;; Unlike commands listed in a flat `*Apropos*' page, menu items are +;; organized, grouped logically by common area of application +;; (`File', `Edit',...). This grouping is also available when +;; cycling completion candidates using Icicles, and you can take +;; advantage of it to hasten your search for the right command. +;; +;; You want to execute a command that puts the cursor at the end of a +;; buffer, but you don't remember its name, what menu it might be a +;; part of, or where it might appear in that (possibly complex) menu. +;; With Icicles and La Carte, you type `ESC M-x' and then type +;; `buffer' at the prompt. You use the Page Up and Page Down keys to +;; cycle through all menu items that contain the word `buffer'. +;; +;; There are lots of such menu items. But all items from the same +;; menu (e.g. `File') are grouped together. You cycle quickly (not +;; reading) to the `Edit' menu, because you guess that moving the +;; cursor has more to do with editing than with file operations, tool +;; use, buffer choice, help, etc. Then you cycle more slowly among +;; the `buffer' menu items in the `Edit' menu. You quickly find +;; `Edit > Go To > Goto End of Buffer'. QED. +;; +;; +;; Learn About Menu Items By Exploring Them +;; ---------------------------------------- +;; +;; With Icicles, you can display the complete documentation (doc +;; string) for the command corresponding to each menu item, as the +;; item appears in the minibuffer. To do this, just cycle menu-item +;; candidates using `C-down' or `C-next', instead of `[down]' or +;; `[next]'. The documentation appears in buffer `*Help*'. +;; +;; In sum, if you use La Carte, you will want to use it with Icicles +;; - enjoy! +;; +;; +;; To Do? +;; ------ +;; +;; 1. Provide sorting by menu-bar order, instead of alphabetically. +;; 2. Echo key bindings for each completed menu item. +;; +;; 3. Maybe use tmm-get-bind? + +;;(@> "Index") +;; +;; If you have library `linkd.el' and Emacs 22 or later, load +;; `linkd.el' and turn on `linkd-mode' now. It lets you easily +;; navigate around the sections of this doc. Linkd mode will +;; highlight this Index, as well as the cross-references and section +;; headings throughout this file. You can get `linkd.el' here: +;; http://dto.freeshell.org/notebook/Linkd.html. +;; +;; (@> "Change log") +;; (@> "User Options") +;; (@> "Internal Variables") +;; (@> "Functions") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;;(@* "Change log") +;; +;; 2010/06/26 dadams +;; lacarte-execute-command: Protected Icicles vars with boundp. Thx to Alexey Romanov. +;; 2010/05/11 dadams +;; lacarte-get-a-menu-item-alist-1: Add keyboard shortcuts to item names. +;; Applied Icicles renamings (belatedly): +;; icicle-sort-functions-alist to icicle-sort-orders-alist, +;; icicle-sort-function to icicle-sort-comparer. +;; 2009/12/25 dadams +;; Added: lacarte-execute-command, lacarte-menu-first-p. +;; lacarte-get-a-menu-item-alist-1: Handle :filter (e.g. File > Open Recent submenus). +;; lacarte-execute-menu-command: +;; Just let-bind lacarte-menu-items-alist - don't use unwind-protect. +;; lacarte-get-overall-menu-item-alist: Reset lacarte-menu-items-alist to nil. +;; lacarte-get-a-menu-item-alist: Set to the return value. +;; 2009/07/29 dadams +;; Added: lacarte-history. +;; lacarte-execute-menu-command: +;; Use lacarte-history as the history list. Use strict completion. +;; 2009/07/26 dadams +;; lacarte-execute-menu-command: Use icicle-interactive-history as the history list. +;; 2008/08/28 dadams +;; Renamed from alacarte to lacarte. Confusion with alacarte Ubuntu source package. +;; 2008/05/21 dadams +;; Renamed library icicles-menu.el to alacarte.el. +;; alacarte-execute-menu-command: Case-insensitive completion, by default. +;; 2008/05/20 dadams +;; icicle-get-a-menu-item-alist-1: Don't add non-selectable item to alist. +;; 2006/12/22 dadams +;; icicle-convert-menu-item-function: Use choice as :type, allowing nil. +;; :group 'icicles -> :group 'Icicles. +;; 2006/10/16 dadams +;; icicle-get-overall-menu-item-alist: Include minor-mode keymaps. +;; 2006/03/16 dadams +;; Added to Commentary. +;; 2006/02/18 dadams +;; icicle-execute-menu-command: \s -> \\s. (Thx to dslcustomer-211-74.vivodi.gr.) +;; 2006/01/07 dadams +;; Added :link for sending bug reports. +;; 2006/01/06 dadams +;; Changed defgroup to icicles-menu from icicles. +;; Added :link. +;; 2005/11/08 dadams +;; icicle-execute-menu-command: +;; Reset icicle-menu-items-alist in unwind-protect. +;; Fix for dynamic menus Select and Paste, Buffers, and Frames: +;; Treat special cases of last-command-event. +;; icicle-get-overall-menu-item-alist: setq result of sort. +;; 2005/11/05 dadams +;; Replaced icicle-menu-items with icicle-menu-items-alist (no need for both). +;; icicle-execute-menu-command: Set, don't bind icicle-menu-items-alist. +;; 2005/08/23 dadams +;; icicle-execute-menu-command: renamed alist to icicle-menu-items-alist, so can +;; refer to it unambiguously in icicle-help-on-candidate (in icicles.el). +;; 2005/08/19 dadams +;; Added: icicle-convert-menu-item-function, icicle-remove-w32-keybd-accelerators, +;; icicle-escape-w32-accel. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(unless (fboundp 'replace-regexp-in-string) (require 'subr-21 nil t)) + +;;;;;;;;;;;;;;;;;;;;;;;;; + +;;(@* "User Options") + +;;; User Options ------------------------------------------- + +(defgroup lacarte nil + "Execute menu items as commands, with completion." + :prefix "lacarte-" :group 'menu + :link `(url-link :tag "Send Bug Report" + ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject= +lacarte.el bug: \ +&body=Describe bug here, starting with `emacs -q'. \ +Don't forget to mention your Emacs and library versions.")) + :link '(url-link :tag "Other Libraries by Drew" + "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries") + :link '(url-link :tag "Download" "http://www.emacswiki.org/cgi-bin/wiki/lacarte.el") + :link '(url-link :tag "Description" "http://www.emacswiki.org/cgi-bin/wiki/LaCarte") + :link '(emacs-commentary-link :tag "Commentary" "lacarte.el") + ) + +(defcustom lacarte-convert-menu-item-function nil + "*Function to call to convert a menu item. +Used by `lacarte-execute-menu-command'. A typical use would be to +remove the `&' characters used in MS Windows menus to define keyboard +accelerators. See `lacarte-remove-w32-keybd-accelerators'." + :type '(choice (const :tag "None" nil) function) :group 'lacarte) + +;; $$$ NOT YET IMPLEMENTED +;; (defcustom lacarte-sort-menu-bar-order-flag nil +;; "*Non-nil means that `lacarte-execute-menu-command' uses menu-bar order. +;; Nil means use alphabetic order. +;; The order is what is used for completion. +;; Note: Using a non-nil value imposes an extra sorting operation, which +;; slows down the creation of the completion-candidates list." +;; :type 'boolean :group 'lacarte) + +;;; Internal Variables ------------------------------------- + +(defvar lacarte-history nil "History for menu items read using La Carte completion.") + +;; This is used also in `icicle-help-on-candidate', which is defined in Icicles +;; (library `icicles-mcmd.el'). +(defvar lacarte-menu-items-alist nil + "Alist of pairs (MENU-ITEM . COMMAND). +The pairs are defined by the current local and global keymaps. +MENU-ITEM is a menu item, with ancestor-menu prefixes. + Example: `(\"Files > Insert File...\" . insert-file)'. +COMMAND is the command bound to the menu item.") + +;;; Functions ------------------------------- + +(defun lacarte-execute-command (&optional no-commands-p) + "Execute a menu-bar menu command or an ordinary command. +Type a menu item or a command name. Completion is available. +With a prefix arg, only menu items are available. +Completion is not case-sensitive. However, if you use Icicles, then +you can use `C-A' in the minibuffer to toggle case-sensitivity. + +If you use Icicles, then you can also sort the completion candidates +in different ways, using `C-,'. With Icicles, by default menu items +are sorted before non-menu commands, and menu items are highlighted +using face `icicle-special-candidate'." + (interactive "P") + (let ((lacarte-menu-items-alist (lacarte-get-overall-menu-item-alist)) + (completion-ignore-case t) ; Not case-sensitive, by default. + (icicle-special-candidate-regexp (and (not no-commands-p) ".* > \\(.\\|\n\\)*")) + (icicle-sort-orders-alist (and (boundp 'icicle-sort-orders-alist) + (if no-commands-p + icicle-sort-orders-alist + (cons '("menu items first" + . lacarte-menu-first-p) + icicle-sort-orders-alist)))) + (icicle-sort-comparer (and (boundp 'icicle-sort-comparer) + (if no-commands-p + icicle-sort-comparer + 'lacarte-menu-first-p))) + choice cmd) + (unless no-commands-p + (mapatoms (lambda (symb) + (when (commandp symb) + (push (cons (symbol-name symb) symb) lacarte-menu-items-alist))))) + (setq choice (completing-read (if no-commands-p "Menu command: " "Command: ") + lacarte-menu-items-alist nil t nil 'lacarte-history) + cmd (cdr (assoc choice lacarte-menu-items-alist))) + (unless cmd (error "No such menu command")) + ;; Treat special cases of `last-command-event', reconstructing it for + ;; menu items that get their meaning from the click itself. + (cond ((eq cmd 'menu-bar-select-buffer) + (string-match " >\\s-+\\(.+\\)\\s-+\\*?%?\\s-+\\S-*\\s-*$" choice) + (setq choice (substring choice (match-beginning 1) (match-end 1))) + (when (string-match " \\*?%?" choice) + (setq choice (substring choice 0 (match-beginning 0)))) + (setq last-command-event choice)) + ((eq cmd 'menu-bar-select-yank) + (string-match "Edit > Select and Paste > \\(.*\\)$" choice) + (setq last-command-event + (substring choice (match-beginning 1) (match-end 1)))) + ((eq cmd 'menu-bar-select-frame) + (string-match " >\\s-[^>]+>\\s-+\\(.+\\)$" choice) + (setq choice (substring choice (match-beginning 1) (match-end 1))) + (setq last-command-event choice))) + (call-interactively cmd))) + +(defun lacarte-menu-first-p (s1 s2) + "Return non-nil if S1 is a menu item and S2 is not." + (save-match-data + (and (string-match " > " s1) (not (string-match " > " s2))))) + +(defun lacarte-execute-menu-command () + "Execute a menu-bar menu command. +Type a menu item. Completion is available. +Completion is not case-sensitive. However, if you use Icicles, then +you can use `C-A' in the minibuffer to toggle case-sensitivity. +If you use Icicles, then you can also sort the completion candidates +in different ways, using `C-,'." + (interactive) + (let* ((lacarte-menu-items-alist (lacarte-get-overall-menu-item-alist)) + (completion-ignore-case t) ; Not case-sensitive, by default. + (menu-item (completing-read "Menu command: " + lacarte-menu-items-alist + nil t nil 'lacarte-history)) + (cmd (cdr (assoc menu-item lacarte-menu-items-alist)))) + (unless cmd (error "No such menu command")) + ;; Treat special cases of `last-command-event', reconstructing it for + ;; menu items that get their meaning from the click itself. + (cond ((eq cmd 'menu-bar-select-buffer) + (string-match " >\\s-+\\(.+\\)\\s-+\\*?%?\\s-+\\S-*\\s-*$" + menu-item) + (setq menu-item (substring menu-item (match-beginning 1) (match-end 1))) + (when (string-match " \\*?%?" menu-item) + (setq menu-item (substring menu-item 0 (match-beginning 0)))) + (setq last-command-event menu-item)) + ((eq cmd 'menu-bar-select-yank) + (string-match "Edit > Select and Paste > \\(.*\\)$" menu-item) + (setq last-command-event + (substring menu-item (match-beginning 1) (match-end 1)))) + ((eq cmd 'menu-bar-select-frame) + (string-match " >\\s-[^>]+>\\s-+\\(.+\\)$" menu-item) + (setq menu-item (substring menu-item (match-beginning 1) (match-end 1))) + (setq last-command-event menu-item))) + (call-interactively cmd))) + +(defun lacarte-get-overall-menu-item-alist () + "Alist formed from menu items in current active keymaps. +See `lacarte-get-a-menu-item-alist' for the structure. +As a side effect, this modifies `lacarte-get-a-menu-item-alist' and +then resets it to ()" + (let ((alist + (apply #'nconc + (lacarte-get-a-menu-item-alist (assq 'menu-bar (current-local-map))) + (lacarte-get-a-menu-item-alist (assq 'menu-bar (current-global-map))) + (mapcar (lambda (map) (lacarte-get-a-menu-item-alist (assq 'menu-bar map))) + (current-minor-mode-maps))))) + (setq lacarte-menu-items-alist ()) + (if nil;; `lacarte-sort-menu-bar-order-flag' ; Not yet implemented. + (setq alist (sort alist SOME-PREDICATE)) + alist))) + +(defun lacarte-get-a-menu-item-alist (keymap) + "Alist of pairs (MENU-ITEM . COMMAND) defined by KEYMAP. +KEYMAP is any keymap that has menu items. +MENU-ITEM is a menu item, with ancestor-menu prefixes. + Example: `(\"Files > Insert File...\" . insert-file)'. +COMMAND is the command bound to the menu item. +Returns `lacarte-menu-items-alist' which it modifies." + (setq lacarte-menu-items-alist ()) + (lacarte-get-a-menu-item-alist-1 keymap) + (setq lacarte-menu-items-alist (nreverse lacarte-menu-items-alist))) + +(defun lacarte-get-a-menu-item-alist-1 (keymap &optional root) + "Helper function for `lacarte-get-a-menu-item-alist'. +This calls itself recursively, to process submenus. +Returns `lacarte-menu-items-alist', which it modifies." + (let ((scan keymap)) + (setq root (or root)) ; nil, for top level. + (while (consp scan) + (if (atom (car scan)) + (setq scan (cdr scan)) + (let ((defn (cdr (car scan))) + composite-name) + ;; Get REAL-BINDING for the menu item. + (cond + ;; (menu-item ITEM-STRING): non-selectable item - skip it. + ((and (eq 'menu-item (car-safe defn)) + (null (cdr-safe (cdr-safe defn)))) + (setq defn nil)) ; So `keymapp' test, below, fails. + + ;; (ITEM-STRING): non-selectable item - skip it. + ((and (stringp (car-safe defn)) (null (cdr-safe defn))) + (setq defn nil)) ; So `keymapp' test, below, fails. + + ;; (menu-item ITEM-STRING REAL-BINDING . PROPERTIES), with `:filter' + ((and (eq 'menu-item (car-safe defn)) + (member :filter (cdr (cddr defn)))) + (let ((filt (cadr (member :filter (cdr (cddr defn)))))) + (setq composite-name + (concat root (and root " > ") (eval (cadr defn)) + (let ((keys (car-safe (cdr-safe (cdr-safe (cdr-safe defn)))))) + (and (consp keys) (stringp (cdr keys)) (cdr keys))))) + (setq defn (if (functionp filt) ; Apply the filter to REAL-BINDING. + (funcall filt (car (cddr defn))) + (car (cddr defn)))))) + + ;; (menu-item ITEM-STRING REAL-BINDING . PROPERTIES) + ((eq 'menu-item (car-safe defn)) + (setq composite-name + (concat root (and root " > ") (eval (cadr defn)) + (let ((keys (car-safe (cdr-safe (cdr-safe (cdr-safe defn)))))) + (and (consp keys) (stringp (cdr keys)) (cdr keys))))) + (setq defn (car (cddr defn)))) + + ;; (ITEM-STRING . REAL-BINDING) or + ;; (ITEM-STRING [HELP-STRING] (KEYBD-SHORTCUTS) . REAL-BINDING) + ((stringp (car-safe defn)) + (setq composite-name (concat root (and root " > ") (eval (car defn)))) + (setq defn (cdr defn)) + ;; Skip HELP-STRING + (when (stringp (car-safe defn)) (setq defn (cdr defn))) + ;; Skip (KEYBD-SHORTCUTS): cached key-equivalence data for menu items. + ;; But first add shortcuts to composite name. + (when (and (consp defn) (consp (car defn))) + (when (stringp (cdar defn)) ; Add shortcuts to name. + (setq composite-name (concat composite-name (cdar defn)))) + (setq defn (cdr defn))))) + + ;; If REAL-BINDING is a keymap, then recurse on it. + (when (keymapp defn) + ;; Follow indirections to ultimate symbol naming a command. + (while (and (symbolp defn) (fboundp defn) (keymapp (symbol-function defn))) + (setq defn (symbol-function defn))) + (if (eq 'keymap (car-safe defn)) + (lacarte-get-a-menu-item-alist-1 (cdr defn) composite-name) + (lacarte-get-a-menu-item-alist-1 (symbol-function defn) composite-name))) + + ;; Add menu item + command pair to `lacarte-menu-items-alist' alist. + ;; Don't add it if `composite-name' is nil - that's a non-selectable item. + (when (and root composite-name (not (keymapp defn))) + (setq lacarte-menu-items-alist + (cons + (cons (if (and (functionp lacarte-convert-menu-item-function) + (stringp composite-name)) ; Could be nil + (funcall lacarte-convert-menu-item-function composite-name) + composite-name) + defn) + lacarte-menu-items-alist)))) + (when (consp scan) (setq scan (cdr scan))))) + lacarte-menu-items-alist)) + +(defun lacarte-remove-w32-keybd-accelerators (menu-item) + "Remove `&' characters that define keyboard accelerators in MS Windows. +\"&&\" is an escaped `&' - it is replaced by a single `&'. +This is a candidate value for `lacarte-convert-menu-item-function'." + (replace-regexp-in-string "&&?" 'lacarte-escape-w32-accel menu-item)) + +(defun lacarte-escape-w32-accel (match-string) + "If STRING is \"&&\", then return \"&\". Else return \"\"." + (if (> (length match-string) 1) "&" "")) + +;;;;;;;;;;;;;;;;;;;;;;; + +(provide 'lacarte) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; lacarte.el ends here diff --git a/emacs/ll-debug.el b/emacs/ll-debug.el new file mode 100644 index 0000000..713ec41 --- /dev/null +++ b/emacs/ll-debug.el @@ -0,0 +1,634 @@ +;; -*- Emacs-Lisp -*- + +;;; ll-debug.el --- low level debug tools + +;; Copyright (C) 2002-2005 Claus Brunzema + +;; http://www.cbrunzema.de/software.html#ll-debug + +;; Version: 2.0.0 +;; $Id: ll-debug.el,v 1.22 2004/12/28 22:23:16 chb Exp $ + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or +;; (at your option) any later version. +;; +;; It is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to the +;; Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;; ----------------------------------------------------------------------- + + +;;; Commentary: + +;; ll-debug.el provides commands to support a low level debug style. +;; It features quick insertion of various debug output statements and +;; improved functions for commenting and uncommenting chunks of code. +;; +;; I don't use debuggers very much. I know they can be a big help in +;; some situations and I tried some of them, but I find it almost +;; always more direct/convenient/enlightening to put a quick 'printf' +;; into a critical area to see what is happening than to fire up a big +;; clumsy extra program where it takes me ages just to step through to +;; the interesting point. In order to avoid repeated typing of +;; 'printf("I AM HERE\n");' and similar stuff, I created +;; `ll-debug-insert'. It inserts a statement into your +;; sourcecode that will display a debug message. It generates +;; unique messages on each invocation (the message consists of a big +;; fat DEBUG together with a counter and the current filename). +;; +;; See variable `ll-debug-statement-alist' if you want to know which +;; modes are currently supported by ll-debug. You can add new modes +;; with `ll-debug-register-mode'. +;; +;; When I have found the buggy spot, I like to keep a version of the +;; old code in place, just in case I mess things up. +;; `ll-debug-copy-and-comment-region-or-line' helps here, it makes a +;; copy of the current line (or the current region, if active) and +;; comments out the original version. +;; +;; I always missed a keystroke that toggles the 'comment state' of a +;; line (or region) of sourcecode. I need to turn a line or a block of +;; code on and off quickly. `ll-debug-toggle-comment-region-or-line' +;; does just that. +;; +;; Finally, if you want to spit out the values of a lot of variables +;; you can use `ll-debug-insert' with a C-u prefix arg. It calls +;; mode-specific skeletons that keep asking for variable names (and +;; sometimes format specifiers) in the minibuffer. If you just press +;; return here the skeleton interaction ends and a statement to print +;; the names and the values of the variables is inserted in the +;; buffer. +;; +;; If you want to get rid of the debug messages, use +;; `ll-debug-revert'. It finds and removes the lines with the debug +;; output statements, asking for confirmation before it removes +;; anything. + + +;; Prerequisites: +;; +;; I made the latest version of ll-debug with the following emacs: +;; GNU Emacs 21.3.1 +;; Please let me know if other versions work. + + +;; Installation: +;; +;; Get the newest version of ll-debug.el via +;; +;; http://www.cbrunzema.de/software.html#ll-debug +;; +;; and put it in your load-path. Add the following form to your init +;; file (~/.emacs or ~/.xemacs/init.el): +;; +;; (require 'll-debug) +;; +;; Now you can bind ll-debug commands to keystrokes yourself or just +;; call `ll-debug-install-suggested-keybindings'. It clobbers C-v, +;; which may not be completely emacs-political-correct, but it happens +;; to be the stuff I use daily, it is only a suggestion, blah, if you +;; don't like it, don't use it blah blah, do it your own way blah bla +;; blah and don't flame me.... +;; `ll-debug-install-suggested-keybindings' installs the following +;; keybindings: +;; +;; C-v C-v ll-debug-toggle-comment-region-or-line +;; C-v v ll-debug-uncomment-region-or-line +;; C-v C-y ll-debug-copy-and-comment-region-or-line +;; C-v C-d ll-debug-insert + + +;; Usage example 1: +;; +;; If you use `ll-debug-install-suggested-keybindings', hitting C-v C-d +;; in a c-mode buffer called 'main.c' produces: +;; +;; printf("DEBUG-1-main.c\n"); +;; +;; a second C-v C-d prints +;; +;; printf("DEBUG-2-main.c\n"); +;; +;; and so on. The following conversation uses the variable output (the +;; part in '[' and ']' takes place in the minibuffer): +;; +;; C-u C-v C-d [ foo s bar d baz f ] +;; +;; This gives: +;; +;; printf("DEBUG-3-main.c foo:%s bar:%d baz:%f\n", foo, bar, baz); +;; +;; +;; Usage example 2: +;; +;; In a lisp-mode buffer called 'tree.lisp' this: +;; +;; C-v C-d +;; C-v C-d +;; C-u C-v C-d [ foo bar baz ] +;; +;; produces the following lines: +;; +;; (CL:format t "DEBUG-1-tree.lisp~%") +;; (CL:format t "DEBUG-2-tree.lisp~%") +;; (CL:format t "DEBUG-3-tree.lisp foo:~S bar:~S baz:~S~%" foo bar baz) +;; +;; +;; Usage example 3: +;; +;; The keybindings installed via +;; `ll-debug-install-suggested-keybindings' will call an alternative +;; versions for variable output if one ore more C-u prefix args are +;; given. An alternative version is currently available in (c)perl-mode +;; only. So, in a (c)perl-mode buffer called 'answer.pl' these keys +;; +;; C-u C-u C-v C-d [ @quux %thud $grunt ] +;; +;; produce: +;; +;; print "DEBUG-1-answer.pl ", Data::Dumper->Dump([\@quux, \%thud, $grunt], [qw/*quux *thud grunt/]), "\n"; + + +;; Customisation: +;; +;; You can use a different string for the debug messages by setting the +;; variable `ll-debug-output-prefix'. If you set it e.g. to "# DEBUG-" +;; your debug output won't disturb gnuplot datafiles anymore. +;; +;; If you don't like c++'s streams, you can request the printf style +;; output by putting the following in your init file: +;; +;; (setcdr (assq 'c++-mode ll-debug-statement-alist) +;; (cdr (assq 'c-mode ll-debug-statement-alist))) +;; +;; +;; If you want to have dynamic output not only according to the major +;; mode, you can substitute functions in `ll-debug-statement-alist'. +;; For example, the following snippet uses prefix 'printk' instead of +;; 'printf' if you are editing c-sources in a file on a path +;; containing a 'linux' component: +;; +;; (setf (ll-debug-struct-prefix (cdr (assq 'c-mode +;; ll-debug-statement-alist))) +;; #'(lambda () +;; (if (string-match "linux" (buffer-file-name)) +;; "printk(" +;; "printf("))) +;; +;; +;; +;; Please read the documentation for `ll-debug-insert' and +;; `ll-debug-expand' to see what is possible. +;; +;; +;; If you want to teach ll-debug new modes, see +;; `ll-debug-register-mode' and consider sending a patch to +;; . + + +;; History: +;; 2004-12-28 Claus Brunzema +;; * Major rewrite using defstruct. +;; * New ll-debug-insert instead of +;; ll-debug-insert-debug-output and +;; ll-debug-insert-variable-output. +;; * New ll-debug-register-mode. +;; * Version 2.0.0 +;; 2003-05-21 Claus Brunzema +;; * Added java support. +;; * Moved prefix calculation stuff into new +;; ll-debug-insert-debug-output-statement. +;; * Some cleanup. +;; * Version 1.3.0 +;; 2003-05-15 Claus Brunzema +;; * Added ll-debug-install-suggested-keybindings. +;; 2003-03-10 Claus Brunzema +;; * Added package/namespace identifiers to common lisp/c++ code +;; * Version 1.2.6 +;; 2003-03-10 Claus Brunzema +;; * Put in ll-debug-output-prefix instead of the hardcoded +;; default (thanks to Stefan Kamphausen for the idea with +;; gnuplot). +;; * More documentation. +;; * Version 1.2.5 +;; 2003-01-30 Claus Brunzema +;; * added ll-debug-insert-emacs-lisp-variable-output. +;; * ll-debug-insert-perl-variable-output doesn't insert +;; the '$' automatically anymore. That always confused me. +;; * various cleanup and documentation changes. +;; * Version 1.2.3 +;; 2003-01-29 Claus Brunzema +;; * added ll-debug-insert-perl-variable-dumper-output. +;; 2003-01-28 Claus Brunzema +;; * after (un)commenting a single line the point is moved +;; to the next line. +;; 2002-11-20 Claus Brunzema +;; * added ll-debug-insert-scheme-variable-output. +;; * Version 1.2.0 +;; 2002-11-11 Claus Brunzema +;; * added ll-debug-create-next-debug-string (thanks to Scott Frazer). +;; * updated skeletons to use ll-debug-create-next-debug-string. +;; * Version 1.1.0 +;; 2002-11-09 Claus Brunzema +;; * added DEBUG to skeletons. +;; * added ll-debug-revert (thanks to Scott Frazer for the idea). +;; * removed automatic linebreaks from skeletons, so ll-debug-revert +;; doesn't leave half statemets behind. +;; 2002-10-15 Claus Brunzema +;; * fixed ll-debug-region-or-line-comment-start to look +;; for comment-chars starting a line only (thanks to Stefan +;; Kamphausen for the bug report). +;; * Code cleanup. +;; * Version 1.0.0 +;; 2002-09-04 Claus Brunzema +;; * fixed point position after +;; ll-debug-copy-and-comment-region-or-line +;; * Version 0.2.2 +;; 2002-08-17 Claus Brunzema +;; * use (search-forward comment-start ...) instead of +;; (re-search-forward comment-start-skip ...). +;; * use ll-debug-region-or-line-comment-start instead of +;; the optional ignore-current-column argument for +;; ll-debug-region-or-line-start. +;; * ll-debug-copy-and-comment-region-or-line works correctly +;; now if point is in the middle of the line. +;; * Version 0.2.1 +;; 2002-08-11 Claus Brunzema +;; * Variable output support for Common Lisp, perl and c. +;; * Various cleanup. +;; * Version 0.2.0 +;; 2002-08-08 Claus Brunzema +;; * Uncommenting doesn't check the current column anymore +;; (thanks to Stefan Kamphausen). +;; * More blurb. +;; * Version 0.1.1 +;; 2002-08-07 Claus Brunzema +;; * First public version 0.1.0 + + +;; ToDo: +;; * Check if the strange log calculation in ll-debug-insert is really +;; necessary. I want the number of C-u keypresses to dispatch +;; alternatives on the content slot value of a ll-debug-struct, but +;; every C-u multiplies prefix-numeric-value by 4. Is there a better +;; way to do this? +;; * Make preferred output stream customizable. + + +;;; Code: + +(require 'skeleton) +(require 'cl) + +;; Struct------------------------------------------------------------------ +(defstruct ll-debug-struct + "Strings/functions/skeletons to create debug messages for a single mode. +See `ll-debug-statement-alist' and `ll-debug-expand', too." + (prefix "") + (postfix "") + (content '() :type list)) + + +;; Variables -------------------------------------------------------------- +(defvar ll-debug-output-prefix "DEBUG-" + "*Prefix string for debug output messages.") + +(defvar ll-debug-statement-alist () + "Stores mode-specific ll-debug-structs.") + + +;;; gnuemacs / xemacs compatibility --------------------------------------- +(defun ll-debug-region-exists-p () + (if (fboundp 'region-exists-p) + (region-exists-p) ;XEmacs + (and transient-mark-mode mark-active))) ;GNUEmacs + +(defun ll-debug-uncomment-region (beg end) + (if (fboundp 'uncomment-region) + (uncomment-region beg end) ;GNUEmacs + (comment-region beg end -1))) ;XEmacs + + +;;; misc. Functions ------------------------------------------------------- +(defun ll-debug-region-or-line-start () + (save-excursion + (if (ll-debug-region-exists-p) + (progn + (goto-char (region-beginning)) + (point-at-bol)) + (if (= (current-column) (current-indentation)) + (point) + (point-at-bol))))) + +(defun ll-debug-region-or-line-end () + (save-excursion + (if (ll-debug-region-exists-p) + (progn + (goto-char (region-end)) + (unless (bolp) + (forward-line)) + (point)) + (progn + (forward-line) + (point))))) + +(defun ll-debug-install-suggested-keybindings () + "Install suggested keybindings for ll-debug. +This installs the following keybindings (clobbering C-v): + +C-v C-v ll-debug-toggle-comment-region-or-line +C-v v ll-debug-uncomment-region-or-line +C-v C-y ll-debug-copy-and-comment-region-or-line +C-v C-d ll-debug-insert" + (interactive) + (unless (keymapp (global-key-binding '[(control v)])) + (global-unset-key '[(control v)])) + + (define-key global-map '[(control v) (control v)] + #'ll-debug-toggle-comment-region-or-line) + (define-key global-map '[(control v) v] + #'ll-debug-uncomment-region-or-line) + (define-key global-map '[(control v) (control y)] + #'ll-debug-copy-and-comment-region-or-line) + (define-key global-map '[(control v) (control d)] + #'ll-debug-insert)) + + +(defun ll-debug-expand (thing) + "Expands THING into the current buffer. +If THING is a string, it is inserted. +If THING is a list, it is treated as a skeleton (see `skeleton-insert') +If THING is a function, it is funcalled and `ll-debug-expand' is +invoked recursively on the returned value." + (when thing + (etypecase thing + (string + (insert thing)) + (list + (skeleton-insert thing)) + (function + (ll-debug-expand + (funcall thing)))))) + + +;; comment in and out ----------------------------------------------------- +(defun ll-debug-region-or-line-comment-start () + "Find the comment marker at the beginning of the line or region." + (save-excursion + (when (ll-debug-region-exists-p) (goto-char (region-beginning))) + (beginning-of-line) + (skip-chars-forward " \t" (point-at-eol)) + (if (looking-at (regexp-quote comment-start)) + (point) + nil))) + +(defun ll-debug-copy-and-comment-region-or-line () + "Copy the current line/region and comment out the original." + (interactive) + (let* ((start (ll-debug-region-or-line-start)) + (end (ll-debug-region-or-line-end)) + (src-code (buffer-substring start end))) + (goto-char end) + (comment-region start end) + (save-excursion + (insert-string src-code)))) + +(defun ll-debug-comment-region-or-line () + "Comment out the current line or all lines of the region." + (interactive) + (comment-region (ll-debug-region-or-line-start) + (ll-debug-region-or-line-end)) + (unless (ll-debug-region-exists-p) + (forward-line))) + +(defun ll-debug-uncomment-region-or-line () + "Uncomment the current line or all lines of the region." + (interactive) + (ll-debug-uncomment-region (ll-debug-region-or-line-comment-start) + (ll-debug-region-or-line-end)) + (unless (ll-debug-region-exists-p) + (forward-line))) + +(defun ll-debug-toggle-comment-region-or-line () + "Toggle the current line/region between uncommented and commented state." + (interactive) + (if (ll-debug-region-or-line-comment-start) + (ll-debug-uncomment-region-or-line) + (ll-debug-comment-region-or-line))) + + +;; debug output statements ------------------------------------------------ +(defun ll-debug-before-text-p () + "Return t iff point is at bol or in leading whitespace." + (save-excursion + (skip-chars-backward " \t" (point-at-bol)) + (bolp))) + +(defun ll-debug-after-text-p () + "Return t iff point is at eol or in trailing whitespace." + (save-excursion + (skip-chars-forward " \t" (point-at-eol)) + (eolp))) + +(defun ll-debug-open-fresh-line () + "Make room for a debug output statement." + (cond + ((ll-debug-before-text-p) + (open-line 1)) + ((ll-debug-after-text-p) + (open-line 1) + (forward-line)) + (t + (open-line 2) + (forward-line))) + (indent-according-to-mode)) + +(defun ll-debug-register-mode (modes prefix postfix skel1 &rest skels) + "Register mode info in `ll-debug-statement-alist'. +MODES can be a single symbol denoting a mode or a list of mode +symbols. If it is a list, the following info is registered in every +listed mode. PREFIX is the prefix thing for debug statements, POSTFIX +is the postfix thing. SKEL1 and all following SKELS are the content +things. For more information about these, see the documentation of +`ll-debug-insert'. If an entry for a given mode already exists in +`ll-debug-statement-alist', it will be overwritten." + (unless (listp modes) + (setq modes (list modes))) + (push skel1 skels) + (dolist (mode modes) + (setq ll-debug-statement-alist + (cons (cons mode (make-ll-debug-struct :prefix prefix + :postfix postfix + :content skels)) + (assq-delete-all mode ll-debug-statement-alist))))) + +(defun ll-debug-create-next-debug-string () + "Create the next unique debug string." + (let ((max-used 0)) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward + (concat (regexp-quote ll-debug-output-prefix) + "\\([0-9]+\\)-") + nil t) + (setq max-used (max max-used + (string-to-number (match-string 1)))))) + (format "%s%d-%s" + ll-debug-output-prefix + (+ 1 max-used) + (if (buffer-file-name) + (file-name-nondirectory (buffer-file-name)) + "nofile")))) + +(defun ll-debug-insert (arg) + "Insert a line of debug output at point according to mode. +Looks up the current mode in `ll-debug-statement-alist'. The prefix +thing of the coressponding ll-debug-struct gets inserted by +`ll-debug-insert'. The number of times C-u was pressed (prefix arg) +determines the entry from the content list of the ll-debug-struct that +gets inserted next. Finally the postfix thing from the ll-debug-struct +is inserted into the current buffer. +" + (interactive "P") + (when (listp arg) + (if (null arg) + (setq arg 0) + (setq arg (floor (/ (log (car arg)) + (log 4)))))) + (let ((mode-data (cdr (assoc major-mode ll-debug-statement-alist)))) + (cond + ((null mode-data) + (message "%s not supported by ll-debug-insert yet." major-mode)) + ((>= arg (length (ll-debug-struct-content mode-data))) + (message "Only %d flavours of debug output defined for %s." + (length (ll-debug-struct-content mode-data)) + major-mode)) + (t + (ll-debug-open-fresh-line) + (ll-debug-expand (ll-debug-struct-prefix mode-data)) + (ll-debug-expand (elt (ll-debug-struct-content mode-data) arg)) + (ll-debug-expand (ll-debug-struct-postfix mode-data)) + (indent-according-to-mode) + (forward-line) + (indent-according-to-mode))))) + +(defun ll-debug-revert () + "Deletes (with confirmation) lines containing the regexp 'DEBUG-[0-9]+-'. +Uses `query-replace-regexp' internally." + (interactive) + (save-excursion + (goto-char (point-min)) + (query-replace-regexp (concat "^.*" + (regexp-quote ll-debug-output-prefix) + "[0-9]+-.*\n") + ""))) + + +;; register modes --------------------------------------------------------- +(ll-debug-register-mode 'scheme-mode + "(begin " "(newline))" + '(nil "(display \"" + (ll-debug-create-next-debug-string) "\")") + '(nil "(display \"" + (ll-debug-create-next-debug-string) "\")" + ("Variable name: " + "(display \" " str ":\")(display " str ")"))) + +(ll-debug-register-mode 'lisp-mode + "(CL:format t " ")" + '(nil "\"" (ll-debug-create-next-debug-string) "~%\"") + '(nil "\"" (ll-debug-create-next-debug-string) + ("Variable name: " + " " str ":~S" + '(progn (setq v1 (concat v1 " " str)) nil) + ) + "~%\" " v1)) + + +(ll-debug-register-mode '(emacs-lisp-mode lisp-interaction-mode) + "(message " ")" + '(nil "\"" (ll-debug-create-next-debug-string) "\"") + '(nil "\"" (ll-debug-create-next-debug-string) + ("Variable name: " + " " str ":%S" + '(progn (setq v1 (concat v1 " " str)) nil)) + "\" " v1)) + +(ll-debug-register-mode '(perl-mode cperl-mode) + "print " ";" + '(nil "\"" (ll-debug-create-next-debug-string) "\\n\"") + '(nil "\"" (ll-debug-create-next-debug-string) + ("Variable: " + " \\" str ":" str) + "\\n\"") + '(nil "\"" (ll-debug-create-next-debug-string) + " \", Data::Dumper->Dump([" + ("Variable: " + str + '(progn + (if (string= "$" (substring str 0 1)) + (setq v1 (concat v1 " " + (substring str 1))) + (progn + (backward-word 1) + (backward-char 1) + (insert "\\") + (forward-char 1) + (forward-word 1) + (setq v1 (concat v1 + " *" + (substring str 1))))) + nil) + ", ") + "], [qw/" v1 "/]), \"\\n\"")) + +(ll-debug-register-mode 'c++-mode + "std::cout << " " << std::endl;" + '(nil "\"" (ll-debug-create-next-debug-string) "\"") + '(nil "\"" (ll-debug-create-next-debug-string) "\"" + ("Variable name: " + " << \" " str ":\" << " str))) + +(ll-debug-register-mode 'c-mode + "printf(" ");" + '(nil "\"" (ll-debug-create-next-debug-string) "\\n\"") + '(nil "\"" (ll-debug-create-next-debug-string) + ("Variable name: " + " " str ":%" + '(progn + (if v1 + (setq v1 (concat v1 ", " str)) + (setq v1 str)) + nil) + (read-string "Format: ")) + "\\n\", " v1)) + +(ll-debug-register-mode '(java-mode jde-mode) + "System.out.println(" ");" + '(nil "\"" (ll-debug-create-next-debug-string) "\"") + '(nil "\"" (ll-debug-create-next-debug-string) "\"" + ("Variable name: " + "+\" " str ":\"+" str))) + +(ll-debug-register-mode 'ruby-mode + "puts " "" + '(nil "\"" (ll-debug-create-next-debug-string) "\"")) + +(ll-debug-register-mode 'sh-mode + "echo " "" + '(nil (ll-debug-create-next-debug-string))) + +(ll-debug-register-mode '(octave-mode matlab-mode) + "disp(" ");" + '(nil "'" (ll-debug-create-next-debug-string) "'")) + +(provide 'll-debug) + +;;; ll-debug.el ends here diff --git a/emacs/malyon.el b/emacs/malyon.el new file mode 100644 index 0000000..423f05b --- /dev/null +++ b/emacs/malyon.el @@ -0,0 +1,3211 @@ +; malyon.el --- mode to execute z code files version 3, 5, 8 + +;; Copyright (C) 1999-2009 Peter Ilberg + +;; Maintainer: Peter Ilberg + +;; Credits: +;; The author would like to thank the following people for reporting +;; bugs, testing, suggesting and/or contributing improvements: +;; Bernhard Barde, Jonathan Craven, Alberto Petrofsky, Alan Shutko + +;;; Commentary: + +;; This package provides a basic interpreter for version 3, 5, 8 z code +;; story files as generated by Inform (C) Graham Nelson and Infocom. + +;; If you encounter a bug please send a report to Peter Ilberg at +;; peter.ilberg@gmail.com. Thank you! + +;; To play a story file simple type M-x malyon and enter the path to the +;; story file. If anything goes wrong and you want to manually clean +;; up type M-x malyon-quit. In addition, you can switch back to a game in +;; progress by typing M-x malyon-restore. + +;; A note on the format of saved game states: + +;; As of version 1.0, Malyon supports the quetzal file format for saved +;; games. Support for this format required changes to several internal +;; data structures (stack frames and catch-throw) that are incompatible +;; with the old implementation. Unfortunately, the old file format for +;; saved games cannot be converted into quetzal. + +;; For backwards compatibility, however, Malyon still supports the old +;; file format. And you can continue to play your old game states. + +;; Because of the incompatibility of the two file formats, Malyon now +;; runs, as follows, in either of two modes: quetzal and compatibility. + +;; - in quetzal mode, game states are saved in quetzal format +;; - in compatibility mode, games states are saved in the old format +;; - loading a game state in quetzal format switches to quetzal mode +;; - loading an old game state switches to compatibility mode +;; - quetzal mode is the default setting + +;; In other words, Malyon will only use the old file format if you've +;; restored a game state saved in the old file format. + +;; Enjoy! + +;;; Code: + +;; global variables - moved here to appease the byte-code compiler + +;; story file information + +(defvar malyon-story-file-name nil + "The name of the story file being executed.") + +(defvar malyon-story-file nil + "The story file which is currently being run.") + +(defvar malyon-story-version nil + "The story file version.") + +(defvar malyon-supported-versions '(3 5 8) + "A list of supported story file versions.") + +;; status and transcript buffers + +(defvar malyon-transcript-buffer nil + "The main transcript buffer of the story file execution.") + +(defvar malyon-transcript-buffer-buffered nil + "Is output in the transcript buffer buffered?") + +(defvar malyon-status-buffer nil + "The status bar buffer of the story file execution.") + +(defvar malyon-status-buffer-lines nil + "The number of lines in the status bar buffer.") + +(defvar malyon-status-buffer-delayed-split nil + "If the number of lines in the status buffer is reduced, +the window configuration is not changed immediately. It +is changed after the next turn (read or read_char).") + +(defvar malyon-status-buffer-point nil + "The point location in the status bar buffer.") + +(defvar malyon-max-column 72 + "Maximum column for text display.") + +;; window management + +(defvar malyon-window-configuration nil + "The current window configuration of the malyon interpreter.") + +(defvar malyon-current-window nil + "The currently active window for text output.") + +;; z machine registers + +(defvar malyon-stack nil + "The stack of the z machine.") + +(defvar malyon-stack-pointer nil + "The stack pointer of the z machine.") + +(defvar malyon-frame-pointer nil + "The frame pointer of the z machine.") + +(defvar malyon-instruction-pointer nil + "The instruction pointer of the z machine.") + +;; game file related global variables + +(defvar malyon-score-game nil + "A flag indicating whether this story uses score or time.") + +(defvar malyon-packed-multiplier nil + "The amount by which packed addresses are multiplied to get byte +addresses.") + +(defvar malyon-global-variables nil + "A pointer to the global variable section in the story file.") + +(defvar malyon-abbreviations nil + "A pointer to the abbreviations in the story file.") + +(defvar malyon-alphabet nil + "The z machine's text alphabet.") + +(defvar malyon-whitespace nil + "A string of whitespace characters recognized by the interpreter.") + +;; object tables + +(defvar malyon-object-table nil + "A pointer to the object table in the story file.") + +(defvar malyon-object-table-entry-size nil + "The size of one entry in the object table.") + +(defvar malyon-object-properties nil + "The number of properties per object minus one.") + +(defvar malyon-object-property-offset nil + "The byte offset of the properties table in the object.") + +;; dictionaries + +(defvar malyon-dictionary nil + "A pointer to the dictionary of the story file.") + +(defvar malyon-dictionary-entry-length nil + "The length of a dictionary entry.") + +(defvar malyon-dictionary-num-entries nil + "The number of dictionary entries.") + +(defvar malyon-dictionary-entries nil + "A pointer to the first dictionary entry.") + +(defvar malyon-dictionary-word-length nil + "The length of a dictionary word.") + +;; game state information + +(defvar malyon-game-state-restart nil + "The machine state for implementing restart.") + +(defvar malyon-game-state-undo nil + "The machine state for implementing undo.") + +(defvar malyon-game-state-quetzal t + "Store game state information for quetzal.") + +;; various + +(defvar malyon-current-face nil + "The current face in which to display text.") + +(defvar malyon-last-cursor-position-after-input nil + "The last cursor position after reading input from the keyboard.") + +;; interactive functions + +(defun malyon (file-name) + "Major mode for playing z3/5/8 story files. +This mode allows execution of version 3, 5, 8 z code story files." + (interactive "fStory file name: ") + (if malyon-story-file + (message "You are already playing a game.") + (if (not (string-match ".*\.z[358]$" file-name)) + (message "%s is not a version 3, 5, or 8 story file." file-name) + (condition-case nil + (malyon-load-story-file file-name) + (error + (malyon-fatal-error "loading of story file failed."))) + (setq malyon-story-version (aref malyon-story-file 0)) + (cond ((memq malyon-story-version malyon-supported-versions) + (condition-case nil + (malyon-initialize) + (error + (malyon-fatal-error "initialization of interpreter failed."))) + (malyon-interpreter)) + (t + (message "%s is not a version 3, 5, or 8 story file." file-name) + (malyon-cleanup)))))) + +(defun malyon-restore () + "Restore the save window configuration for the interpreter." + (interactive) + (condition-case nil + (progn + (malyon-restore-window-configuration) + (malyon-adjust-transcript)) + (error + (malyon-fatal-error "restoring window configuration failed.")))) + +(defun malyon-quit () + "Exit the malyon interpreter." + (interactive) + (if malyon-story-file + (progn + (malyon-restore) + (if (malyon-yes-or-no-p-minibuf "Do you really want to quit? ") + (malyon-cleanup))))) + +(defun malyon-mode () + "This mode provides a basic interpreter for version 3, 5, 8 z code +story files as generated by Inform (C) Graham Nelson and Infocom. + +Note that this package is by no means complete and bug free. +If you encounter a bug please send a report to Peter Ilberg at +peter.ilberg@natinst.com. Thank you! + +To play a story file simple type M-x malyon and enter the path to the +story file. If anything goes wrong and you want to manually clean +up type M-x malyon-quit. In addition, you can switch back to a game in +progress by typing M-x malyon-restore. + +The author would like to thank the following people for reporting +bugs, testing, suggesting and/or contributing improvements: + Bernhard Barde, Jonathan Craven, Alberto Petrofsky, Alan Shutko" + (message "Use M-x malyon if you want to play a zcode game.")) + +;; compatibility functions for GNU emacs + +(if (fboundp 'cadr) + (defalias 'malyon-cadr 'cadr) + (defun malyon-cadr (list) + "Take the cadr of the list." + (car (cdr list)))) + +(if (fboundp 'caddr) + (defalias 'malyon-caddr 'caddr) + (defun malyon-caddr (list) + "Take the caddr of the list." + (car (cdr (cdr list))))) + +(if (fboundp 'cdddr) + (defalias 'malyon-cdddr 'cdddr) + (defun malyon-cdddr (list) + "Take the cdddr of the list." + (cdr (cdr (cdr list))))) + +(if (fboundp 'char-before) + (defalias 'malyon-char-before 'char-before) + (defun malyon-char-before () + "Return the character before the point." + (char-after (- (point) 1)))) + +(if (fboundp 'char-to-int) + (defalias 'malyon-char-to-int 'char-to-int) + (defun malyon-char-to-int (c) + "Convert a character into an integer." + c)) + +(if (fboundp 'characterp) + (defalias 'malyon-characterp 'characterp) + (defun malyon-characterp (x) + "Test for a character." + (and (numberp x) (<= 0 x) (< x 256)))) + +(defun malyon-disable-multibyte () + "Disable multibyte support in the current buffer." + (condition-case nil (set-buffer-multibyte nil) (error))) + +(defun malyon-erase-buffer (&optional buffer) + "Erase the given buffer." + (save-excursion + (if buffer (set-buffer buffer)) + (if (and buffer (eq buffer malyon-transcript-buffer)) + (malyon-begin-section) + (erase-buffer)))) + +(if (fboundp 'int-to-char) + (defalias 'malyon-int-to-char 'int-to-char) + (defun malyon-int-to-char (i) + "Convert an integer into a character." + i)) + +(if (fboundp 'mapc) + (defalias 'malyon-mapc 'mapc) + (defun malyon-mapc (function list) + "Apply fun to every element of args ignoring the results." + (if (null list) + '() + (funcall function (car list)) + (malyon-mapc function (cdr list))))) + +(if (fboundp 'mapcan) + (defalias 'malyon-mapcan 'mapcan) + (defun malyon-mapcan (function list) + "Apply fun to every element of args nconc'ing the result." + (if (null list) + '() + (nconc (funcall function (car list)) + (malyon-mapcan function (cdr list)))))) + +; Do not use the built-in conversion via 'multibyte-char-to-unibyte. +(defun malyon-multibyte-char-to-unibyte (char) + "Convert a multibyte character to unibyte." + char) + +(defun malyon-point-max (&optional buffer) + "Get the point-max of the given buffer." + (save-excursion + (if buffer (set-buffer buffer)) + (point-max))) + +(if (fboundp 'redisplay-frame) + (defalias 'malyon-redisplay-frame 'redisplay-frame) + (defun malyon-redisplay-frame (frame &rest ignore) + "Redisplay the given frame.")) + +(if (fboundp 'remove) + (defalias 'malyon-remove 'remove) + (defun malyon-remove (element list) + "Remove the element from the list." + (cond ((null list) + '()) + ((eq element (car list)) + (malyon-remove element (cdr list))) + ((equal element (car list)) + (malyon-remove element (cdr list))) + (t + (cons (car list) + (malyon-remove element (cdr list))))))) + +(if (fboundp 'set-keymap-name) + (defalias 'malyon-set-keymap-name 'set-keymap-name) + (defun malyon-set-keymap-name (keymap name) + "Set the name of the keymap.")) + +(if (fboundp 'string-to-list) + (defalias 'malyon-string-to-list 'string-to-list) + (defun malyon-string-to-list (s) + "Convert a string into a list of characters." + (let ((i (- (length s) 1)) (l '())) + (while (<= 0 i) + (setq l (cons (aref s i) l) + i (- i 1))) + l))) + +(if (fboundp 'string-to-vector) + (defalias 'malyon-string-to-vector 'string-to-vector) + (defun malyon-string-to-vector (s) + "Convert a string into a vector of characters." + (let* ((i 0) (l (length s)) (v (make-vector l 0))) + (while (< i l) + (aset v i (aref s i)) + (setq i (+ 1 i))) + v))) + +; Do not use the built-in conversion via 'unibyte-char-to-multibyte. +(defun malyon-unibyte-char-to-multibyte (char) + "Convert a unibyte character to multibyte." + char) + +(defun malyon-vector-to-list (v begin end) + "Return a list of elements in v in the range [begin, end)." + (let ((result '())) + (while (< begin end) + (setq result (cons (aref v begin) result)) + (setq begin (+ 1 begin))) + (reverse result))) + +(if (fboundp 'window-displayed-height) + (defalias 'malyon-window-displayed-height 'window-displayed-height) + (defun malyon-window-displayed-height (&optional window) + "Get the height of the window's displayed region." + (- (window-height) 1))) + +(if (fboundp 'yes-or-no-p-minibuf) + (defalias 'malyon-yes-or-no-p-minibuf 'yes-or-no-p-minibuf) + (defun malyon-yes-or-no-p-minibuf (prompt) + "Ask a yes or no question." + (yes-or-no-p prompt))) + +;; global variables for the malyon mode + +(defvar malyon-syntax-table nil + "Syntax table used while in malyon mode (same as in text-mode).") + +(if malyon-syntax-table + '() + (setq malyon-syntax-table (make-syntax-table)) + (modify-syntax-entry ?\" ". " malyon-syntax-table) + (modify-syntax-entry ?\\ ". " malyon-syntax-table) + (modify-syntax-entry ?' "w " malyon-syntax-table)) + +(defvar malyon-keymap-read nil + "Keymap for malyon mode for reading input into a buffer.") + +(defvar malyon-history-saved-up nil + "The saved binding for the up arrow key.") + +(defvar malyon-history-saved-down nil + "The saved binding for the down arrow key.") + +(if malyon-keymap-read + '() + (setq malyon-keymap-read (make-sparse-keymap)) + (malyon-set-keymap-name malyon-keymap-read 'malyon-keymap-read) + (setq malyon-history-saved-up (global-key-binding [up])) + (setq malyon-history-saved-down (global-key-binding [down])) + (define-key malyon-keymap-read "\r" 'malyon-end-input) + (define-key malyon-keymap-read [up] 'malyon-history-previous-char) + (define-key malyon-keymap-read [down] 'malyon-history-next-char) + (define-key malyon-keymap-read "\M-p" 'malyon-history-previous-char) + (define-key malyon-keymap-read "\M-n" 'malyon-history-next-char) + (define-key malyon-keymap-read "\C-a" 'malyon-beginning-of-line) + (define-key malyon-keymap-read "\C-w" 'malyon-kill-region) + (define-key malyon-keymap-read "\C-k" 'malyon-kill-line) + (define-key malyon-keymap-read "\M-d" 'malyon-kill-word) + (define-key malyon-keymap-read "\C-y" 'malyon-yank) + (define-key malyon-keymap-read "\M-y" 'malyon-yank-pop) + (define-key malyon-keymap-read "\C-d" 'malyon-delete-char) + (define-key malyon-keymap-read "\d" 'malyon-backward-delete-char) + (define-key malyon-keymap-read [del] 'malyon-delete-char) + (define-key malyon-keymap-read [backspace] 'malyon-backward-delete-char) + (substitute-key-definition (lookup-key (current-global-map) "a") + 'malyon-self-insert-command + malyon-keymap-read (current-global-map))) + +(defvar malyon-keymap-readchar nil + "Keymap for malyon mode for waiting for input.") + +(if malyon-keymap-readchar + '() + (setq malyon-keymap-readchar (make-sparse-keymap)) + (malyon-set-keymap-name malyon-keymap-readchar 'malyon-keymap-readchar) + (define-key malyon-keymap-readchar "\r" 'malyon-wait-char) + (substitute-key-definition (lookup-key (current-global-map) "a") + 'malyon-wait-char + malyon-keymap-readchar (current-global-map))) + +(defvar malyon-keymap-more nil + "Keymap for malyon mode for browsing through text.") + +(if malyon-keymap-more + '() + (setq malyon-keymap-more (make-sparse-keymap)) + (malyon-set-keymap-name malyon-keymap-more 'malyon-keymap-more) + (define-key malyon-keymap-more "\r" 'malyon-more-char) + (substitute-key-definition (lookup-key (current-global-map) "a") + 'malyon-more-char + malyon-keymap-more (current-global-map))) + +(defvar malyon-keymap-more-status nil + "Keymap for malyon mode for browsing through the status buffer.") + +(if malyon-keymap-more-status + '() + (setq malyon-keymap-more-status (make-sparse-keymap)) + (malyon-set-keymap-name malyon-keymap-more-status 'malyon-keymap-more-status) + (define-key malyon-keymap-more-status "\r" 'malyon-more-char-status) + (substitute-key-definition (lookup-key (current-global-map) "a") + 'malyon-more-char-status + malyon-keymap-more-status (current-global-map))) + +(defvar malyon-faces nil + "An association list of text faces used by the malyon mode.") + +(defun malyon-initialize-faces () + (copy-face 'default 'malyon-face-plain) + (copy-face 'bold 'malyon-face-reverse) + (copy-face 'bold 'malyon-face-bold) + (copy-face 'italic 'malyon-face-italic) + (copy-face 'default 'malyon-face-error) + (set-face-foreground 'malyon-face-error "red") + (setq malyon-faces '((0 . malyon-face-plain) + (1 . malyon-face-reverse) + (2 . malyon-face-bold) + (4 . malyon-face-italic) + (8 . malyon-face-plain)))) + +(defvar malyon-print-separator nil + "A flag indicating whether to print the * * * separator.") + +(defun malyon-begin-section () + "Print a section divider and begin a new section." + (if malyon-print-separator + (progn + (malyon-mapc 'malyon-putchar-transcript '(?\n ?\n ?* ? ?* ? ?*)) + (center-line) + (malyon-mapc 'malyon-putchar-transcript '(?\n ?\n)) + (setq malyon-print-separator nil))) + (narrow-to-region (point-max) (point-max))) + +(if malyon-whitespace + '() + (setq malyon-whitespace (list (malyon-char-to-int ? ) + (malyon-char-to-int ?\t) + (malyon-char-to-int ?\n) + (malyon-char-to-int ?\r)))) + +;; memory utilities + +(defsubst malyon-read-byte (address) + "Read a byte at address in the story file." + (if (<= 0 address) + (aref malyon-story-file address) + (aref malyon-story-file (+ 65536 address)))) + +(defsubst malyon-store-byte (address value) + "Store a byte at address in the story file." + (if (<= 0 address) + (aset malyon-story-file address (logand 255 value)) + (aset malyon-story-file (+ 65536 address) (logand 255 value)))) + +(defsubst malyon-read-word (address) + "Read a word at address in the story file." + (if (<= 0 address) + (logior (lsh (aref malyon-story-file address) 8) + (aref malyon-story-file (+ 1 address))) + (logior (lsh (aref malyon-story-file (+ 65536 address)) 8) + (aref malyon-story-file (+ 65537 address))))) + +(defsubst malyon-store-word (address value) + "Store a word at address in the story file." + (if (<= 0 address) + (progn + (aset malyon-story-file address (logand 255 (lsh value -8))) + (aset malyon-story-file (+ 1 address) (logand 255 value))) + (aset malyon-story-file (+ 65536 address) (logand 255 (lsh value -8))) + (aset malyon-story-file (+ 65537 address) (logand 255 value)))) + +(defsubst malyon-read-code-byte () + "Read the next byte at the program counter location." + (setq malyon-instruction-pointer (+ malyon-instruction-pointer 1)) + (malyon-read-byte (- malyon-instruction-pointer 1))) + +(defsubst malyon-read-code-word () + "Read the next word at the program counter location." + (setq malyon-instruction-pointer (+ malyon-instruction-pointer 2)) + (malyon-read-word (- malyon-instruction-pointer 2))) + +(defsubst malyon-pop-stack () + "Pop a value off the stack." + (if (> 0 malyon-stack-pointer) + (malyon-fatal-error "stack underflow.")) + (setq malyon-stack-pointer (- malyon-stack-pointer 1)) + (aref malyon-stack (+ malyon-stack-pointer 1))) + +(defsubst malyon-read-local-variable (variable) + "Read a local variable." + (aref malyon-stack (+ variable malyon-frame-pointer))) + +(defsubst malyon-read-global-variable (variable) + "Read a global variable." + (malyon-read-word (+ malyon-global-variables (* 2 variable)))) + +(defsubst malyon-read-variable (variable) + "Read a variable." + (cond ((= variable 0) (malyon-pop-stack)) + ((< variable 16) (malyon-read-local-variable variable)) + (t (malyon-read-global-variable (- variable 16))))) + +(defsubst malyon-push-stack (value) + "Push a value onto the stack." + (setq malyon-stack-pointer (+ malyon-stack-pointer 1)) + (aset malyon-stack malyon-stack-pointer value)) + +(defsubst malyon-store-local-variable (variable value) + "Store a value in a local variable." + (aset malyon-stack (+ variable malyon-frame-pointer) value)) + +(defsubst malyon-store-global-variable (variable value) + "Store a value in a global variable." + (malyon-store-word (+ malyon-global-variables (* 2 variable)) value)) + +(defsubst malyon-store-variable (var value) + "Store the value in a variable." + (setq value (logand 65535 value)) + (cond ((= var 0) (malyon-push-stack value)) + ((< var 16) (malyon-store-local-variable var value)) + (t (malyon-store-global-variable (- var 16) value)))) + +;; list of opcodes + +(defvar malyon-opcodes + [malyon-opcode-nop + malyon-opcode-je malyon-opcode-jl + malyon-opcode-jg malyon-opcode-dec-chk + malyon-opcode-inc-chk malyon-opcode-jin + malyon-opcode-test malyon-opcode-or + malyon-opcode-and malyon-opcode-test-attr + malyon-opcode-set-attr malyon-opcode-clear-attr + malyon-opcode-store malyon-opcode-insert-obj + malyon-opcode-loadw malyon-opcode-loadb + malyon-opcode-get-prop malyon-opcode-get-prop-addr + malyon-opcode-get-next-prop malyon-opcode-add + malyon-opcode-sub malyon-opcode-mul + malyon-opcode-div malyon-opcode-mod + malyon-opcode-calls malyon-opcode-calln + malyon-opcode-set-color malyon-opcode-throw + malyon-opcode-nop malyon-opcode-nop + malyon-opcode-nop malyon-opcode-nop + malyon-opcode-je malyon-opcode-jl + malyon-opcode-jg malyon-opcode-dec-chk + malyon-opcode-inc-chk malyon-opcode-jin + malyon-opcode-test malyon-opcode-or + malyon-opcode-and malyon-opcode-test-attr + malyon-opcode-set-attr malyon-opcode-clear-attr + malyon-opcode-store malyon-opcode-insert-obj + malyon-opcode-loadw malyon-opcode-loadb + malyon-opcode-get-prop malyon-opcode-get-prop-addr + malyon-opcode-get-next-prop malyon-opcode-add + malyon-opcode-sub malyon-opcode-mul + malyon-opcode-div malyon-opcode-mod + malyon-opcode-calls malyon-opcode-calln + malyon-opcode-set-color malyon-opcode-throw + malyon-opcode-nop malyon-opcode-nop + malyon-opcode-nop malyon-opcode-nop + malyon-opcode-je malyon-opcode-jl + malyon-opcode-jg malyon-opcode-dec-chk + malyon-opcode-inc-chk malyon-opcode-jin + malyon-opcode-test malyon-opcode-or + malyon-opcode-and malyon-opcode-test-attr + malyon-opcode-set-attr malyon-opcode-clear-attr + malyon-opcode-store malyon-opcode-insert-obj + malyon-opcode-loadw malyon-opcode-loadb + malyon-opcode-get-prop malyon-opcode-get-prop-addr + malyon-opcode-get-next-prop malyon-opcode-add + malyon-opcode-sub malyon-opcode-mul + malyon-opcode-div malyon-opcode-mod + malyon-opcode-calls malyon-opcode-calln + malyon-opcode-set-color malyon-opcode-throw + malyon-opcode-nop malyon-opcode-nop + malyon-opcode-nop malyon-opcode-nop + malyon-opcode-je malyon-opcode-jl + malyon-opcode-jg malyon-opcode-dec-chk + malyon-opcode-inc-chk malyon-opcode-jin + malyon-opcode-test malyon-opcode-or + malyon-opcode-and malyon-opcode-test-attr + malyon-opcode-set-attr malyon-opcode-clear-attr + malyon-opcode-store malyon-opcode-insert-obj + malyon-opcode-loadw malyon-opcode-loadb + malyon-opcode-get-prop malyon-opcode-get-prop-addr + malyon-opcode-get-next-prop malyon-opcode-add + malyon-opcode-sub malyon-opcode-mul + malyon-opcode-div malyon-opcode-mod + malyon-opcode-calls malyon-opcode-calln + malyon-opcode-set-color malyon-opcode-throw + malyon-opcode-nop malyon-opcode-nop + malyon-opcode-nop malyon-opcode-jz + malyon-opcode-get-sibling malyon-opcode-get-child + malyon-opcode-get-parent malyon-opcode-get-prop-len + malyon-opcode-inc malyon-opcode-dec + malyon-opcode-print-addr malyon-opcode-calls + malyon-opcode-remove-obj malyon-opcode-print-obj + malyon-opcode-ret malyon-opcode-jump + malyon-opcode-print-paddr malyon-opcode-load + malyon-opcode-calln malyon-opcode-jz + malyon-opcode-get-sibling malyon-opcode-get-child + malyon-opcode-get-parent malyon-opcode-get-prop-len + malyon-opcode-inc malyon-opcode-dec + malyon-opcode-print-addr malyon-opcode-calls + malyon-opcode-remove-obj malyon-opcode-print-obj + malyon-opcode-ret malyon-opcode-jump + malyon-opcode-print-paddr malyon-opcode-load + malyon-opcode-calln malyon-opcode-jz + malyon-opcode-get-sibling malyon-opcode-get-child + malyon-opcode-get-parent malyon-opcode-get-prop-len + malyon-opcode-inc malyon-opcode-dec + malyon-opcode-print-addr malyon-opcode-calls + malyon-opcode-remove-obj malyon-opcode-print-obj + malyon-opcode-ret malyon-opcode-jump + malyon-opcode-print-paddr malyon-opcode-load + malyon-opcode-calln malyon-opcode-rtrue + malyon-opcode-rfalse malyon-opcode-print + malyon-opcode-print-ret malyon-opcode-nop + malyon-opcode-illegal malyon-opcode-illegal + malyon-opcode-restart malyon-opcode-ret-popped + malyon-opcode-catch malyon-opcode-quit + malyon-opcode-new-line malyon-opcode-illegal + malyon-opcode-verify malyon-opcode-illegal + malyon-opcode-piracy malyon-opcode-nop + malyon-opcode-je malyon-opcode-jl + malyon-opcode-jg malyon-opcode-dec-chk + malyon-opcode-inc-chk malyon-opcode-jin + malyon-opcode-test malyon-opcode-or + malyon-opcode-and malyon-opcode-test-attr + malyon-opcode-set-attr malyon-opcode-clear-attr + malyon-opcode-store malyon-opcode-insert-obj + malyon-opcode-loadw malyon-opcode-loadb + malyon-opcode-get-prop malyon-opcode-get-prop-addr + malyon-opcode-get-next-prop malyon-opcode-add + malyon-opcode-sub malyon-opcode-mul + malyon-opcode-div malyon-opcode-mod + malyon-opcode-calls malyon-opcode-calln + malyon-opcode-set-color malyon-opcode-throw + malyon-opcode-nop malyon-opcode-nop + malyon-opcode-nop malyon-opcode-calls + malyon-opcode-storew malyon-opcode-storeb + malyon-opcode-put-prop malyon-opcode-aread + malyon-opcode-print-char malyon-opcode-print-num + malyon-opcode-random malyon-opcode-push + malyon-opcode-pull malyon-opcode-split-window + malyon-opcode-set-window malyon-opcode-calls + malyon-opcode-erase-window malyon-opcode-erase-line + malyon-opcode-set-cursor malyon-opcode-get-cursor + malyon-opcode-set-text-style malyon-opcode-buffer-mode + malyon-opcode-output-stream malyon-opcode-input-stream + malyon-opcode-nop malyon-opcode-read-char + malyon-opcode-scan-table malyon-opcode-not + malyon-opcode-calln malyon-opcode-calln + malyon-opcode-tokenise malyon-opcode-encode-text + malyon-opcode-copy-table malyon-opcode-print-table + malyon-opcode-check-arg-count malyon-opcode-save + malyon-opcode-restore malyon-opcode-log-shift + malyon-opcode-art-shift malyon-opcode-set-font + malyon-opcode-illegal malyon-opcode-illegal + malyon-opcode-illegal malyon-opcode-illegal + malyon-opcode-save-undo malyon-opcode-restore-undo + malyon-opcode-print-unicode malyon-opcode-check-unicode + malyon-opcode-nop malyon-opcode-nop + malyon-opcode-nop] + "A vector of all known legal z code opcodes.") + +;; initialization + +(defun malyon-load-story-file (file-name) + "Load a z code story file into an internal vector." + (save-excursion + (set-buffer (create-file-buffer file-name)) + (malyon-disable-multibyte) + (malyon-erase-buffer) + (let ((coding-system-for-read 'binary)) + (insert-file-contents file-name)) + (setq malyon-story-file-name file-name) + (setq malyon-story-file (buffer-substring-no-properties (point-min) + (point-max))) + (setq malyon-story-file (malyon-string-to-vector malyon-story-file)) + (if (not (eq ?\^A 1)) + (let ((i 0)) + (while (< i (length malyon-story-file)) + (aset malyon-story-file + i + (malyon-char-to-int (aref malyon-story-file i))) + (setq i (+ 1 i))))) + (kill-buffer nil))) + +(defun malyon-initialize () + "Initialize the z code interpreter." +; (malyon-trace-file) + (setq malyon-game-state-quetzal t) + (malyon-initialize-faces) + (malyon-initialize-status) + (malyon-initialize-transcript) + (malyon-initialize-windows) + (malyon-initialize-story-header) + (malyon-initialize-registers) + (malyon-initialize-opcodes) + (malyon-history-clear) + (setq malyon-game-state-restart (malyon-current-game-state)) + (malyon-print-header)) + +(defun malyon-initialize-status () + "Initialize the status buffer." + (setq malyon-status-buffer (get-buffer-create "Malyon Status")) + (switch-to-buffer malyon-status-buffer) + (malyon-erase-buffer) + (kill-all-local-variables) + (setq malyon-status-buffer-point (point)) + (setq malyon-status-buffer-lines 0) + (setq malyon-status-buffer-delayed-split nil) + (use-local-map malyon-keymap-read) + (set-syntax-table malyon-syntax-table) + (setq mode-name "Malyon") + (setq major-mode 'malyon-mode) + (run-hooks 'malyon-mode-hook)) + +(defun malyon-initialize-transcript () + "Initialize the transcript buffer." + (setq malyon-transcript-buffer (get-buffer-create "Malyon Transcript")) + (switch-to-buffer malyon-transcript-buffer) + (malyon-erase-buffer) + (kill-all-local-variables) + (setq malyon-last-cursor-position-after-input + (malyon-point-max malyon-transcript-buffer)) + (use-local-map malyon-keymap-read) + (set-syntax-table malyon-syntax-table) + (setq fill-column malyon-max-column) + (auto-fill-mode 1) + (setq mode-name "Malyon") + (setq major-mode 'malyon-mode) + (run-hooks 'malyon-mode-hook)) + +(defun malyon-initialize-windows () + "Initialize the window configuration for the z machine." + (setq window-min-height 3) + (setq malyon-transcript-buffer-buffered t) + (malyon-set-window-configuration 0) + (malyon-opcode-set-window 0)) + +(defun malyon-initialize-story-header () + "Initializes the header section of the story file." + (malyon-store-byte 1 + (if (>= malyon-story-version 5) + 28 + (logior 48 (malyon-read-byte 1)))) + (malyon-store-byte 16 (logand 440 (malyon-read-byte 16))) + (malyon-store-byte 30 1) + (malyon-store-byte 31 65) + (malyon-store-byte 32 255) + (malyon-store-byte 33 (- malyon-max-column 1)) + (malyon-store-word 34 (- malyon-max-column 1)) + (malyon-store-word 36 255) + (malyon-store-word 38 1) + (malyon-store-word 39 1) + (malyon-store-byte 44 0) + (malyon-store-byte 45 0) + (malyon-store-byte 50 1) + (malyon-store-byte 51 0)) + +(defun malyon-initialize-registers () + "Initialize the interpreter's internal registers." + (setq malyon-stack (make-vector 1024 0)) + (setq malyon-stack-pointer -1) + (malyon-push-initial-frame) + (setq malyon-frame-pointer malyon-stack-pointer) + (setq malyon-instruction-pointer (malyon-read-word 6)) + (setq malyon-global-variables (malyon-read-word 12)) + (setq malyon-object-table (malyon-read-word 10)) + (cond ((< malyon-story-version 5) + (setq malyon-object-table-entry-size 9) + (setq malyon-object-properties 31) + (setq malyon-object-property-offset 7)) + (t + (setq malyon-object-table-entry-size 14) + (setq malyon-object-properties 63) + (setq malyon-object-property-offset 12))) + (setq malyon-abbreviations (malyon-read-word 24)) + (if (< malyon-story-version 5) + (setq malyon-score-game (zerop (logand 2 (malyon-read-byte 1))))) + (setq malyon-packed-multiplier + (malyon-cadr (assq malyon-story-version '((3 2) (5 4) (8 8))))) + (if (or (< malyon-story-version 5) (zerop (malyon-read-word 52))) + (setq malyon-alphabet (concat "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + " \n0123456789.,!?_#'\"/\\-:()")) + (setq malyon-alphabet (make-string 78 ? )) + (let ((i 0)) + (while (< i 78) + (aset malyon-alphabet i + (malyon-read-byte (+ i (malyon-read-word 52)))) + (setq i (+ 1 i))))) + (malyon-initialize-unicode-table) + (setq malyon-dictionary (malyon-read-word 8)) + (setq malyon-dictionary-entry-length + (malyon-read-byte + (+ 1 malyon-dictionary (malyon-read-byte malyon-dictionary)))) + (setq malyon-dictionary-num-entries + (malyon-read-word + (+ 2 malyon-dictionary (malyon-read-byte malyon-dictionary)))) + (setq malyon-dictionary-entries + (+ 4 malyon-dictionary (malyon-read-byte malyon-dictionary))) + (setq malyon-dictionary-word-length (if (< malyon-story-version 5) 3 5)) + (setq malyon-current-face 'malyon-face-plain) + (setq malyon-print-separator nil) + (malyon-initialize-output-streams)) + +(defun malyon-initialize-opcodes () + "Initialize the opcode table used by the story file." + (cond ((< malyon-story-version 5) + (aset malyon-opcodes 143 'malyon-opcode-not) + (aset malyon-opcodes 181 'malyon-opcode-save) + (aset malyon-opcodes 182 'malyon-opcode-restore) + (aset malyon-opcodes 185 'malyon-opcode-pop) + (aset malyon-opcodes 188 'malyon-opcode-show-status)) + (t + (aset malyon-opcodes 143 'malyon-opcode-calln) + (aset malyon-opcodes 181 'malyon-opcode-illegal) + (aset malyon-opcodes 182 'malyon-opcode-illegal) + (aset malyon-opcodes 185 'malyon-opcode-catch) + (aset malyon-opcodes 188 'malyon-opcode-illegal)))) + +(defun malyon-print-header () + "Print malyon mode header information." + (malyon-opcode-set-text-style 2) + (malyon-print "Malyon V 1.0.2") + (malyon-opcode-set-text-style 0) + (malyon-newline) + (malyon-print "A z-code interpreter for version 3, 5, and 8 games.") + (malyon-newline) + (malyon-print "(c) 1999-2009 by Peter Ilberg ") + (malyon-newline) + (malyon-newline)) + +;; cleanup + +(defun malyon-cleanup () + "Clean up the z code interpreter." + (condition-case nil + (progn + (setq malyon-story-file nil) + (setq malyon-window-configuration nil) + (setq malyon-game-state-restart nil) + (setq malyon-game-state-undo nil) + (if (get-buffer "Malyon Status") + (kill-buffer (get-buffer "Malyon Status"))) + (if (get-buffer "Malyon Transcript") + (progn + (switch-to-buffer (get-buffer "Malyon Transcript")) + (malyon-redisplay-frame (selected-frame) t) + (delete-other-windows (get-buffer-window (current-buffer))) + (widen) + (text-mode))) + (setq malyon-status-buffer nil) + (setq malyon-transcript-buffer nil)) + (error + (malyon-fatal-error "cleanup failed.")))) + +;; error handling + +(defun malyon-fatal-error (message) + "Print error message and abort." + (setq message (concat "Malyon fatal error: " message)) + (unwind-protect + (save-excursion + (set-buffer malyon-transcript-buffer) + (goto-char (point-max)) + (newline) + (newline) + (put-text-property 0 + (length message) + 'face + 'malyon-face-error + message) + (insert message) + (newline)) + (malyon-cleanup) + (malyon-redisplay-frame (selected-frame) t) + (error message))) + +;; conversion of zscii to ascii + +(defvar malyon-unicode-table nil + "An array mapping zscii characters to latin-1 ones.") + +(defvar malyon-default-unicode-table nil + "The default array mapping zscii characters to latin-1 ones.") + +(if malyon-default-unicode-table + '() + (setq malyon-default-unicode-table + [32 + 0 0 0 0 0 0 0 ; 1 - 7 + 8 0 0 0 0 10 0 0 ; 8 - 15 + 0 0 0 0 0 0 0 0 ; 16 - 23 + 0 0 0 39 0 0 0 0 ; 24 - 31 + 32 33 34 35 36 37 38 39 ; 32 - 39 + 40 41 42 43 44 45 46 47 ; 40 - 47 + 48 49 50 51 52 53 54 55 ; 48 - 55 + 56 57 58 59 60 61 62 63 ; 56 - 63 + 64 65 66 67 68 69 70 71 ; 64 - 71 + 72 73 74 75 76 77 78 79 ; 72 - 79 + 80 81 82 83 84 85 86 87 ; 80 - 87 + 88 89 90 91 92 93 94 95 ; 88 - 95 + 96 97 98 99 100 101 102 103 ; 96 - 103 + 104 105 106 107 108 109 110 111 ; 104 - 111 + 112 113 114 115 116 117 118 119 ; 112 - 119 + 120 121 122 123 124 125 126 0 ; 120 - 127 + 0 0 0 0 0 0 0 0 ; 128 - 135 + 0 0 0 0 0 0 0 0 ; 136 - 143 + 0 48 49 50 51 52 53 54 ; 144 - 151 + 55 56 57 228 246 252 196 214 ; 152 - 159 + 220 223 187 171 235 239 255 203 ; 160 - 167 + 207 225 233 237 243 250 253 193 ; 168 - 175 + 201 205 211 218 221 224 232 236 ; 176 - 183 + 242 249 192 200 204 210 217 226 ; 184 - 191 + 234 238 244 251 194 202 206 212 ; 192 - 199 + 219 229 197 248 216 227 241 245 ; 200 - 207 + 195 209 213 230 198 231 199 254 ; 208 - 215 + 240 222 208 163 63 63 161 191 ; 216 - 223 + 0 0 0 0 0 0 0 0 ; 224 - 231 + 0 0 0 0 0 0 0 0 ; 232 - 239 + 0 0 0 0 0 0 0 0 ; 240 - 247 + 0 0 0 0 0 0 0 0 ; 248 - 255 + ])) + +(defun malyon-initialize-unicode-table () + "Initializes the zscii-to-unicode conversion table." + (setq malyon-unicode-table + (copy-sequence malyon-default-unicode-table)) + (let* ((ext (malyon-read-word 54)) + (len (if (zerop ext) 0 (malyon-read-word ext))) + (table (if (< len 3) 0 (malyon-read-word (+ ext 6))))) + (if (or (< malyon-story-version 5) (zerop table)) + '() + (let ((i 0)) + (while (< i 96) + (aset malyon-unicode-table (+ 155 i) (malyon-char-to-int ??)) + (setq i (+ 1 i)))) + (setq len (malyon-read-byte table)) + (let ((i 0)) + (while (< i len) + (aset malyon-unicode-table (+ 155 i) + (malyon-read-word (+ table 1 i))) + (setq i (+ 1 i))))))) + +(defsubst malyon-zscii-to-unicode (char) + "Converts a zscii character to unicode." + (if (or (< char 0) (> char 255)) + ?? + (let ((uni (aref malyon-unicode-table char))) + (if (zerop uni) + ?? + (malyon-unibyte-char-to-multibyte (malyon-int-to-char uni)))))) + +(defsubst malyon-unicode-to-zscii (char) + "Converts a unicode character to zscii." + (setq char (malyon-multibyte-char-to-unibyte char)) + (setq char (if (malyon-characterp char) (malyon-char-to-int char) char)) + (if (= 13 char) + ?\r + (let ((i 1) (found 0)) + (while (and (< i 255) (zerop found)) + (if (= char (aref malyon-unicode-table i)) + (setq found i)) + (setq i (+ i 1))) + (malyon-int-to-char found)))) + +;; output streams + +(defvar malyon-output-streams nil + "Valid output streams for the interpreter.") + +(defvar malyon-output-streams-tables nil + "A list of active tables for stream 3.") + +(defun malyon-initialize-output-streams () + "Initializes the output streams." + (setq malyon-output-streams '()) + (setq malyon-output-streams-tables '()) + (malyon-add-output-stream 1 0)) + +(defun malyon-output-stream-function (stream) + "Returns the output function representing the given stream." + (cond ((= 1 stream) (if (zerop malyon-current-window) + 'malyon-putchar-transcript + 'malyon-putchar-status)) + ((= 2 stream) 'malyon-putchar-printer))) + +(defun malyon-add-output-stream (stream table) + "Add a new output stream." + (if (= stream 3) + (progn + (setq malyon-output-streams-tables + (cons table malyon-output-streams-tables)) + (malyon-store-word table 0)) + (let ((function (malyon-output-stream-function stream))) + (setq malyon-output-streams + (if (member function malyon-output-streams) + malyon-output-streams + (cons function malyon-output-streams)))))) + +(defun malyon-remove-output-stream (stream) + "Remove an output stream." + (if (= stream 3) + (setq malyon-output-streams-tables (cdr malyon-output-streams-tables)) + (setq malyon-output-streams + (malyon-remove (malyon-output-stream-function stream) + malyon-output-streams)))) + +(defun malyon-update-output-streams () + "Update output streams when the output window has changed." + (let ((one (or (member 'malyon-putchar-transcript malyon-output-streams) + (member 'malyon-putchar-status malyon-output-streams)))) + (setq malyon-output-streams + (malyon-remove 'malyon-putchar-transcript + (malyon-remove 'malyon-putchar-status + malyon-output-streams))) + (if one + (malyon-add-output-stream 1 0)))) + +(defsubst malyon-output-character (char) + "Output a single character on all active streams." + (setq char (malyon-zscii-to-unicode char)) + (if malyon-output-streams-tables + (malyon-putchar-table char (car malyon-output-streams-tables)) + (malyon-mapc (lambda (s) (funcall s char)) malyon-output-streams))) + +;; printing text + +(defsubst malyon-abbrev (abbrev x) + "Print an abbreviation." + (malyon-print-ztext + (* 2 (malyon-read-word (+ malyon-abbreviations + (* 2 (+ x (* 32 (1- abbrev))))))))) + +(defun malyon-newline () + "Print a newline." + (if (eq malyon-status-buffer (current-buffer)) + (goto-char malyon-status-buffer-point) + (goto-char (point-max))) + (malyon-output-character ?\r) + (if (eq malyon-status-buffer (current-buffer)) + (setq malyon-status-buffer-point (point)) + (goto-char malyon-last-cursor-position-after-input)) + (malyon-redisplay-frame (selected-frame) nil)) + +(defun malyon-print (object) + "Print text." + (let ((text (if (malyon-characterp object) (char-to-string object) object)) + (start)) + (if (eq malyon-transcript-buffer (current-buffer)) + (goto-char (point-max)) + (goto-char malyon-status-buffer-point)) + (setq start (point)) + (malyon-print-characters (malyon-string-to-list text)) + (put-text-property start (point) 'face malyon-current-face) + (if (eq malyon-status-buffer (current-buffer)) + (setq malyon-status-buffer-point (point)) + (goto-char malyon-last-cursor-position-after-input)))) + +(defun malyon-print-characters (text) + "Print a list of characters." + (malyon-mapc 'malyon-output-character text)) + +(defsubst malyon-print-state-new (char shift abbr zscii zcode) + "Generate a new print state." + (list char shift abbr zscii zcode)) + +(defsubst malyon-print-state-initial () + "Returns an initial state for the ztext decoder." + (malyon-print-state-new nil -6 0 0 0)) + +(defsubst malyon-print-state-next (x ignore shift abbr zscii z) + "Print state transition function." + (cond ((= zscii 2) + (malyon-print-state-new (+ z x) -6 0 0 0)) + ((= zscii 1) + (malyon-print-state-new nil -6 0 2 (* 32 x))) + ((> abbr 0) + (malyon-abbrev abbr x) + (malyon-print-state-initial)) + ((= x 0) + (malyon-print-state-new ? -6 0 0 0)) + ((< x 4) + (malyon-print-state-new nil -6 x 0 0)) + ((= x 4) + (malyon-print-state-new nil 20 0 0 0)) + ((= x 5) + (malyon-print-state-new nil 46 0 0 0)) + ((and (= shift 46) (= x 6)) + (malyon-print-state-new nil -6 0 1 0)) + ((and (= shift 46) (= x 7)) + (malyon-print-state-new ?\r -6 0 0 0)) + (t + (malyon-print-state-new + (aref malyon-alphabet (+ shift x)) -6 0 0 0)))) + +(defun malyon-print-text (address) + "Print text at address and return the address of the following byte." + (let ((start)) + (if (eq malyon-transcript-buffer (current-buffer)) + (goto-char (point-max)) + (goto-char malyon-status-buffer-point)) + (setq start (point)) + (setq address (malyon-print-ztext address)) + (put-text-property start (point) 'face malyon-current-face) + (if (eq malyon-status-buffer (current-buffer)) + (setq malyon-status-buffer-point (point)) + (goto-char malyon-last-cursor-position-after-input)) + (malyon-redisplay-frame (selected-frame) nil) + address)) + +(defun malyon-print-ztext (address) + "Print the ztext stored at the given address." + (let ((high 0) (low) (a) (b) (c) (state (malyon-print-state-initial))) + (while (zerop (logand 128 high)) + (setq high (malyon-read-byte address)) + (setq low (malyon-read-byte (+ 1 address))) + (setq a (logand 31 (lsh high -2))) + (setq b (logand 31 (logior (lsh high 3) (lsh low -5)))) + (setq c (logand 31 low)) + (setq state (apply 'malyon-print-state-next a state)) + (if (car state) (malyon-output-character (car state))) + (setq state (apply 'malyon-print-state-next b state)) + (if (car state) (malyon-output-character (car state))) + (setq state (apply 'malyon-print-state-next c state)) + (if (car state) (malyon-output-character (car state))) + (setq address (+ 2 address))) + address)) + +(defun malyon-putchar-transcript (char) + "Print a single character in the transcript window." + (if (char-equal char ?\n) + (newline 1) + (insert char) + (setq malyon-print-separator (null (member char malyon-whitespace)))) + (if (and malyon-transcript-buffer-buffered + (> (current-column) (current-fill-column))) + (progn + (end-of-line) + (forward-word -1) + (if (< 0 (current-column)) + (newline 1)) + (end-of-line)))) + +(defun malyon-putchar-status (char) + "Print a single character in the status window." + (if malyon-status-buffer-delayed-split + (progn + (malyon-split-buffer-windows malyon-status-buffer-delayed-split) + (other-window 1))) + (if (char-equal char ?\n) + (progn + (beginning-of-line) + (forward-line 1) + (if (= (point) (point-max)) + (forward-line -1))) + (if (> (current-column) (current-fill-column)) + '() + (insert char) + (delete-char 1)))) + +(defun malyon-putchar-table (char table) + "Print a single character into a table." + (setq char (malyon-unicode-to-zscii char)) + (malyon-store-byte (+ 2 table (malyon-read-word table)) char) + (malyon-store-word table (+ 1 (malyon-read-word table)))) + +(defun malyon-putchar-printer (char) + "Print a single character onto a printer."); not yet implemented + +;; more + +(defvar malyon-more-continue-keymap nil + "The keymap with which to continue after More has finished.") + +(defun malyon-more (keymap) + "Enter More mode." + (if (eq malyon-status-buffer (current-buffer)) + (use-local-map keymap) + (if (< malyon-story-version 5) (malyon-opcode-show-status)) + (if (< (count-lines malyon-last-cursor-position-after-input (point-max)) + (malyon-window-displayed-height)) + (progn + (malyon-adjust-transcript) + (use-local-map keymap)) + (goto-char malyon-last-cursor-position-after-input) + (beginning-of-line) + (recenter 1) + (setq malyon-more-continue-keymap keymap) + (use-local-map malyon-keymap-more) + (message "[More]")))) + +(defun malyon-more-status-buffer () + "Enter More mode for the status buffer." + (setq malyon-more-continue-keymap (current-local-map)) + (use-local-map malyon-keymap-more-status) + (message "[More]") + (throw 'malyon-end-of-interpreter-loop 'malyon-waiting-for-input)) + +;; input history + +(defvar malyon-history nil + "The input history.") + +(defun malyon-history-previous () + "Move one entry up in the input history." + (let ((prev (aref malyon-history 0)) + (curr (aref malyon-history 1)) + (next (aref malyon-history 2))) + (if (null prev) + curr + (aset malyon-history 2 (if curr (cons curr next) next)) + (aset malyon-history 0 (cdr prev)) + (aset malyon-history 1 (car prev))))) + +(defun malyon-history-next () + "Move one entry down in the input history." + (let ((prev (aref malyon-history 0)) + (curr (aref malyon-history 1)) + (next (aref malyon-history 2))) + (if (null next) + curr + (aset malyon-history 0 (if curr (cons curr prev) prev)) + (aset malyon-history 2 (cdr next)) + (aset malyon-history 1 (car next))))) + +(defun malyon-history-clear () + "Clear the input history." + (setq malyon-history (vector '() nil '()))) + +(defun malyon-history-insert (entry) + "Insert an entry into the input history." + (let* ((prev (aref malyon-history 0)) + (curr (aref malyon-history 1)) + (next (aref malyon-history 2)) + (l (malyon-remove entry + (append (nreverse prev) + (if curr (cons curr next) next)))) + (cut (- (length l) 19))) + (while (> cut 0) + (setq l (cdr l) + cut (- cut 1))) + (aset malyon-history 0 + (malyon-remove nil (malyon-remove "" (cons entry (nreverse l))))) + (aset malyon-history 1 nil) + (aset malyon-history 2 '()))) + +;; dictionary lookup + +(defun malyon-dictionary-word (chars) + "Convert a list of characters into a dictionary word." + (list (car (car chars)) + (length chars) + (malyon-encode-dictionary-word (append (malyon-mapcan 'cdr chars) + '(5 5 5 5 5 5 5 5))))) + +(defsubst malyon-join-characters (stop list) + "Joins three ztext characters into two bytes." + (let ((a (car list)) + (b (malyon-cadr list)) + (c (malyon-caddr list)) + (x (if (zerop stop) 0 128))) + (list (logior x (logand 255 (logior (lsh a 2) (lsh b -3)))) + (logand 255 (logior (lsh b 5) c))))) + +(defun malyon-encode-dictionary-word (l) + "Converts a list of ztext characters into a dictionary word." + (let* ((first l) + (second (malyon-cdddr first)) + (third (malyon-cdddr second))) + (apply 'vector + (if (< malyon-story-version 5) + (append (malyon-join-characters 0 first) + (malyon-join-characters 1 second)) + (append (malyon-join-characters 0 first) + (malyon-join-characters 0 second) + (malyon-join-characters 1 third)))))) + +(defun malyon-lookup (dict code) + "Look for the given code in the dictionary and return its address." + (cond ((not code) 0) + ((not dict) (malyon-binary-search code)) + ((= dict malyon-dictionary) (malyon-binary-search code)) + (t (malyon-linear-search dict code)))) + +(defsubst malyon-compare-words (word address) + "Compares the given word to the word stored at address." + (let* ((i 0) + (j address) + (x (aref word i)) + (y (malyon-read-byte j))) + (while (not (or (/= x y) (= i malyon-dictionary-word-length))) + (setq i (+ 1 i) + j (+ 1 j) + x (aref word i) + y (malyon-read-byte j))) + (- x y))) + +;; search functions + +(defun malyon-binary-search (code) + "Binary search through the main dictionary." + (let* ((lower 0) + (upper (- malyon-dictionary-num-entries 1)) + (median (/ (+ lower upper) 2)) + (entry (+ malyon-dictionary-entries + (* malyon-dictionary-entry-length median))) + (looking (malyon-compare-words code entry))) + (while (not (or (> lower upper) (zerop looking))) + (setq lower (if (< 0 looking) (+ median 1) lower) + upper (if (> 0 looking) (- median 1) upper) + median (/ (+ lower upper) 2) + entry (+ malyon-dictionary-entries + (* malyon-dictionary-entry-length median)) + looking (malyon-compare-words code entry))) + (if (zerop looking) entry 0))) + +(defun malyon-linear-search (dictionary code) + "Linear search through the given dictionary." + (let* ((length (malyon-read-byte (+ dictionary 1 + (malyon-read-byte dictionary)))) + (number (malyon-read-word (+ dictionary 2 + (malyon-read-byte dictionary)))) + (entries (+ dictionary 4 (malyon-read-byte dictionary))) + (i 0) + (entry (+ entries (* length i))) + (looking (malyon-compare-words code entry))) + (while (not (or (>= i number) (zerop looking))) + (setq i (+ 1 i) + entry (+ entries (* length i)) + looking (malyon-compare-words code entry))) + (if (zerop looking) entry 0))) + +;; encoding text and lexical analysis + +(defun malyon-split-list (sep list &optional x) + "Split a list into sublists as indicated by the separators." + (cond ((null list) + (list (nreverse x))) + ((eq sep (car list)) + (cons (nreverse x) (malyon-split-list sep (cdr list) '()))) + (t + (malyon-split-list sep (cdr list) (cons (car list) x))))) + +(defun malyon-characters-to-words (list) + "Turn the list of characters into a list of words." + (mapcar 'malyon-dictionary-word + (delete '() (malyon-split-list 'malyon-word-separator list)))) + +(defsubst malyon-char-in-string (c s) + "Returns the index of c in s if found, or length of s." + (let ((i 0)) + (while (not (or (= i (length s)) (= c (aref s i)))) + (setq i (+ 1 i))) + i)) + +(defsubst malyon-encode-into-ztext (c) + "Convert a character into ztext." + (let* ((index (malyon-char-in-string c malyon-alphabet)) + (shift (floor index 26)) + (char (+ 6 (mod index 26)))) + (cond ((> shift 2) (list 5 6 (logand 31 (lsh c -5)) (logand 31 c))) + ((= shift 2) (list 5 char)) + ((= shift 1) (list 4 char)) + (t (list char))))) + +(defun malyon-encode-single-character (terminating-characters char) + "Encode a character into ztext." + (let ((pos (car char)) + (c (cdr char))) + (cond ((member c malyon-whitespace) + (list 'malyon-word-separator)) + ((member c terminating-characters) + (list 'malyon-word-separator + (cons pos (malyon-encode-into-ztext c)) + 'malyon-word-separator)) + (t (list (cons pos (malyon-encode-into-ztext c))))))) + +(defun malyon-encode-character-list (dict list) + "Encode the list of characters into ztext." + (let ((l '()) + (i 0)) + (while (< i (malyon-read-byte dict)) + (setq l (cons (malyon-read-byte (+ dict 1 i)) l) + i (+ 1 i))) + (malyon-mapcan (lambda (x) (malyon-encode-single-character l x)) list))) + +(defun malyon-text-length (address) + "Return the length of the input text." + (if (>= malyon-story-version 5) + (malyon-read-byte (+ 1 address)) + (let ((i 0)) + (while (not (zerop (malyon-read-byte (+ i 1 address)))) + (setq i (+ i 1))) + i))) + +(defun malyon-text-to-character-list (address) + "Convert the input text into a list of characters." + (let ((i (malyon-text-length address)) + (text '())) + (while (< 0 i) + (setq text (cons + (cons (if (< malyon-story-version 5) i (+ 1 i)) + (malyon-read-byte + (+ i address (if (< malyon-story-version 5) 0 1)))) + text) + i (- i 1))) + text)) + +(defun malyon-text-to-words (address dictionary) + "Turn ztext into a list of dictionary words." + (malyon-characters-to-words + (malyon-encode-character-list (if dictionary dictionary malyon-dictionary) + (malyon-text-to-character-list address)))) + +;; window management + +(defvar malyon-status-buffer-grew-this-turn nil + "A flag signalling if the status buffer grew this turn.") + +(defun malyon-adjust-transcript () + "Adjust the position of the transcript text." + (save-excursion + (setq malyon-status-buffer-grew-this-turn nil) + (set-buffer malyon-transcript-buffer) + (goto-char (point-max)) + (recenter (- (malyon-window-displayed-height) 2)))) + +(defun malyon-prepare-status-buffer (status) + "Fill the status buffer with empty lines." + (save-excursion + (set-buffer malyon-status-buffer) + (let ((lines (count-lines (point-min) (point-max))) + (new status)) + (if (zerop lines) + (newline 1)) + (goto-char (point-max)) + (setq status (- status lines -1)) + (while (> status 0) + (insert (make-string (+ 3 malyon-max-column) ? )) + (newline 1) + (setq status (- status 1))) + (goto-char (point-min)) + (forward-line (+ 1 new)) + (kill-region (point) (point-max)) + (insert (make-string (+ 3 malyon-max-column) ? )) + (newline 1)))) + +(defun malyon-restore-window-configuration () + "Restore the saved window configuration." + (let ((buffer (window-buffer (selected-window)))) + (if malyon-window-configuration + (set-window-configuration malyon-window-configuration)) + (cond ((eq malyon-status-buffer buffer) (other-window 1)) + ((eq malyon-transcript-buffer buffer) (goto-char (point-max)))))) + +(defun malyon-set-window-configuration (status) + "Set up the new window configuration." + (cond ((< status malyon-status-buffer-lines) + (setq malyon-status-buffer-delayed-split status) + (if malyon-status-buffer-grew-this-turn + (malyon-more-status-buffer))) + ((> status malyon-status-buffer-lines) + (malyon-split-buffer-windows status) + (setq malyon-status-buffer-grew-this-turn t)) + ((not malyon-window-configuration) + (malyon-split-buffer-windows status)))) + +(defun malyon-split-buffer-windows (status) + "Split the buffer windows. +The status buffer gets 'status' lines while the transcript buffer +gets the remaining lines." + (delete-other-windows (get-buffer-window (current-buffer))) + (setq malyon-status-buffer-lines status) + (setq malyon-status-buffer-delayed-split nil) + (if (zerop status) + '() + (split-window (get-buffer-window (current-buffer)) (+ status 3)) + (switch-to-buffer malyon-status-buffer) + (malyon-prepare-status-buffer status) + (malyon-opcode-set-cursor 1 1) + (other-window 1)) + (switch-to-buffer malyon-transcript-buffer) + (setq malyon-window-configuration (current-window-configuration))) + +;; getting and setting the machine state + +(defun malyon-current-game-state () + "Return the current state of the interpreter." + (vector malyon-instruction-pointer + malyon-stack-pointer + malyon-frame-pointer + (copy-sequence malyon-stack) + (copy-sequence malyon-story-file) + malyon-game-state-quetzal)) + +(defun malyon-set-game-state (state) + "Installs the given state as the new state of the interpreter." + (setq malyon-instruction-pointer (aref state 0)) + (setq malyon-stack-pointer (aref state 1)) + (setq malyon-frame-pointer (aref state 2)) + (setq malyon-stack (copy-sequence (aref state 3))) + (setq malyon-story-file (copy-sequence (aref state 4))) + (setq malyon-game-state-quetzal (aref state 5)) + (save-excursion + (malyon-erase-buffer malyon-status-buffer) + (malyon-split-buffer-windows 0) + (setq malyon-last-cursor-position-after-input + (malyon-point-max malyon-transcript-buffer)))) + +;; file utilities + +(defsubst malyon-write-byte-to-file (byte) + "Write a byte to a file." + (insert-char (logand 255 byte) 1)) + +(defsubst malyon-write-word-to-file (word) + "Write a word to the last opened file." + (insert-char (logand 255 (lsh word -8)) 1) + (insert-char (logand 255 word) 1)) + +(defsubst malyon-write-dword-to-file (dword) + "Write a dword to the last opened file." + (insert-char (logand 255 (lsh dword -24)) 1) + (insert-char (logand 255 (lsh dword -16)) 1) + (insert-char (logand 255 (lsh dword -8)) 1) + (insert-char (logand 255 dword) 1)) + +(defsubst malyon-write-chunk-id-to-file (id) + "Write a quetzal chunk id to the last opened file." + (insert id)) + +(defsubst malyon-read-byte-from-file () + "Read the next byte from a file." + (if (= (point) (point-max)) + 0 + (forward-char 1) + (malyon-char-to-int (malyon-char-before)))) + +(defsubst malyon-read-word-from-file () + "Read the next word from the last opened file." + (logior (lsh (malyon-read-byte-from-file) 8) (malyon-read-byte-from-file))) + +(defsubst malyon-read-dword-from-file () + "Read the next dword from the last opened file." + (logior (lsh (malyon-read-byte-from-file) 24) + (lsh (malyon-read-byte-from-file) 16) + (lsh (malyon-read-byte-from-file) 8) + (malyon-read-byte-from-file))) + +(defsubst malyon-read-chunk-id-from-file () + "Read a quetzal chunk id from the last opened file." + (string (malyon-int-to-char (malyon-read-byte-from-file)) + (malyon-int-to-char (malyon-read-byte-from-file)) + (malyon-int-to-char (malyon-read-byte-from-file)) + (malyon-int-to-char (malyon-read-byte-from-file)))) + +(defun malyon-get-file-name (address) + "Retrieves the file name stored at address." + (let ((name (make-string (malyon-read-byte address) ? )) + (i 0)) + (while (< i (length name)) + (aset name i (malyon-read-byte (+ address 1 i))) + (setq i (+ 1 i))) + name)) + +;; saving data to disk + +(defun malyon-save-file (file &optional table length) + "Save the current game state or a memory section to disk." + (interactive "FSave file: ") + (condition-case nil + (save-excursion + (set-buffer (create-file-buffer file)) + (malyon-disable-multibyte) + (malyon-erase-buffer) + (cond (table (malyon-save-table table length)) + (malyon-game-state-quetzal + (malyon-save-quetzal-state (malyon-current-game-state))) + (t + (malyon-save-game-state (malyon-current-game-state)))) + (let ((coding-system-for-write 'binary)) + (write-file file)) + (kill-buffer nil) + 1) + (error 0))) + +(defun malyon-save-table (table length) + "Save the given section of memory to the file." + (let ((i 0) + (j table)) + (while (< i length) + (malyon-write-byte-to-file (malyon-read-byte j)) + (setq i (+ 1 i) + j (+ 1 j))))) + +(defun malyon-save-game-state (state) + "Saves the game state to disk." + (let ((ip (aref state 0)) + (sp (aref state 1)) + (fp (aref state 2)) + (stack (aref state 3)) + (mem (aref state 4)) + (dyn (malyon-read-word 14)) + (i 0)) + (malyon-write-word-to-file (length malyon-story-file-name)) + (while (< i (length malyon-story-file-name)) + (malyon-write-byte-to-file (aref malyon-story-file-name i)) + (setq i (+ 1 i))) + (malyon-write-dword-to-file ip) + (malyon-write-word-to-file sp) + (malyon-write-word-to-file fp) + (malyon-write-word-to-file dyn) + (setq i 0) + (while (<= i sp) + (malyon-write-dword-to-file (aref stack i)) + (setq i (+ 1 i))) + (setq i 0) + (while (< i dyn) + (malyon-write-byte-to-file (aref mem i)) + (setq i (+ 1 i))))) + +(defun malyon-save-quetzal-state (state) + "Saves the game state to disk in quetzal format." + (goto-char (point-min)) + (malyon-save-quetzal-ifhd state) + (malyon-save-quetzal-cmem state) + (malyon-save-quetzal-stks state) + (goto-char (point-min)) + (malyon-write-chunk-id-to-file "IFZS") + (goto-char (point-min)) + (malyon-write-dword-to-file (- (point-max) (point-min))) + (goto-char (point-min)) + (malyon-write-chunk-id-to-file "FORM")) + +(defun malyon-save-quetzal-ifhd (state) + "Saves the IFhd chunk of the quetzal format." + (malyon-write-chunk-id-to-file "IFhd") + (malyon-write-dword-to-file 13) + (malyon-write-word-to-file (malyon-read-word 2)) + (malyon-write-word-to-file (malyon-read-word 18)) + (malyon-write-word-to-file (malyon-read-word 20)) + (malyon-write-word-to-file (malyon-read-word 22)) + (malyon-write-word-to-file (malyon-read-word 28)) + (malyon-write-byte-to-file (lsh (aref state 0) -16)) + (malyon-write-byte-to-file (lsh (aref state 0) -8)) + (malyon-write-byte-to-file (aref state 0)) + (malyon-write-byte-to-file 0)) + +(defun malyon-save-quetzal-cmem (state) + "Saves the CMem chunk of the quetzal format." + (let ((beginning (point-max)) + (original (aref malyon-game-state-restart 4)) + (current (aref state 4)) + (size (malyon-read-word 14)) + (byte 0) + (count 0) + (i 0)) + (goto-char (point-max)) + (while (< i size) + (setq byte (logxor (aref current i) (aref original i))) + (if (zerop byte) + (setq count (+ 1 count)) + (while (> count 0) + (malyon-write-byte-to-file 0) + (setq count (- count 1)) + (malyon-write-byte-to-file (min 255 count)) + (setq count (- count (min 255 count)))) + (malyon-write-byte-to-file byte)) + (setq i (+ 1 i))) + (setq size (- (point-max) beginning)) + (if (zerop (mod size 2)) '() (malyon-write-byte-to-file 0)) + (goto-char beginning) + (malyon-write-chunk-id-to-file "CMem") + (malyon-write-dword-to-file size))) + +(defun malyon-save-quetzal-stks (state) + "Saves the Stks chunk of the quetzal format." + (let ((beginning (point-max)) + (size 0)) + (goto-char (point-max)) + (malyon-save-quetzal-stack-frame (- (aref state 2) 4) + (aref state 1) + (aref state 3)) + (setq size (- (point-max) beginning)) + (if (zerop (mod size 2)) '() (malyon-write-byte-to-file 0)) + (goto-char beginning) + (malyon-write-chunk-id-to-file "Stks") + (malyon-write-dword-to-file size))) + +(defun malyon-save-quetzal-stack-frame (fp sp stack) + "Saves the stack frames for the Stks chunk." + (let* ((frame (malyon-get-stack-frame fp sp stack)) + (frame-id (aref frame 0)) + (previous-fp (aref frame 1)) + (previous-sp (aref frame 2)) + (return-addr (aref frame 3)) + (result-addr (aref frame 4)) + (local-vars (aref frame 5)) + (num-args (aref frame 6)) + (eval-stack (aref frame 7))) + (if (> frame-id 0) + (malyon-save-quetzal-stack-frame previous-fp previous-sp stack)) + (malyon-write-byte-to-file (lsh return-addr -16)) + (malyon-write-byte-to-file (lsh return-addr -8)) + (malyon-write-byte-to-file return-addr) + (if (zerop frame-id) + (malyon-write-byte-to-file 0) + (malyon-write-byte-to-file (logior (if result-addr 0 16) + (length local-vars)))) + (malyon-write-byte-to-file (if result-addr result-addr 0)) + (malyon-write-byte-to-file (- (lsh 1 num-args) 1)) + (malyon-write-word-to-file (length eval-stack)) + (while (not (null local-vars)) + (malyon-write-word-to-file (car local-vars)) + (setq local-vars (cdr local-vars))) + (while (not (null eval-stack)) + (malyon-write-word-to-file (car eval-stack)) + (setq eval-stack (cdr eval-stack))))) + +;; restoring data from disk + +(defvar malyon-restore-data-error nil + "An error message if restoring data from a file failed.") + +(defvar malyon-restore-quetzal-stack nil + "A temporary stack for restoring quetzal game states.") + +(defvar malyon-restore-quetzal-stack-pointer nil + "A temporary stack pointer for restoring quetzal game states.") + +(defvar malyon-restore-quetzal-frame-pointer nil + "A temporary frame-pointer for restoring quetzal game states.") + +(defun malyon-restore-file (file &optional table length) + "Restore a game state or a memory section from disk." + (interactive "fLoad file: ") + (if (not (and (file-exists-p file) (file-readable-p file))) + 0 + (condition-case nil + (save-excursion + (setq malyon-restore-data-error nil) + (set-buffer (create-file-buffer file)) + (malyon-disable-multibyte) + (malyon-erase-buffer) + (let ((coding-system-for-read 'binary)) + (insert-file-contents file)) + (goto-char (point-min)) + (if table + (malyon-restore-table table length) + (let* ((first (malyon-read-chunk-id-from-file)) + (second (malyon-read-dword-from-file)) + (third (malyon-read-chunk-id-from-file))) + (if (and (string= "FORM" first) (string= "IFZS" third)) + (malyon-restore-quetzal-state (+ 8 second)) + (goto-char (point-min)) + (malyon-restore-game-state)))) + (kill-buffer nil) + (if (null malyon-restore-data-error) + 2 + (message malyon-restore-data-error) + 0)) + (error 0)))) + +(defun malyon-restore-table (table length) + "Restore the given section of memory from a file." + (let ((i 0) + (j table)) + (while (< i length) + (malyon-store-byte j (malyon-read-byte-from-file)) + (setq i (+ 1 i) + j (+ 1 j))))) + +(defun malyon-restore-game-state () + "Restore a saved game state from disk." + (let ((len 0) + (name 0) + (story 0) + (ip 0) + (sp 0) + (fp 0) + (dyn 0) + (stack (copy-sequence malyon-stack)) + (mem (copy-sequence malyon-story-file)) + (i 0)) + (setq len (malyon-read-word-from-file)) + (setq name (make-string len ? )) + (while (< i len) + (aset name i (malyon-read-byte-from-file)) + (setq i (+ 1 i))) + (setq ip (malyon-read-dword-from-file)) + (setq sp (malyon-read-word-from-file)) + (setq fp (malyon-read-word-from-file)) + (setq dyn (malyon-read-word-from-file)) + (setq i 0) + (while (<= i sp) + (aset stack i (malyon-read-dword-from-file)) + (setq i (+ 1 i))) + (setq i 0) + (while (< i dyn) + (aset mem i (malyon-read-byte-from-file)) + (setq i (+ 1 i))) + (setq name (file-name-nondirectory name)) + (setq story (file-name-nondirectory malyon-story-file-name)) + (if (or (string-match name story) (string-match story name)) + (malyon-set-game-state (vector ip sp fp stack mem nil)) + (setq malyon-restore-data-error "Invalid save file.")))) + +(defun malyon-restore-quetzal-state (size) + "Restore a saved quetzal game state from disk." + (let ((chunk-id nil) + (chunk-len 0) + (ip 0) + (memory nil) + (stack nil) + (beginning 0)) + (while (< (point) size) + (setq chunk-id (malyon-read-chunk-id-from-file)) + (setq chunk-len (malyon-read-dword-from-file)) + (setq beginning (point)) + (cond ((string= chunk-id "IFhd") + (setq ip (malyon-restore-quetzal-ifhd chunk-len))) + ((string= chunk-id "CMem") + (setq memory (malyon-restore-quetzal-cmem chunk-len))) + ((string= chunk-id "UMem") + (setq memory (malyon-restore-quetzal-umem chunk-len))) + ((string= chunk-id "Stks") + (setq stack (malyon-restore-quetzal-stks chunk-len)))) + (if (zerop (mod chunk-len 2)) '() (setq chunk-len (+ 1 chunk-len))) + (goto-char (+ beginning chunk-len))) + (cond ((and ip memory stack) + (malyon-set-game-state (vector ip + (aref stack 0) + (aref stack 1) + (aref stack 2) + memory + t))) + ((null malyon-restore-data-error) + (setq malyon-restore-data-error "invalid quetzal file."))))) + +(defun malyon-restore-quetzal-ifhd (size) + "Restore an IFhd chunk from disk. Return the instruction pointer." + (if (and (= (malyon-read-word-from-file) (malyon-read-word 2)) + (= (malyon-read-word-from-file) (malyon-read-word 18)) + (= (malyon-read-word-from-file) (malyon-read-word 20)) + (= (malyon-read-word-from-file) (malyon-read-word 22)) + (= (malyon-read-word-from-file) (malyon-read-word 28))) + (logior (lsh (malyon-read-byte-from-file) 16) + (lsh (malyon-read-byte-from-file) 8) + (malyon-read-byte-from-file)) + (setq malyon-restore-data-error "quetzal file doesn't belong to game.") + nil)) + +(defun malyon-restore-quetzal-cmem (size) + "Restore a CMem chunk from disk. Return the entire memory layout." + (let ((memory (copy-sequence (aref malyon-game-state-restart 4))) + (max-size (+ (point) size)) + (byte 0) + (i 0)) + (while (< (point) max-size) + (setq byte (malyon-read-byte-from-file)) + (if (zerop byte) + (setq i (+ 1 i (malyon-read-byte-from-file))) + (aset memory i (logxor byte (aref memory i))) + (setq i (+ 1 i)))) + memory)) + +(defun malyon-restore-quetzal-umem (size) + "Restore a UMem chunk from disk. Return the entire memory layout." + (let ((memory (copy-sequence (aref malyon-game-state-restart 4))) + (i 0)) + (while (< i size) + (aset memory i (malyon-read-byte-from-file)) + (setq i (+ 1 i))) + memory)) + +(defun malyon-restore-quetzal-stks (size) + "Restore a Stks chunk from disk. Return a vector containing the +stack pointer, the frame pointer, and the stack itself." + (let ((i 0) (frame-id 0)) + (setq malyon-restore-quetzal-stack + (copy-sequence (aref malyon-game-state-restart 3))) + (setq malyon-restore-quetzal-stack-pointer -1) + (setq malyon-restore-quetzal-frame-pointer 2) + (while (< i size) + (let* ((beginning (point)) + (return3 (malyon-read-byte-from-file)) + (return2 (malyon-read-byte-from-file)) + (return1 (malyon-read-byte-from-file)) + (return-addr (logior (lsh return3 16) (lsh return2 8) return1)) + (result-locals (malyon-read-byte-from-file)) + (has-result (zerop (logand 16 result-locals))) + (num-locals (logand 15 result-locals)) + (result-addr (malyon-read-byte-from-file)) + (arg-flags (+ 1 (malyon-read-byte-from-file))) + (num-args 0) + (eval-size (malyon-read-word-from-file)) + (local-vars '()) + (eval-stack '())) + (while (> num-locals 0) + (setq local-vars (cons (malyon-read-word-from-file) local-vars)) + (setq num-locals (- num-locals 1))) + (while (> eval-size 0) + (setq eval-stack (cons (malyon-read-word-from-file) eval-stack)) + (setq eval-size (- eval-size 1))) + (while (> arg-flags 1) + (setq arg-flags (lsh arg-flags -1)) + (setq num-args (+ num-args 1))) + (malyon-push-stack-frame frame-id + return-addr + (if (zerop frame-id) + nil + (if has-result result-addr nil)) + (reverse local-vars) + num-args + (reverse eval-stack)) + (setq frame-id (+ 1 frame-id)) + (setq i (+ i (- (point) beginning))))) + (vector malyon-restore-quetzal-stack-pointer + malyon-restore-quetzal-frame-pointer + malyon-restore-quetzal-stack))) + +;; object table management + +(defsubst malyon-object-address (object) + "Compute the address at which the object is stored." + (+ malyon-object-table + (* 2 malyon-object-properties) + (* malyon-object-table-entry-size (- object 1)))) + +(defsubst malyon-object-read-parent (address) + "Return the parent." + (if (< malyon-story-version 5) + (malyon-read-byte (+ 4 address)) + (malyon-read-word (+ 6 address)))) + +(defsubst malyon-object-read-sibling (address) + "Return the next sibling." + (if (< malyon-story-version 5) + (malyon-read-byte (+ 5 address)) + (malyon-read-word (+ 8 address)))) + +(defsubst malyon-object-read-child (address) + "Return the first child." + (if (< malyon-story-version 5) + (malyon-read-byte (+ 6 address)) + (malyon-read-word (+ 10 address)))) + +(defsubst malyon-object-store-parent (address value) + "Set the parent." + (if (< malyon-story-version 5) + (malyon-store-byte (+ 4 address) value) + (malyon-store-word (+ 6 address) value))) + +(defsubst malyon-object-store-sibling (address value) + "Set the next sibling." + (if (< malyon-story-version 5) + (malyon-store-byte (+ 5 address) value) + (malyon-store-word (+ 8 address) value))) + +(defsubst malyon-object-store-child (address value) + "Set the first child." + (if (< malyon-story-version 5) + (malyon-store-byte (+ 6 address) value) + (malyon-store-word (+ 10 address) value))) + +(defun malyon-find-property (object property) + "Return the address of the object's property, or 0 if it doesn't exist." + (let ((next (malyon-first-property object)) + (number 0)) + (setq number (logand (malyon-read-byte next) malyon-object-properties)) + (while (> number property) + (setq next (malyon-next-property next)) + (setq number (logand (malyon-read-byte next) malyon-object-properties))) + (if (= number property) next 0))) + +(defun malyon-first-property (object) + "Get the address of the object's first property." + (let ((header (malyon-read-word (+ malyon-object-property-offset + (malyon-object-address object))))) + (+ header 1 (* 2 (malyon-read-byte header))))) + +(defun malyon-next-property (property) + "Get the address of the following property." + (let ((size (malyon-read-byte property)) + (addr (+ property 1))) + (+ 1 addr (cond ((< malyon-story-version 5) (lsh size -5)) + ((zerop (logand 128 size)) (lsh size -6)) + (t + (let ((second (logand 63 (malyon-read-byte addr)))) + (if (= 0 second) 64 second))))))) + +(defun malyon-remove-object (object) + "Remove the object from the children list of its parent." + (let* ((address (malyon-object-address object)) + (parent (malyon-object-read-parent address)) + (sibling (malyon-object-read-sibling address))) + (malyon-object-store-parent address 0) + (malyon-object-store-sibling address 0) + (if (/= parent 0) + (let ((parent-addr (malyon-object-address parent))) + (let ((children (malyon-object-read-child parent-addr))) + (if (or (= children 0) (= children object)) + (malyon-object-store-child parent-addr sibling) + (let ((this (malyon-object-address children))) + (let ((next (malyon-object-read-sibling this))) + (while (/= next object) + (setq this (malyon-object-address next)) + (setq next (malyon-object-read-sibling this))) + (malyon-object-store-sibling this sibling))))))))) + +;; function calls and code branches + +(defun malyon-call-routine (routine arguments &optional result) + "Call a routine with the given arguments and return its result." + (if (= routine 0) + (if result (malyon-store-variable result 0) 0) + (malyon-push-stack (if result 0 1)) + (malyon-push-stack (if result result 0)) + (malyon-push-stack malyon-instruction-pointer) + (malyon-push-stack + (logior (lsh (- malyon-stack-pointer malyon-frame-pointer) 8) + (length arguments))) + (setq malyon-instruction-pointer (* malyon-packed-multiplier routine)) + (let ((args (malyon-read-code-byte)) (value nil)) + (if malyon-game-state-quetzal + (let ((id (lsh (aref malyon-stack malyon-frame-pointer) -8))) + (malyon-push-stack (logior (lsh (+ 1 id) 8) args)))) + (setq malyon-frame-pointer malyon-stack-pointer) + (while (> args 0) + (setq value (if (< malyon-story-version 5) (malyon-read-code-word) 0)) + (malyon-push-stack (if (null arguments) value (car arguments))) + (setq arguments (cdr arguments)) + (setq args (- args 1)))))) + +(defun malyon-jump-if (condition) + "Jump depending on the condition and the following jump data." + (let ((byte (malyon-read-code-byte)) + (offset nil) + (iftrue nil)) + (setq iftrue (/= 0 (logand byte 128))) + (setq offset (logand byte 63)) + (if (= 0 (logand byte 64)) + (progn + (setq offset (logior (lsh offset 8) (malyon-read-code-byte))) + (if (>= offset 8192) (setq offset (- offset 16384))))) + (if (or (and iftrue condition) (and (not iftrue) (not condition))) + (progn + (cond ((= offset 0) (malyon-opcode-rfalse)) + ((= offset 1) (malyon-opcode-rtrue)) + (t (setq + malyon-instruction-pointer + (+ malyon-instruction-pointer offset -2)))))))) + +(defun malyon-return (value) + "Return from a routine." + (setq malyon-stack-pointer malyon-frame-pointer) + (if malyon-game-state-quetzal (malyon-pop-stack)) + (setq malyon-frame-pointer + (- malyon-stack-pointer 1 (lsh (malyon-pop-stack) -8))) + (setq malyon-instruction-pointer (malyon-pop-stack)) + (let ((result (malyon-pop-stack)) + (store (malyon-pop-stack))) + (if (zerop store) + (malyon-return-store result value) + (malyon-return-ignore result value)))) + +(defun malyon-return-ignore (where value) + "Return from a routine ignoring the result.") + +(defun malyon-return-store (where value) + "Return from a routine storing the result." + (malyon-store-variable where value)) + +(defun malyon-push-initial-frame () + "Push the initial stack frame required in quetzal mode." + (if malyon-game-state-quetzal + (progn + (malyon-push-stack 1) + (malyon-push-stack 0) + (malyon-push-stack 0) + (malyon-push-stack 0) + (malyon-push-stack 0)))) + +(defun malyon-get-stack-frame (fp sp stack) + "Return a decoded stack frame in quetzal mode. +The result is a vector containing the frame id, the fp of the +previous frame, the sp of the previous frame, the return address, +the result variable if any, a list of local variables, the number +of arguments, and a list of the evaluation stack elements." + (let* ((has-result (zerop (aref stack fp))) + (result-addr (if has-result (aref stack (+ 1 fp)) nil)) + (return-addr (aref stack (+ 2 fp))) + (offset (lsh (aref stack (+ 3 fp)) -8)) + (num-args (logand 255 (aref stack (+ 3 fp)))) + (frame-id (lsh (aref stack (+ 4 fp)) -8)) + (num-locals (logand 255 (aref stack (+ 4 fp)))) + (start-locals (+ 5 fp)) + (start-eval (+ 5 fp num-locals)) + (local-vars '()) + (eval-stack '())) + (if (not (zerop num-locals)) + (setq local-vars + (malyon-vector-to-list stack start-locals start-eval))) + (if (> sp start-eval) + (setq eval-stack + (malyon-vector-to-list stack start-eval (+ 1 sp)))) + (vector frame-id + (- fp offset 2) + (- fp 1) + return-addr + result-addr + local-vars + num-args + eval-stack))) + +(defsubst malyon-restore-quetzal-push-stack (value) + "Push a value onto the restore quetzal stack." + (setq malyon-restore-quetzal-stack-pointer + (+ malyon-restore-quetzal-stack-pointer 1)) + (aset malyon-restore-quetzal-stack + malyon-restore-quetzal-stack-pointer + value)) + +(defun malyon-push-stack-frame + (frame-id return-addr result local-vars num-args eval-stack) + "Pushes a new stack frame in quetzal mode." + (malyon-restore-quetzal-push-stack (if result 0 1)) + (malyon-restore-quetzal-push-stack (if result result 0)) + (malyon-restore-quetzal-push-stack return-addr) + (malyon-restore-quetzal-push-stack + (logior (lsh (- malyon-restore-quetzal-stack-pointer + malyon-restore-quetzal-frame-pointer) 8) + num-args)) + (malyon-restore-quetzal-push-stack + (logior (lsh frame-id 8) (length local-vars))) + (setq malyon-restore-quetzal-frame-pointer + malyon-restore-quetzal-stack-pointer) + (while (not (null local-vars)) + (malyon-restore-quetzal-push-stack (car local-vars)) + (setq local-vars (cdr local-vars))) + (while (not (null eval-stack)) + (malyon-restore-quetzal-push-stack (car eval-stack)) + (setq eval-stack (cdr eval-stack)))) + +;; other stuff + +(defvar malyon-aread-text nil + "Text buffer for user input.") + +(defvar malyon-aread-parse nil + "Parse buffer for user input.") + +(defvar malyon-aread-beginning-of-line nil + "The beginning of the input line.") + +;; execution + +(defun malyon-interpreter () + "Run the z code interpreter on the given story file." +; (condition-case nil + (progn + (malyon-restore-window-configuration) + (if malyon-story-file + (catch 'malyon-end-of-interpreter-loop + (setq malyon-last-cursor-position-after-input + (malyon-point-max malyon-transcript-buffer)) + (malyon-execute)))) +; (error +; (malyon-fatal-error "unspecified internal runtime error.")))) +) +(defsubst malyon-fetch-variable-operands (specifier) + "Fetch a variable number of operands based on the specifier argument." + (let ((var (logand specifier 49152)) + (op '())) + (setq specifier (logand 65535 specifier)) + (while (/= 0 specifier) + (cond ((= var 0) (setq op (cons (malyon-read-code-word) op))) + ((= var 16384) (setq op (cons (malyon-read-code-byte) op))) + ((= var 32768) (setq op (cons (malyon-read-variable + (malyon-read-code-byte)) op))) + (t (setq specifier 0))) + (setq specifier (logand 65535 (lsh specifier 2))) + (setq var (logand specifier 49152))) + (nreverse op))) + +(defsubst malyon-fetch-extended (opcode) + "Fetch operands for an extended instruction." + (malyon-fetch-variable-operands + (logior (lsh (malyon-read-code-byte) 8) 255))) + +(defsubst malyon-fetch-variable (opcode) + "Fetch operands for a variable instruction." + (malyon-fetch-variable-operands + (if (or (= opcode 236) (= opcode 250)) + (malyon-read-code-word) + (logior (lsh (malyon-read-code-byte) 8) 255)))) + +(defsubst malyon-fetch-short (opcode) + "Fetch operands for a short instruction." + (let ((op (logand opcode 48))) + (cond ((= op 0) (list (malyon-read-code-word))) + ((= op 16) (list (malyon-read-code-byte))) + ((= op 32) (list (malyon-read-variable (malyon-read-code-byte))))))) + +(defsubst malyon-fetch-long (instr) + "Fetch operands for a long instruction." + (let ((byte1 (malyon-read-code-byte)) + (byte2 (malyon-read-code-byte))) + (list (if (= (logand instr 64) 0) byte1 (malyon-read-variable byte1)) + (if (= (logand instr 32) 0) byte2 (malyon-read-variable byte2))))) + +(defun malyon-execute () + "Execute z code instructions. +Load the next instruction opcode and its operands and execute it. +Repeat ad infinitum." + (let ((opcode) (operands)); (pc)) + (while t +; (setq pc malyon-instruction-pointer) + (setq opcode (malyon-read-code-byte)) + (setq operands (cond ((= opcode 190) + (setq opcode (+ 256 (malyon-read-code-byte))) + (malyon-fetch-extended opcode)) + ((>= opcode 192) + (malyon-fetch-variable opcode)) + ((>= opcode 128) + (malyon-fetch-short opcode)) + (t + (malyon-fetch-long opcode)))) +; (malyon-trace-opcode pc opcode operands) + (apply (aref malyon-opcodes opcode) operands)))) + +;; opcodes + +(defsubst malyon-number (n) + "Convert an unsigned number into a signed one." + (if (< n 32768) n (- n 65536))) + +(defun malyon-opcode-add (a b) + "Addition." + (malyon-store-variable (malyon-read-code-byte) + (+ (malyon-number a) (malyon-number b)))) + +(defun malyon-opcode-and (a b) + "Bitwise and." + (malyon-store-variable (malyon-read-code-byte) (logand a b))) + +(defun malyon-opcode-aread (text parse &optional time routine) + "Read input text." + (setq malyon-aread-text text) + (setq malyon-aread-parse parse) + (goto-char (point-max)) + (setq malyon-aread-beginning-of-line (point)) +; Some games violate these assumptions for the "Quit" question. +; (if (> 3 (malyon-read-byte text)) +; (malyon-fatal-error "text buffer less than 3 bytes.")) +; (if (and (not (zerop parse)) (> 2 (malyon-read-byte parse))) +; (malyon-fatal-error "parse buffer less than 2 bytes.")) + (malyon-more malyon-keymap-read) + (throw 'malyon-end-of-interpreter-loop 'malyon-waiting-for-input)) + +(defun malyon-opcode-art-shift (value places) + "Arithmetic shift." + (malyon-store-variable (malyon-read-code-byte) (ash value places))) + +(defun malyon-opcode-buffer-mode (mode) + "Toggles buffering of text in the transcript window." + (setq malyon-transcript-buffer-buffered (/= 0 mode))) + +(defun malyon-opcode-calln (routine &rest arguments) + "Call a routine and ignore the result." + (malyon-call-routine routine arguments)) + +(defun malyon-opcode-calls (routine &rest arguments) + "Call a routine and store the result." + (malyon-call-routine routine arguments (malyon-read-code-byte))) + +(defun malyon-opcode-catch () + "Return the current stack frame." + (malyon-store-variable + (malyon-read-code-byte) + (if malyon-game-state-quetzal + (lsh (aref malyon-stack malyon-frame-pointer) -8) + malyon-frame-pointer))) + +(defun malyon-opcode-check-arg-count (count) + "Tests the number of arguments passed to routine." + (malyon-jump-if + (<= count (logand 255 (aref malyon-stack + (if malyon-game-state-quetzal + (- malyon-frame-pointer 1) + malyon-frame-pointer)))))) + +(defun malyon-opcode-check-unicode (char) + "Check whether the given character is valid for input/output." + (malyon-store-variable (malyon-read-code-byte) 0)) + +(defun malyon-opcode-clear-attr (object attribute) + "Clear the given attribute in the given object." + (let ((attributes (malyon-object-address object)) + (byte (lsh attribute -3))) + (malyon-store-byte (+ attributes byte) + (logand (malyon-read-byte (+ attributes byte)) + (logxor (lsh 128 (- (logand attribute 7))) + 255))))) + +(defun malyon-opcode-copy-table (first second size) + "Copies first table onto second one." + (let* ((length (abs (malyon-number size))) + (zero (zerop second)) + (forward (or (< (malyon-number size) 0) (> first second))) + (i 0) + (a (if forward first (+ first length -1))) + (b (if forward (if zero first second) (+ second length -1)))) + (while (< i length) + (malyon-store-byte b (if zero 0 (malyon-read-byte a))) + (setq i (+ i 1) + a (if forward (+ a 1) (- a 1)) + b (if forward (+ b 1) (- b 1)))))) + +(defun malyon-opcode-dec (var) + "Decrement variable." + (malyon-store-variable var + (- (malyon-number (malyon-read-variable var)) 1))) + +(defun malyon-opcode-dec-chk (variable threshold) + "Decrement variable and jump if it's less than the given value." + (let ((value (malyon-number (malyon-read-variable variable)))) + (malyon-store-variable variable (- value 1)) + (malyon-jump-if (< (- value 1) (malyon-number threshold))))) + +(defun malyon-opcode-div (a b) + "Division." + (if (zerop b) (malyon-fatal-error "division by 0.")) + (malyon-store-variable (malyon-read-code-byte) + (/ (malyon-number a) (malyon-number b)))) + +(defun malyon-opcode-encode-text (text length from encoded) + "Encode the zscii text starting at from with the given length. +The result is stored at encoded." + (let* ((i length) + (j encoded) + (l '()) + (word '())) + (while (< 0 i) + (setq l (cons (malyon-read-byte (+ text from i -1)) l) + i (- i 1))) + (setq word (malyon-encode-dictionary-word + (append (malyon-mapcan 'malyon-encode-into-ztext l) + '(5 5 5 5 5 5 5 5)))) + (while (< i 6) + (malyon-store-byte j (car l)) + (setq i (+ 1 i) + j (+ 1 j) + l (cdr word))))) + +(defun malyon-opcode-erase-line (value) + "Erases the rest of the line." + (if (= value 1) + (if (eq malyon-transcript-buffer (current-buffer)) + (kill-line nil) + (save-excursion + (let ((i (current-column))) + (while (<= i malyon-max-column) + (insert ? ) + (delete-char 1) + (setq i (+ 1 i)))))))) + +(defun malyon-opcode-erase-window (window) + "Erase the contents of the given window." + (save-excursion + (let ((w (malyon-number window))) + (if (or (= w 0) (= w -1) (= w -2)) + (malyon-erase-buffer malyon-transcript-buffer)) + (if (or (= w 1) (= w -1) (= w -2)) + (malyon-erase-buffer malyon-status-buffer)) + (if (= w -1) + (malyon-split-buffer-windows 0))) + (setq malyon-last-cursor-position-after-input + (malyon-point-max malyon-transcript-buffer)))) + +(defun malyon-opcode-get-child (object) + "Get the first child of the given object and jump." + (let ((child (malyon-object-read-child (malyon-object-address object)))) + (malyon-store-variable (malyon-read-code-byte) child) + (malyon-jump-if (/= 0 child)))) + +(defun malyon-opcode-get-cursor (array) + "Retrieves the current cursor position." + (save-excursion + (set-buffer malyon-status-buffer) + (malyon-store-word array (- (count-lines (point-min) (point)) 1)) + (malyon-store-word (+ 2 array) (+ 1 (current-column))))) + +(defun malyon-opcode-get-next-prop (object property) + "Retrieve the first or next property id of object." + (let ((next (malyon-first-property object)) + (number 0)) + (if (zerop property) + '() + (setq number (logand (malyon-read-byte next) + malyon-object-properties)) + (setq next (malyon-next-property next)) + (while (> number property) + (setq number (logand (malyon-read-byte next) + malyon-object-properties)) + (setq next (malyon-next-property next))) + (if (/= number property) + (malyon-fatal-error "property does not exist."))) + (setq number (logand (malyon-read-byte next) malyon-object-properties)) + (malyon-store-variable (malyon-read-code-byte) number))) + +(defun malyon-opcode-get-parent (object) + "Get the parent of the given object." + (malyon-store-variable (malyon-read-code-byte) + (malyon-object-read-parent + (malyon-object-address object)))) + +(defun malyon-opcode-get-prop (object property) + "Get the value of the object's property." + (let* ((address (malyon-find-property object property)) + (size (malyon-read-byte address))) + (malyon-store-variable + (malyon-read-code-byte) + (cond ((zerop address) + (malyon-read-word (+ malyon-object-table (* 2 (- property 1))))) + ((and (< malyon-story-version 5) (zerop (lsh size -5))) + (malyon-read-byte (+ address 1))) + ((and (>= malyon-story-version 5) (zerop (logand 192 size))) + (malyon-read-byte (+ address 1))) + (t + (malyon-read-word (+ address 1))))))) + +(defun malyon-opcode-get-prop-addr (object property) + "Get the address of the object's property." + (let* ((address (malyon-find-property object property)) + (size (malyon-read-byte address)) + (offset (if (< malyon-story-version 5) + 1 + (if (zerop (logand 128 size)) 1 2)))) + (malyon-store-variable (malyon-read-code-byte) + (if (zerop address) 0 (+ address offset))))) + +(defun malyon-opcode-get-prop-len (property) + "Get the length of the object's property." + (let ((size (malyon-read-byte (- property 1)))) + (malyon-store-variable + (malyon-read-code-byte) + (cond ((< malyon-story-version 5) (+ 1 (lsh size -5))) + ((zerop (logand 128 size)) (+ 1 (lsh size -6))) + ((zerop (logand 63 size)) 64) + (t (logand 63 size)))))) + +(defun malyon-opcode-get-sibling (object) + "Get the next object in the tree and jump." + (let ((sibling (malyon-object-read-sibling (malyon-object-address object)))) + (malyon-store-variable (malyon-read-code-byte) sibling) + (malyon-jump-if (/= 0 sibling)))) + +(defun malyon-opcode-illegal (&rest ignore) + "Print an error message and exit the interpreter." + (malyon-fatal-error "illegal opcode.")) + +(defun malyon-opcode-inc (var) + "Increment variable." + (malyon-store-variable var + (+ (malyon-number (malyon-read-variable var)) 1))) + +(defun malyon-opcode-inc-chk (variable threshold) + "Increment variable and jump if it's greater than the given value." + (let ((value (malyon-number (malyon-read-variable variable)))) + (malyon-store-variable variable (+ value 1)) + (malyon-jump-if (> (+ value 1) (malyon-number threshold))))) + +(defun malyon-opcode-input-stream (number) + "Select the given input stream. Only the keyboard is supported." + (if (zerop (malyon-number number)) + '() + (message "Only the keyboard is supported as an input stream."))) + +(defun malyon-opcode-insert-obj (object destination) + "Insert an object into the children list of another." + (let ((child (malyon-object-address object)) + (parent (malyon-object-address destination))) + (malyon-remove-object object) + (malyon-object-store-parent child destination) + (malyon-object-store-sibling child (malyon-object-read-child parent)) + (malyon-object-store-child parent object))) + +(defun malyon-opcode-je (a &rest rest) + "Jump if first operand equals any of the following." + (malyon-jump-if (member (malyon-number a) (mapcar 'malyon-number rest)))) + +(defun malyon-opcode-jg (a b) + "Jump if first operand > second operand." + (malyon-jump-if (> (malyon-number a) (malyon-number b)))) + +(defun malyon-opcode-jin (child parent) + "Jump if second object is parent of the first one." + (malyon-jump-if + (= parent (malyon-object-read-parent (malyon-object-address child))))) + +(defun malyon-opcode-jl (a b) + "Jump if first operand < second operand." + (malyon-jump-if (< (malyon-number a) (malyon-number b)))) + +(defun malyon-opcode-jump (offset) + "Jump unconditionally." + (setq malyon-instruction-pointer (+ malyon-instruction-pointer + (malyon-number offset) -2))) + +(defun malyon-opcode-jz (a) + "Jump if operand = 0." + (malyon-jump-if (zerop a))) + +(defun malyon-opcode-load (variable) + "Load a variable." + (malyon-store-variable (malyon-read-code-byte) + (malyon-read-variable variable))) + +(defun malyon-opcode-loadb (array index) + "Load an array element into a variable." + (malyon-store-variable (malyon-read-code-byte) + (malyon-read-byte (+ array index)))) + +(defun malyon-opcode-loadw (array index) + "Load an array element into a variable." + (malyon-store-variable (malyon-read-code-byte) + (malyon-read-word (+ array (* 2 index))))) + +(defun malyon-opcode-log-shift (value places) + "Logical shift." + (malyon-store-variable (malyon-read-code-byte) (lsh value places))) + +(defun malyon-opcode-mod (a b) + "Modulo." + (malyon-store-variable (malyon-read-code-byte) + (mod (malyon-number a) (malyon-number b)))) + +(defun malyon-opcode-mul (a b) + "Multiplication." + (malyon-store-variable (malyon-read-code-byte) + (* (malyon-number a) (malyon-number b)))) + +(defun malyon-opcode-new-line () + "Print a newline." + (malyon-newline)) + +(defun malyon-opcode-nop (&rest ignore) + "Do nothing.") + +(defun malyon-opcode-not (a) + "Bitwise not." + (malyon-store-variable (malyon-read-code-byte) (logand 65535 (lognot a)))) + +(defun malyon-opcode-or (a b) + "Bitwise or." + (malyon-store-variable (malyon-read-code-byte) (logior a b))) + +(defun malyon-opcode-output-stream (stream &optional table) + "Select an output stream." + (let ((stream (malyon-number stream))) + (cond ((< 0 stream) (malyon-add-output-stream stream table)) + ((> 0 stream) (malyon-remove-output-stream (- stream)))))) + +(defun malyon-opcode-piracy () + "Piracy check, effectively an unconditional jump." + (malyon-jump-if 1)) + +(defun malyon-opcode-print () + "Print a string." + (setq malyon-instruction-pointer + (malyon-print-text malyon-instruction-pointer))) + +(defun malyon-opcode-print-addr (address) + "Print a string." + (malyon-print-text address)) + +(defun malyon-opcode-print-char (c) + "Print a character." + (malyon-print (char-to-string c))) + +(defun malyon-opcode-print-num (n) + "Print a number." + (malyon-print (number-to-string (malyon-number n)))) + +(defun malyon-opcode-print-obj (obj) + "Print the short name of the object." + (malyon-print-text + (+ 1 (malyon-read-word (+ malyon-object-property-offset + (malyon-object-address obj)))))) + +(defun malyon-opcode-print-paddr (address) + "Print a string." + (malyon-print-text (* malyon-packed-multiplier address))) + +(defun malyon-opcode-print-ret () + "Print a string, print a newline, return true/1." + (setq malyon-instruction-pointer + (malyon-print-text malyon-instruction-pointer)) + (malyon-newline) + (malyon-return 1)) + +(defun malyon-opcode-print-table (text width &optional height skip) + "Print the given table." + (if (not height) (setq height 1)) + (if (not skip) (setq skip 0)) + (let ((column (current-column)) + (address text) + (y 0) + (x 0)) + (while (< y height) + (if (zerop y) + '() + (malyon-newline) + (malyon-print-characters (make-string column ? ))) + (setq x 0) + (while (< x width) + (malyon-output-character (malyon-read-byte address)) + (setq address (+ 1 address)) + (setq x (+ 1 x))) + (setq address (+ skip address)) + (setq y (+ 1 y))))) + +(defun malyon-opcode-print-unicode (char) + "Prints a unicode character.") + +(defun malyon-opcode-pull (variable) + "Pull value off stack." + (malyon-store-variable variable (malyon-pop-stack))) + +(defun malyon-opcode-push (value) + "Push value onto stack." + (malyon-push-stack value)) + +(defun malyon-opcode-put-prop (object property value) + "Set the object's property to the given value." + (let* ((address (malyon-find-property object property)) + (size (malyon-read-byte address))) + (cond ((= address 0) + (malyon-fatal-error "property does not exist.")) + ((and (< malyon-story-version 5) (zerop (lsh size -5))) + (malyon-store-byte (+ 1 address) (logand 255 value))) + ((and (>= malyon-story-version 5) (zerop (logand size 192))) + (malyon-store-byte (+ 1 address) (logand 255 value))) + (t + (malyon-store-word (+ 1 address) value))))) + +(defun malyon-opcode-quit () + "End the game immediately." + (malyon-adjust-transcript) + (malyon-cleanup) + (throw 'malyon-end-of-interpreter-loop 'malyon-opcode-quit)) + +(defun malyon-opcode-random (limit) + "Generate a random number or set the seed value." + (malyon-store-variable (malyon-read-code-byte) + (if (>= 0 (malyon-number limit)) + 0 + (+ 1 (random (malyon-number limit)))))) + +(defun malyon-opcode-read-char (&optional device &rest ignore) + "Read a character." + (if (and device (/= 1 device)) + (malyon-fatal-error "illegal device specified in read_char.")) + (if (eq malyon-transcript-buffer (current-buffer)) + (goto-char (point-max))) + (message "[Press a key.]") + (malyon-more malyon-keymap-readchar) + (throw 'malyon-end-of-interpreter-loop 'malyon-waiting-for-character)) + +(defun malyon-opcode-remove-obj (object) + "Remove an object from its parent's children list." + (malyon-remove-object object)) + +(defun malyon-opcode-restart () + "Restart the game." + (malyon-set-game-state malyon-game-state-restart)) + +(defun malyon-opcode-restore (&optional table bytes name) + "Restore a saved game state or a section of memory from a file." + (let ((result (if name + (malyon-restore-file + (malyon-get-file-name name) table bytes) + (call-interactively 'malyon-restore-file)))) + (if (< malyon-story-version 5) + (malyon-jump-if (not (zerop result))) + (malyon-store-variable (malyon-read-code-byte) result)))) + +(defun malyon-opcode-restore-undo () + "Restore game state for undo." + (if malyon-game-state-undo + (malyon-set-game-state malyon-game-state-undo)) + (malyon-store-variable (malyon-read-code-byte) 2)) + +(defun malyon-opcode-ret (value) + "Return a value." + (malyon-return value)) + +(defun malyon-opcode-ret-popped () + "Return top of stack." + (malyon-return (malyon-pop-stack))) + +(defun malyon-opcode-rfalse () + "Return false/0." + (malyon-return 0)) + +(defun malyon-opcode-rtrue () + "Return true/1." + (malyon-return 1)) + +(defun malyon-opcode-save (&optional table bytes name) + "Save the current game state or a section of memory to a file." + (let ((result (if name + (malyon-save-file (malyon-get-file-name name) table bytes) + (call-interactively 'malyon-save-file)))) + (if (< malyon-story-version 5) + (malyon-jump-if (not (zerop result))) + (malyon-store-variable (malyon-read-code-byte) result)))) + +(defun malyon-opcode-save-undo () + "Save game state for undo." + (setq malyon-game-state-undo (malyon-current-game-state)) + (malyon-store-byte (malyon-read-code-byte) 1)) + +(defun malyon-opcode-scan-table (x table len &optional form) + "Scan the given table for the first occurrence of x." + (if (not form) (setq form 130)) + (let ((inc (logand 127 form)) + (byte (zerop (logand 128 form))) + (addr table) + (found 0) + (index 0)) + (while (and (zerop found) (< index len)) + (setq found + (if byte + (if (= x (malyon-read-byte addr)) addr 0) + (if (= x (malyon-read-word addr)) addr 0))) + (setq addr (+ addr inc)) + (setq index (+ index 1))) + (malyon-store-variable (malyon-read-code-byte) found) + (malyon-jump-if (not (zerop found))))) + +(defun malyon-opcode-set-attr (object attribute) + "Set the given attribute in the given object." + (let ((attributes (malyon-object-address object)) + (byte (lsh attribute -3))) + (malyon-store-byte (+ attributes byte) + (logior (malyon-read-byte (+ attributes byte)) + (lsh 128 (- (logand attribute 7))))))) + +(defun malyon-opcode-set-color (foreground background) + "Sets the fore- and background colors ie. does nothing.") + +(defun malyon-opcode-set-cursor (&optional line column) + "Set the cursor." + (if (eq malyon-transcript-buffer (current-buffer)) + (goto-char (point-max)) + (if malyon-status-buffer-delayed-split + (progn + (malyon-split-buffer-windows malyon-status-buffer-delayed-split) + (other-window 1))) + (if line '() (setq line (count-lines (point-min) (point)))) + (if column '() (setq column (current-column))) + (if (> line malyon-status-buffer-lines) + (progn + (malyon-split-buffer-windows line) + (other-window 1))) + (goto-char (point-min)) + (if (and (<= 1 line) (<= line malyon-status-buffer-lines)) + (forward-line line) + (beginning-of-line)) + (if (and (<= 1 column) (<= column malyon-max-column)) + (forward-char (- column 1)) + (beginning-of-line)) + (setq malyon-status-buffer-point (point)))) + +(defun malyon-opcode-set-font (font) + "Sets the font if available or 0 otherwise." + (malyon-store-variable (malyon-read-code-byte) 0)) + +(defun malyon-opcode-set-text-style (style) + "Set the text style/face." + (let ((face (assq style malyon-faces))) + (setq malyon-current-face (if face (cdr face) 'malyon-face-plain)))) + +(defun malyon-opcode-set-window (window) + "Set the current window." + (malyon-restore-window-configuration) + (setq malyon-current-window window) + (malyon-update-output-streams) + (if (zerop window) + (if (not (eq malyon-transcript-buffer (current-buffer))) + (other-window 1)) + (if (not (eq malyon-status-buffer (current-buffer))) + (other-window 1)) + (malyon-opcode-set-cursor 1 1))) + +(defun malyon-opcode-show-status () + "Display the status line." + (save-excursion + (malyon-opcode-split-window 1) + (malyon-restore-window-configuration) + (malyon-opcode-set-window 1) + (malyon-prepare-status-buffer 1) + (malyon-opcode-set-cursor 1 1) + (malyon-opcode-print-obj (malyon-read-global-variable 0)) + (if (<= (current-column) (- (current-fill-column) 10)) + (let* ((x (malyon-read-global-variable 1)) + (y (malyon-read-global-variable 2)) + (hours (if (> x 12) (- x 12) x)) + (ampm (if (> x 12) "PM" "AM")) + (score (format "%4d/%4d" x y)) + (time (format "%02d:%02d%s" hours y ampm))) + (malyon-opcode-set-cursor 1 (- (current-fill-column) 10)) + (malyon-print (if malyon-score-game score time)))) + (malyon-opcode-set-window 0) + (malyon-adjust-transcript))) + +(defun malyon-opcode-split-window (size) + "Split upper and lower window." + (malyon-set-window-configuration size)) + +(defun malyon-opcode-store (variable value) + "Store a value in a variable." + (malyon-store-variable variable value)) + +(defun malyon-opcode-storeb (array index value) + "Store a value in an array at the given index." + (malyon-store-byte (+ array index) value)) + +(defun malyon-opcode-storew (array index value) + "Store a value in an array at the given index." + (malyon-store-word (+ array (* 2 index)) value)) + +(defun malyon-opcode-sub (a b) + "Subtraction." + (malyon-store-variable (malyon-read-code-byte) + (- (malyon-number a) (malyon-number b)))) + +(defun malyon-opcode-test (bitmap flags) + "Test if all of the flags are set in the bitmap." + (malyon-jump-if (= flags (logand bitmap flags)))) + +(defun malyon-opcode-test-attr (object attribute) + "Jump depending on the given attribute in the given object." + (malyon-jump-if + (/= 0 (logand (malyon-read-byte (+ (malyon-object-address object) + (lsh attribute -3))) + (lsh 128 (- (logand attribute 7))))))) + +(defun malyon-opcode-throw (value frame) + "Return from the given stack frame." + (if malyon-game-state-quetzal + (let ((id (lsh (aref malyon-stack malyon-frame-pointer) -8))) + (while (/= frame id) + (setq malyon-stack-pointer malyon-frame-pointer) + (malyon-pop-stack) + (setq malyon-frame-pointer + (- malyon-stack-pointer 1 (lsh (malyon-pop-stack) -8))) + (malyon-pop-stack) + (malyon-pop-stack) + (setq id (lsh (aref malyon-stack malyon-frame-pointer) -8)))) + (setq malyon-frame-pointer frame)) + (malyon-return value)) + +(defun malyon-opcode-tokenise (text parse &optional dict flag) + "Perform lexical analysis on the text buffer." + (let* ((words (malyon-text-to-words text dict)) + (word (car words)) + (start (car word)) + (len (malyon-cadr word)) + (code (malyon-caddr word)) + (entry (malyon-lookup dict code)) + (i 0)) + (while (not (or (null words) (= i (malyon-read-byte parse)))) + (if (and (zerop entry) flag (/= 0 flag)) + '() + (malyon-store-word (+ 2 parse (* 4 i)) entry) + (malyon-store-byte (+ 4 parse (* 4 i)) len) + (malyon-store-byte (+ 5 parse (* 4 i)) start)) + (setq words (cdr words) + word (car words) + start (car word) + len (malyon-cadr word) + code (malyon-caddr word) + entry (malyon-lookup dict code) + i (+ 1 i))) + (malyon-store-byte (+ 1 parse) i))) + +(defun malyon-opcode-verify () + "Verify the correctness of the story file." + (let ((length (+ 1 (* malyon-packed-multiplier (malyon-read-word 26)))) + (sum 0) + (i 64)) + (while (< i length) + (setq sum (mod (+ sum (malyon-read-byte i)) 65536) + i (+ 1 i))) + (malyon-jump-if (= (malyon-read-word 28) sum)))) + +;; keymap utilities + +(defun malyon-end-input () + "Store the input line in a text buffer and perform lexical analysis." + (interactive) + (condition-case nil + (progn + (malyon-adjust-transcript) + (switch-to-buffer malyon-transcript-buffer) + (goto-char (point-max)) + (let* ((input (downcase + (buffer-substring-no-properties + (if (< malyon-aread-beginning-of-line (point)) + malyon-aread-beginning-of-line + (point)) + (point)))) + (vec (malyon-string-to-vector input)) + (text (apply 'vector (mapcar 'malyon-unicode-to-zscii vec))) + (len (min (malyon-read-byte malyon-aread-text) (length text))) + (i 0)) + (malyon-history-insert input) + (if (>= malyon-story-version 5) + (malyon-store-byte (+ malyon-aread-text 1) len)) + (while (< i len) + (malyon-store-byte + (+ malyon-aread-text (if (< malyon-story-version 5) 1 2) i) + (malyon-char-to-int (aref text i))) + (setq i (+ 1 i))) + (if (< malyon-story-version 5) + (malyon-store-byte (+ malyon-aread-text 1 len) 0))) + (if (/= 0 malyon-aread-parse) + (malyon-opcode-tokenise malyon-aread-text malyon-aread-parse)) + (newline) + (if (>= malyon-story-version 5) + (malyon-store-variable (malyon-read-code-byte) 10)) + (malyon-interpreter)) + (error + (malyon-fatal-error "unspecified internal runtime error.")))) + +(defun malyon-more-char () + "Page down in More mode." + (interactive) + (condition-case nil + (scroll-up) + (error)) + (if (>= (count-lines (point) (point-max)) + (malyon-window-displayed-height)) + (message "[More]") + (goto-char (point-max)) + (malyon-adjust-transcript) + (use-local-map malyon-more-continue-keymap))) + +(defun malyon-more-char-status () + "Wait for a key then continue." + (interactive) + (condition-case nil + (progn + (malyon-adjust-transcript) + (use-local-map malyon-more-continue-keymap) + (malyon-interpreter)) + (error + (malyon-fatal-error "unspecified internal runtime error.")))) + +(defun malyon-wait-char () + "Store the input character in a variable and resume execution." + (interactive) + (condition-case nil + (progn + (malyon-store-variable + (malyon-read-code-byte) + (malyon-char-to-int (malyon-unicode-to-zscii last-command-char))) + (use-local-map malyon-keymap-read) + (malyon-interpreter)) + (error + (malyon-fatal-error "unspecified internal runtime error.")))) + +(defun malyon-history-previous-char (arg) + "Display the previous item in the input history." + (interactive "p") + (let ((input (malyon-history-previous))) + (cond ((> malyon-aread-beginning-of-line (point)) + (funcall malyon-history-saved-up arg)) + (input + (save-excursion + (set-buffer malyon-transcript-buffer) + (delete-region malyon-aread-beginning-of-line (point-max))) + (goto-char (point-max)) + (insert input) + (malyon-adjust-transcript))))) + +(defun malyon-history-next-char (arg) + "Display the next item in the input history." + (interactive "p") + (let ((input (malyon-history-next))) + (cond ((> malyon-aread-beginning-of-line (point)) + (funcall malyon-history-saved-down arg)) + (input + (save-excursion + (set-buffer malyon-transcript-buffer) + (delete-region malyon-aread-beginning-of-line (point-max))) + (goto-char (point-max)) + (insert input) + (malyon-adjust-transcript))))) + +(defun malyon-beginning-of-line (arg) + "Go to the beginning of the line." + (interactive "p") + (if (> malyon-aread-beginning-of-line (point)) + (beginning-of-line) + (goto-char malyon-aread-beginning-of-line))) + +(defun malyon-kill-region (arg) + "Kill region." + (interactive "p") + (if (<= malyon-aread-beginning-of-line (point)) + (kill-region (point) (mark)) + (message "Editing is restricted to the input prompt."))) + +(defun malyon-kill-line (arg) + "Kill rest of the current line." + (interactive "p") + (if (<= malyon-aread-beginning-of-line (point)) + (kill-line) + (message "Editing is restricted to the input prompt."))) + +(defun malyon-kill-word (arg) + "Kill the current word." + (interactive "p") + (if (<= malyon-aread-beginning-of-line (point)) + (kill-word 1) + (message "Editing is restricted to the input prompt."))) + +(defun malyon-yank (arg) + "Yank." + (interactive "p") + (if (<= malyon-aread-beginning-of-line (point)) + (yank) + (message "Editing is restricted to the input prompt."))) + +(defun malyon-yank-pop (arg) + "Yank pop." + (interactive "p") + (if (<= malyon-aread-beginning-of-line (point)) + (yank-pop 1) + (message "Editing is restricted to the input prompt."))) + +(defun malyon-delete-char (arg) + "Delete a character." + (interactive "p") + (if (<= malyon-aread-beginning-of-line (point)) + (delete-char 1) + (message "Editing is restricted to the input prompt."))) + +(defun malyon-backward-delete-char (arg) + "Delete a character backwards." + (interactive "p") + (if (< malyon-aread-beginning-of-line (point)) + (backward-delete-char-untabify 1) + (message "Editing is restricted to the input prompt."))) + +(defun malyon-self-insert-command (arg) + "Insert a character." + (interactive "p") + (if (> malyon-aread-beginning-of-line (point)) + (goto-char (point-max))) + (self-insert-command 1)) + +;; tracing utility + +(defun malyon-trace-file () + "Turn tracing on for a particular file." + (let ((trace + (get-buffer-create + (concat "Malyon Trace " malyon-story-file-name)))) + (if trace + (save-excursion + (set-buffer trace) + (malyon-erase-buffer) + (insert (concat "Tracing " malyon-story-file-name "...")) + (newline))))) + +(defun malyon-trace-newline () + "Output tracing newline." + (let ((trace (get-buffer (concat "Malyon Trace " malyon-story-file-name)))) + (if trace + (save-excursion + (set-buffer trace) + (goto-char (point-max)) + (newline))))) + +(defun malyon-trace-opcode (pc opcode operands) + "Output a z code instruction." + (malyon-trace-string + (format "%8d %-3d %-25s %s\n" + pc + opcode + (symbol-name (aref malyon-opcodes opcode)) + (apply 'concat (malyon-mapcan + (lambda (x) + (list " " + (number-to-string + (if (malyon-characterp x) + (malyon-char-to-int x) + x)))) + operands))))) + +(defun malyon-trace-string (s) + "Output tracing string." + (let ((trace (get-buffer (concat "Malyon Trace " malyon-story-file-name)))) + (if (and trace s) + (save-excursion + (set-buffer trace) + (goto-char (point-max)) + (insert s))))) + +(defun malyon-trace-object (o) + "Output tracing object." + (let ((trace (get-buffer (concat "Malyon Trace " malyon-story-file-name)))) + (if (and trace o) + (save-excursion + (set-buffer trace) + (goto-char (point-max)) + (prin1 o trace))))) + +;;; announce malyon-mode + +(provide 'malyon-mode) +(provide 'malyon) + +;;; malyon-mode.el ends here diff --git a/emacs/maxframe.el b/emacs/maxframe.el new file mode 100644 index 0000000..e824e77 --- /dev/null +++ b/emacs/maxframe.el @@ -0,0 +1,110 @@ +;;; $Id: maxframe.el 331 2007-02-20 16:58:21Z ryan $ +;; maximize the emacs frame based on display size + +;; Copyright (C) 2007 Ryan McGeary +;; Author: Ryan McGeary +;; Keywords: display frame window maximize + +;; This code is free; you can redistribute it and/or modify it under the +;; terms of the GNU General Public License as published by the Free +;; Software Foundation; either version 2, or (at your option) any later +;; version. + +;;; Commentary: +;; +;; Purpose +;; ------- +;; maxframe provides the ability to maximize the emacs frame and stay within +;; the display resolution. +;; +;; Usage +;; ----- +;; Example of lines to be added to your .emacs: +;; +;; (require 'maxframe) +;; (add-hook 'window-setup-hook 'maximize-frame t) +;; +;; How it works +;; ------------ +;; puts the emacs frame in the top left corner of the display and calculates +;; the maximum number of columns and rows that can fit in the display +;; +;; Limitations +;; ----------- +;; Requires Emacs 22 (for fringe support), but maximize-frame still works +;; under Emacs 21 on Windows. +;; +;; Emacs does not recognize when the display's resolution is changed. This is +;; a problem because I would like to be able to re-maximize the frame after +;; connecting to a display with different resolution. Unfortunately, +;; display-pixel-width and display-pixel-height yield the display resolution +;; values from when emacs was started instead of the current display +;; values. Perhaps there's a way to have emacs re-sniff these values, but I'm +;; not yet sure how. + + +(defgroup maxframe nil "Handle maximizing frames.") + +(defcustom mf-display-padding-width 0 + "*Any extra display padding that you want to account for while +determining the maximize number of columns to fit on a display" + :type 'integer + :group 'maxframe) + +;; The default accounts for a Mac OS X display with a menubar +;; height of 22 pixels, a titlebar of 23 pixels, and no dock. +(defcustom mf-display-padding-height (+ 22 23) + "*Any extra display padding that you want to account for while +determining the maximize number of rows to fit on a display" + :type 'integer + :group 'maxframe) + +(defun w32-maximize-frame () + "Maximize the current frame (windows only)" + (interactive) + (w32-send-sys-command 61488)) + +(defun w32-restore-frame () + "Restore a minimized/maximized frame (windows only)" + (interactive) + (w32-send-sys-command 61728)) + +(defun mf-max-columns (width) + "Calculates the maximum number of columns that can fit in +pixels specified by WIDTH." + (let ((scroll-bar (or (frame-parameter nil 'scroll-bar-width) 0)) + (left-fringe (or left-fringe-width (nth 0 (window-fringes)) 0)) + (right-fringe (or right-fringe-width (nth 1 (window-fringes)) 0))) + (/ (- width scroll-bar left-fringe right-fringe + mf-display-padding-width) + (frame-char-width)))) + +(defun mf-max-rows (height) + "Calculates the maximum number of rows that can fit in pixels +specified by HEIGHT." + (/ (- height + mf-display-padding-height) + (frame-char-height))) + +(defun mf-set-frame-pixel-size (frame width height) + "Sets size of FRAME to WIDTH by HEIGHT, measured in pixels." + (set-frame-size frame (mf-max-columns width) (mf-max-rows height))) + +(defun x-maximize-frame () + "Maximize the current frame (x or mac only)" + (interactive) + (mf-set-frame-pixel-size (selected-frame) + (display-pixel-width) + (display-pixel-height)) + (set-frame-position (selected-frame) 0 0)) + +(defun maximize-frame () + "Maximizes the frame to fit the display if under a windowing +system." + (interactive) + (cond ((eq window-system 'w32) (w32-maximize-frame)) + ((memq window-system '(x mac)) (x-maximize-frame)))) + +(defalias 'mf 'maximize-frame) + +(provide 'maxframe) diff --git a/emacs/moz.el b/emacs/moz.el new file mode 100644 index 0000000..a11324c --- /dev/null +++ b/emacs/moz.el @@ -0,0 +1,282 @@ +;;; moz.el --- Lets current buffer interact with inferior mozilla. + +;; URL: http://github.com/bard/mozrepl/raw/master/chrome/content/moz.el + +;; Copyright (C) 2006 by Massimiliano Mirra +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2 of the License, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, write to the Free Software +;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +;; +;; Author: Massimiliano Mirra, +;; Contributors: +;; - Lennart Borgman + +;;; Commentary: +;; +;; This file implements communication with Firefox via MozRepl +;; (http://hyperstruct.net/projects/mozrepl). It is a slightly +;; modified version of the file moz.el that comes with MozLab. To use +;; it you have to install the MozRepl addon in Firefox. +;; +;; This file contains +;; +;; * a major mode for direct interaction in a buffer (as with +;; telnet) with MozRepl, `inferior-moz-mode'. +;; * a minor mode for sending code portions or whole files from +;; other buffers to MozRepl, `moz-minor-mode'. +;; +;; Assuming you want to use javascript-mode to edit Javascript files, +;; enter the following in your .emacs initialization file (from Emacs +;; integration in the help text): +;; +;; (add-to-list 'auto-mode-alist '("\\.js$" . javascript-mode)) +;; (autoload 'inferior-moz-mode "moz" "MozRepl Inferior Mode" t) +;; (autoload 'moz-minor-mode "moz" "MozRepl Minor Mode" t) +;; (add-hook 'javascript-mode-hook 'javascript-moz-setup) +;; (defun javascript-moz-setup () (moz-minor-mode 1)) +;; +;; Replace javascript-mode above with the name of your favorite +;; javascript mode. +;; +;; If you got this with nXhtml the setup above is already done for +;; you. +;; +;; *Note 1* You have to start the MozRepl server in Firefox (or +;; whatever Mozilla browser you use). From the menus do +;; +;; Tools - MozRepl - Start +;; +;; *Note 2* For clearness and brevity the documentation says Firefox +;; where the correct term should rather be "your Mozilla web +;; browser". + +;;; Change log: +;; +;; 2008-07-20: Lennart Borgman +;; - Add `moz-minor-mode-map'. +;; - Add `inferior-moz-insert-moz-repl'. +;; - Add `inferior-moz-mode-map'. +;; - Add doc strings to interactive functions. +;; - Make minor enhancements to documentation etc. +;; - Change Mozilla to Firefox/MozRepl for clarity and brevity. +;; - Add error handling when starting MozRepl. + +;;; Code: + +(require 'comint) + +;; Maybe fix-me: C-c control-char are reserved for major modes. But +;; this minor mode is used in only one major mode (or one family of +;; major modes) so it complies I think ... +(defvar moz-minor-mode-map + (let ((map (make-sparse-keymap))) + (define-key map "\C-c\C-s" 'run-mozilla) + (define-key map "\C-\M-x" 'moz-send-defun) + (define-key map "\C-c\C-c" 'moz-send-defun-and-go) + (define-key map "\C-c\C-r" 'moz-send-region) + (define-key map "\C-c\C-l" 'moz-save-buffer-and-send) + map)) + +;;;###autoload +(define-minor-mode moz-minor-mode + "MozRepl minor mode for interaction with Firefox. +With no argument, this command toggles the mode. +Non-null prefix argument turns on the mode. +Null prefix argument turns off the mode. + +When this minor mode is enabled, some commands become available +to send current code area \(as understood by c-mark-function) or +region or buffer to an inferior MozRepl process (which will be +started as needed). + +The following keys are bound in this minor mode: + +\\{moz-minor-mode-map}" + nil + " Moz" + :keymap moz-minor-mode-map + :group 'moz) + +(defalias 'run-mozilla 'inferior-moz-switch-to-mozilla) + +(defvar moz-repl-name "repl" + "The current name of the repl.") + +(defvar moz-input-separator "\n--end-remote-input\n") + +(defvar moz-repl-host "localhost") + +(defvar moz-repl-port 4242) + +(defun moz-temporary-file () + (if (and moz-temporary-file + (file-readable-p moz-temporary-file)) + moz-temporary-file + (setq moz-temporary-file (make-temp-file "emacs-mozrepl")))) + +(defun moz-send-region (start end) + "Send the region to Firefox via MozRepl." + (interactive "r") + (comint-send-string (inferior-moz-process) + (concat moz-repl-name ".pushenv('printPrompt', 'inputMode'); " + moz-repl-name ".setenv('printPrompt', false); " + moz-repl-name ".setenv('inputMode', 'multiline'); " + "undefined; \n")) + ;; Give the previous line a chance to be evaluated on its own. If + ;; it gets concatenated to the following ones, we are doomed. + (sleep-for 0 1) + (comint-send-region (inferior-moz-process) + start end) + (comint-send-string (inferior-moz-process) + "\n--end-remote-input\n") + (comint-send-string (inferior-moz-process) + (concat moz-repl-name ".popenv('inputMode', 'printPrompt'); " + "undefined; \n")) + (comint-send-string (inferior-moz-process) + "\n--end-remote-input\n") + (display-buffer (process-buffer (inferior-moz-process)))) + +(defun moz-send-defun () + "Send the current function to Firefox via MozRepl. +Curent function is the one recognized by c-mark-function." + (interactive) + (save-excursion + (mark-defun) + (moz-send-region (point) (mark)))) + +(defun moz-send-defun-and-go () + "Send the current function to Firefox via MozRepl. +Also switch to the interaction buffer." + (interactive) + (moz-send-defun) + (inferior-moz-switch-to-mozilla nil)) + +(defun moz-save-buffer-and-send () + "Save the current buffer and load it in Firefox via MozRepl." + (interactive) + (save-buffer) + (comint-send-string (inferior-moz-process) + (concat moz-repl-name ".pushenv('printPrompt', 'inputMode'); " + moz-repl-name ".setenv('inputMode', 'line'); " + moz-repl-name ".setenv('printPrompt', false); undefined; ")) + (comint-send-string (inferior-moz-process) + (concat moz-repl-name ".load('file://localhost/" (buffer-file-name) "');\n" + moz-repl-name ".popenv('inputMode', 'printPrompt'); undefined;\n")) + (display-buffer (process-buffer (inferior-moz-process)))) + +;;; Inferior Mode + +(defvar inferior-moz-buffer nil + "The buffer in which the inferior process is running.") + +(defun inferior-moz-insert-moz-repl () + "Insert value of `moz-repl-name' and a dot (.)." + (interactive) (insert moz-repl-name ".")) + +(defvar inferior-moz-mode-map + (let ((map (make-sparse-keymap))) + (define-key map "\C-cc" 'inferior-moz-insert-moz-repl) + map)) + +;;;###autoload +(define-derived-mode inferior-moz-mode comint-mode "Inf-MozRepl" + "Major mode for interacting with Firefox via MozRepl." + (setq comint-input-sender 'inferior-moz-input-sender) + (add-hook 'comint-output-filter-functions 'inferior-moz-track-repl-name nil t)) + +(defun inferior-moz-track-repl-name (comint-output) + (when (string-match "\\(\\w+\\)> $" comint-output) + (setq moz-repl-name (match-string 1 comint-output)))) + +(defun inferior-moz-self-insert-or-repl-name () + (interactive) + (if (looking-back "\\(\\w+\\)> $") + (insert moz-repl-name ".") + (insert last-command-char))) + +(defun inferior-moz-input-sender (proc string) + "Custom function to send input with comint-send-input. +Instead of sending input and newline separately like in +comint-simple-send, here we *first* concatenate input and +newline, then send it all together. This prevents newline to be +interpreted on its own." + (comint-send-string proc (concat string "\n"))) + +(defun inferior-moz-switch-to-mozilla (arg) + "Switch to the inferior MozRepl buffer. +Create the buffer and start the MozRepl process and connect to +Firefox if needed. + +See also `inferior-moz-start-process'." + (interactive "P") + (when arg + (setq moz-repl-host (read-string "Host: " "localhost")) + (setq moz-repl-port (read-number "Port: " 4242))) + (pop-to-buffer (process-buffer (inferior-moz-process))) + (goto-char (process-mark (inferior-moz-process)))) + +(defun inferior-moz-process () + "Return inferior MozRepl process. Start it if necessary. +See also `inferior-moz-start-process'." + (or (if (buffer-live-p inferior-moz-buffer) + (get-buffer-process inferior-moz-buffer)) + (progn + (inferior-moz-start-process) + (inferior-moz-process)))) + +(defun inferior-moz-start-process () + "Start an inferior Mozrepl process and connect to Firefox. +It runs the hook `inferior-moz-hook' after starting the process +and setting up the inferior Firefox buffer. + +Note that you have to start the MozRepl server from Firefox." + (interactive) + (condition-case err + (progn + (setq inferior-moz-buffer + (apply 'make-comint "MozRepl" (cons moz-repl-host moz-repl-port) nil nil)) + (sleep-for 0 100) + (with-current-buffer inferior-moz-buffer + (inferior-moz-mode) + (run-hooks 'inferior-moz-hook))) + (file-error + (with-output-to-temp-buffer "*MozRepl Error*" + (with-current-buffer (get-buffer "*MozRepl Error*") + (insert "Can't start MozRepl, the error message was:\n\n " + (error-message-string err) + "\n" + "\nA possible reason is that you have not installed" + "\nthe MozRepl add-on to Firefox or that you have not" + "\nstarted it. You start it from the menus in Firefox:" + "\n\n Tools / MozRepl / Start" + "\n" + "\nSee ") + (insert-text-button + "MozRepl home page" + 'action (lambda (button) + (browse-url + "http://hyperstruct.net/projects/mozrepl") + ) + 'face 'button) + (insert + " for more information." + "\n" + "\nMozRepl is also available directly from Firefox add-on" + "\npages, but is updated less frequently there.") + )) + (error "Can't start MozRepl")))) + +(provide 'moz) + +;;; moz.el ends here diff --git a/emacs/my-c-mode.el b/emacs/my-c-mode.el new file mode 100644 index 0000000..bf0caaf --- /dev/null +++ b/emacs/my-c-mode.el @@ -0,0 +1,29 @@ +(require 'cc-mode) + +(defconst vu3rdd-c-style + '((c-basic-offset . 2) + (tab-width . 4) + (indent-tabs-mode . nil) + (c-comment-only-line-offset . 0) + (c-hanging-braces-alist . ((substatement-open before after))) + (c-offsets-alist . ((topmost-intro . 0) + (substatement . +) + (substatement-open . 0) + (case-label . +) + (access-label . -) + (inclass . ++) + (inline-open . 0) + )))) + + +(c-add-style "vu3rddstyle" vu3rdd-c-style nil) + +(defun vu3rdd-c-hook () + (c-set-style "vu3rddstyle") + ;; parenthesis matching {}[]() + (global-set-key "%" 'match-paren)) + +(add-hook 'c-mode-common-hook 'vu3rdd-c-hook) + +(add-hook 'c-mode-common-hook + (lambda () (which-function-mode t))) diff --git a/emacs/my-erc.el b/emacs/my-erc.el new file mode 100644 index 0000000..53718da --- /dev/null +++ b/emacs/my-erc.el @@ -0,0 +1,77 @@ +;;; erc +(require 'erc) + +;; Load authentication info from an external source. Put sensitive +;; passwords and the like in here. +(load "~/.emacs.d/emacs/.erc-auth") + +(require 'erc-services) +(require 'erc-match) +(erc-services-mode 1) + +(setq erc-prompt-for-nickserv-password nil) + +(setq erc-nickserv-passwords + `((freenode (("vu3rdd" . ,freenode-nick-pass))) + (debian (("vu3rdd" . ,debian-nick-pass))))) + +(setq erc-autojoin-channels-alist + '((".*\\.freenode.net" "#racket" "#haskell") + (".*\\.oftc.net" "#debian-arm" "#debian" "#debian-devel"))) + +(global-set-key "\C-cef" (lambda () (interactive) + (erc :server "irc.freenode.net" :port "8000" + :nick "vu3rdd"))) +(global-set-key "\C-ced" (lambda () (interactive) + (erc :server "irc.debian.org" :port "6668" + :nick "vu3rdd"))) + +(setq erc-user-full-name "Ramakrishnan Muthukrishnan") +(setq erc-email-userid "vu3rdd@gmail.com") + +(require 'erc-track) +(erc-track-mode 1) +(setq erc-track-switch-direction 'importance) + +;; Only track my nick(s) +(defadvice erc-track-find-face (around erc-track-find-face-promote-query activate) + (if (erc-query-buffer-p) + (setq ad-return-value (intern "erc-current-nick-face")) + ad-do-it)) + +(setq erc-keywords '("vu3rdd" "rkrishnan")) + +(setq erc-track-exclude-types '("JOIN" "NICK" "PART" "QUIT" "MODE" + "324" "329" "332" "333" "353" "477")) + +(global-set-key (kbd "C-c SPC") 'erc-track-switch-buffer) + +;; erc notification via notify +(defun clean-message (s) + (setq s (replace-regexp-in-string "'" "'" + (replace-regexp-in-string "\"" """ + (replace-regexp-in-string "&" "&" + (replace-regexp-in-string "<" "<" + (replace-regexp-in-string ">" ">" s))))))) + +(defun call-libnotify (matched-type nick msg) + (let* ((cmsg (split-string (clean-message msg))) + (nick (first (split-string nick "!"))) + (msg (mapconcat 'identity (rest cmsg) " "))) + (shell-command-to-string + (format "notify-send -t 5000 -u critical '%s says:' '%s'" nick msg)))) + +(add-hook 'erc-text-matched-hook 'call-libnotify) + +;; Enable logging +(setq erc-log-insert-log-on-open nil) +(setq erc-log-channels t) +(setq erc-log-channels-directory "~/.erc/logs/") +(setq erc-save-buffer-on-part t) +(setq erc-save-queries-on-quit nil + erc-log-write-after-send t + erc-log-write-after-insert t) +(defadvice save-buffers-kill-emacs (before save-logs (arg) activate) + (save-some-buffers t (lambda () (when (and (eq major-mode 'erc-mode) + (not (null buffer-file-name))))))) +(add-hook 'erc-insert-post-hook 'erc-save-buffer-in-logs) diff --git a/emacs/my-generic-stuff.el b/emacs/my-generic-stuff.el new file mode 100644 index 0000000..e6b5bee --- /dev/null +++ b/emacs/my-generic-stuff.el @@ -0,0 +1,44 @@ +;; inhibit splash screen +(setq inhibit-splash-screen t) + +;; prevent backup file creation +(setq make-backup-files nil) + +(transient-mark-mode t) + +;; disable startup message +(setq inhibit-startup-message t) + +;; Show column number at bottom of screen +(column-number-mode 1) + +;; alias y to yes and n to no +(defalias 'yes-or-no-p 'y-or-n-p) + +;; Pgup/dn will return exactly to the starting point. +(setq scroll-preserve-screen-position 1) + +;; format the title-bar to always include the buffer name +(setq frame-title-format "emacs - %b") + +;; scroll just one line when hitting the bottom of the window +(setq scroll-step 1) +(setq scroll-conservatively 1) + +;; scroll bar +(setq toggle-scroll-bar t) + +;; iswitchb +(setq iswitchb-mode t) + +(setq cursor-type 'bar) + +;; how long to wait? +(setq show-paren-delay 0) +;; turn paren-mode on + +;; alternatives are 'parenthesis' and 'mixed' +;(setq show-paren-style 'expression) + +;; font lock +(global-font-lock-mode t) diff --git a/emacs/my-haskell.el b/emacs/my-haskell.el new file mode 100644 index 0000000..4ae37a3 --- /dev/null +++ b/emacs/my-haskell.el @@ -0,0 +1,24 @@ +(add-to-list 'load-path "~/.emacs.d/vendor/haskell-mode") + +;;; haskell mode +(setq auto-mode-alist + (append auto-mode-alist + '(("\\.[hg]s$" . haskell-mode) + ("\\.hic?$" . haskell-mode) + ("\\.hsc$" . haskell-mode) + ("\\.chs$" . haskell-mode) + ("\\.l[hg]s$" . literate-haskell-mode)))) +(autoload 'haskell-mode "haskell-mode" + "Major mode for editing Haskell scripts." t) +(autoload 'literate-haskell-mode "haskell-mode" + "Major mode for editing literate Haskell scripts." t) + +;adding the following lines according to which modules you want to use: +(require 'inf-haskell) + +(add-hook 'haskell-mode-hook 'turn-on-font-lock) +(add-hook 'haskell-mode-hook 'turn-on-haskell-ghci) +(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode) +(add-hook 'haskell-mode-hook 'turn-on-haskell-indent) +(set-variable 'haskell-program-name "ghci") + diff --git a/emacs/my-org-mode.el b/emacs/my-org-mode.el new file mode 100644 index 0000000..c073c80 --- /dev/null +++ b/emacs/my-org-mode.el @@ -0,0 +1,33 @@ +;; org mode +(require 'org-install) +(add-to-list 'auto-mode-alist '("\\.org$" . org-mode)) +(define-key global-map "\C-cl" 'org-store-link) +(define-key global-map "\C-ca" 'org-agenda) +(define-key global-map "\C-cb" 'org-iswitchb) +(setq org-log-done 'time) +(setq org-startup-indented t) + +(setq org-agenda-files (list "~/org/work.org" + "~/org/remember.org" + "~/org/debian.org" + "~/org/clojure.org" + "~/org/learning.org" + "~/org/reading.org" + "~/org/investments.org")) + +;; adapted from +(setq org-todo-keywords '((sequence "TODO(t)" + "STARTED(s!)" + "|" + "DONE(d!/!)") + (sequence "WAITING(w@/!)" + "SOMEDAY(S!)" + "|" + "CANCELLED(c@/!)"))) + +(setq org-todo-keyword-faces (quote (("TODO" :foreground "red" :weight bold) + ("STARTED" :foreground "blue" :weight bold) + ("DONE" :foreground "forest green" :weight bold) + ("WAITING" :foreground "orange" :weight bold) + ("SOMEDAY" :foreground "magenta" :weight bold) + ("CANCELLED" :foreground "forest green" :weight bold)))) diff --git a/emacs/my-python.el b/emacs/my-python.el new file mode 100644 index 0000000..6dabf3d --- /dev/null +++ b/emacs/my-python.el @@ -0,0 +1,19 @@ +(require 'ac-python) + +;;; Use python-mode with files with these extensions +(add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode)) +(add-to-list 'auto-mode-alist '("\\.pyx\\'" . python-mode)) + +;;; Turn on auto-complete in python shells +(add-hook 'inferior-python-mode-hook (lambda () (auto-complete-mode 1))) + +;;; Use python major mode if 'python' is in hashbang. +(add-to-list 'interpreter-mode-alist '("python" . python-mode)) + +;;; Use python as the python interpreter (can be changed to "ipython" in time +;;; when it works) +(setq python-python-command "python") + +;;; Check files for pep8 mistakes +(autoload 'python-pep8 "python-pep8") +(autoload 'pep8 "python-pep8") diff --git a/emacs/my-search.el b/emacs/my-search.el new file mode 100644 index 0000000..eb2049d --- /dev/null +++ b/emacs/my-search.el @@ -0,0 +1,4 @@ +;; highlight matches from searches +(setq isearch-highlight t) +(setq search-highlight t) +(setq-default transient-mark-mode t) diff --git a/emacs/my-slime.el b/emacs/my-slime.el new file mode 100644 index 0000000..2691f4c --- /dev/null +++ b/emacs/my-slime.el @@ -0,0 +1,43 @@ +;; slime +(add-to-list 'load-path "~/.emacs.d/vendor/slime") + +(eval-after-load "slime" + '(progn + (setq slime-use-autodoc-mode nil) + (slime-setup '(inferior-slime + ;; slime-asdf + ;; slime-autodoc + slime-banner + ;; slime-c-p-c + ;; slime-editing-commands + slime-fancy-inspector + slime-fancy + slime-fuzzy + ;; slime-highlight-edits + ;; slime-parse + ;; slime-presentation-streams + ;; slime-presentations + ;; slime-references + slime-repl + slime-scratch + ;;slime-tramp + ;;slime-typeout-frame + slime-xref-browser + slime-scheme)) + + (setq slime-protocol-version 'ignore) + (setq slime-complete-symbol*-fancy t) + (setq slime-complete-symbol-function 'slime-fuzzy-complete-symbol))) + +(require 'slime) +;(setq inferior-lisp-program "~/src/sbcl/src/runtime/sbcl") +(add-to-list 'slime-lisp-implementations '(sbcl ("/usr/bin/sbcl"))) +(setq slime-default-lisp 'sbcl) + +;; enable cldoc for slime +(dolist (hook '(lisp-mode-hook + slime-repl-mode-hook)) + (add-hook hook 'turn-on-cldoc-mode)) + +;; needed for overriding default method for invoking slime +; (ad-activate 'slime-read-interactive-args) diff --git a/emacs/my-swank-js.el b/emacs/my-swank-js.el new file mode 100644 index 0000000..2046066 --- /dev/null +++ b/emacs/my-swank-js.el @@ -0,0 +1,3 @@ +;; swank-js +(add-to-list 'load-path "~/.emacs.d/vendor/swank-js") +(require 'slime-js) diff --git a/emacs/my-twitter.el b/emacs/my-twitter.el new file mode 100644 index 0000000..bbd9495 --- /dev/null +++ b/emacs/my-twitter.el @@ -0,0 +1,4 @@ +(add-to-list 'load-path "~/.emacs.d/emacs/twittering-mode") +(require 'twittering-mode) + +(add-hook 'twittering-edit-mode-hook (lambda () (ispell-minor-mode) (flyspell-mode))) diff --git a/emacs/naquadah-theme.el b/emacs/naquadah-theme.el new file mode 100644 index 0000000..974c15e --- /dev/null +++ b/emacs/naquadah-theme.el @@ -0,0 +1,185 @@ +;;; naquadah-theme.el --- A color theme + +;; Copyright (C) 2011 Julien Danjou + +;; Authors: Julien Danjou + +;; This file is NOT part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Code: + +(deftheme naquadah + "Naquadah theme.") + +(let ((light-blue "#72A0CF") + (pale-yellow "#D4F77F") + (violet "#C66CD0") + (green "#89E234") + (blue "#374EAB") + (yellow "#FCCD3A") + (pink "#DE336D") + (red "#8A0B0B") + (violet-blue "#5337AD") + (orange "#FFA500") + (tomato "#FC683A") + (background "#252A2B") + (shadow "#888a85")) + (custom-theme-set-faces + 'naquadah + `(default ((((min-colors 4096)) (:background ,background :foreground "#eeeeec")))) + `(shadow ((t (:foreground ,shadow)))) + '(cursor ((t (:background "#aa0000")))) + '(hl-line ((t (:background "#191919")))) + '(highlight ((t (:background "brown1" :foreground nil)))) + '(fringe ((t (:background "gray10")))) + '(mode-line ((t (:foreground "#fafafa" :background "#000000" :box (:line-width 1 :color "#444444"))))) + '(mode-line-inactive ((t (:foreground "#888888" :background "#2c2f2f" :box (:line-width 1 :color "black"))))) + `(mode-line-buffer-id ((t (:bold t :foreground ,orange)))) + '(header-line ((t (:foreground "#dddddd" :background "#1e2426" :box (:line-width 1 :color "#444444"))))) + '(region ((t (:background "grey30")))) + `(link ((t (:underline t :foreground ,light-blue)))) + '(custom-link ((t (:inherit 'link)))) + '(match ((t (:bold t :background "#e9b96e" :foreground "#2e3436")))) + '(tooltip ((t (:inherit 'variable-pitch :foreground "LightYellow" :background "black")))) + '(bold ((t (:bold t :underline nil :background nil)))) + '(italic ((t (:italic t :underline nil :background nil)))) + `(font-lock-builtin-face ((t (:foreground ,light-blue)))) + '(font-lock-comment-face ((t (:inherit 'shadow :italic t)))) + '(font-lock-comment-delimiter-face ((t (:inherit 'font-lock-comment-face)))) + `(font-lock-constant-face ((t (:foreground ,green)))) + '(font-lock-doc-face ((t (:inherit 'shadow)))) + '(font-lock-keyword-face ((t (:inherit 'font-lock-builtin-face :bold t)))) + `(font-lock-string-face ((t (:foreground ,violet)))) + '(font-lock-type-face ((t (:inherit 'font-lock-constant-face :bold t)))) + `(font-lock-variable-name-face ((t (:foreground ,tomato)))) + `(font-lock-warning-face ((t (:bold t :foreground ,orange)))) + `(font-lock-function-name-face ((t (:foreground ,yellow :bold t)))) + '(comint-highlight-input ((t (:italic t :bold t)))) + `(comint-highlight-prompt ((t (:foreground ,green)))) + `(isearch ((t (:background ,orange :foreground ,background)))) + `(show-paren-match-face ((t (:background ,green)))) + `(show-paren-mismatch-face ((t (:background ,violet)))) + `(minibuffer-prompt ((t (:foreground ,light-blue :bold t)))) + `(info-xref ((t (:foreground ,light-blue)))) + `(info-xref-visited ((t (:foreground ,violet)))) + '(widget-button ((t (:bold t)))) + `(widget-mouse-face ((t (:bold t :foreground "white" :background ,red)))) + `(widget-field ((t (:foreground ,orange :background "gray30")))) + `(widget-single-line-field ((t (:foreground ,orange :background "gray30")))) + `(custom-group-tag ((t (:bold t :foreground ,orange :height 1.3)))) + '(custom-variable-tag ((t (:bold t :foreground "#edd400" :height 1.1)))) + '(custom-face-tag ((t (:bold t :foreground "#edd400" :height 1.1)))) + `(custom-state-face ((t (:foreground ,light-blue)))) + '(custom-button ((t (:box (:line-width 1 :style released-button) :background "gray50" :foreground "black")))) + '(custom-variable-button ((t (:inherit 'custom-button)))) + '(custom-button-mouse ((t (:inherit 'custom-button :background "gray60")))) + '(custom-button-unraised ((t (:background "gray50" :foreground "black")))) + '(custom-button-mouse-unraised ((t (:inherit 'custom-button-unraised :background "gray60")))) + '(custom-button-pressed ((t (:inherit 'custom-button :box (:style pressed-button))))) + '(custom-button-mouse-pressed-unraised ((t (:inherit 'custom-button-unraised :background "gray60")))) + '(custom-documentation ((t (:italic t)))) + '(gnus-cite-face-1 ((t (:foreground "#ad7fa3")))) + '(gnus-cite-face-2 ((t (:foreground "sienna3")))) + '(gnus-cite-face-3 ((t (:foreground "khaki4")))) + '(gnus-cite-face-4 ((t (:foreground "PaleTurquoise4")))) + '(gnus-header-name-face ((t (:bold t :foreground "#729fcf")))) + '(gnus-header-from ((t (:bold t :foreground "#e0d400")))) + '(gnus-header-subject ((t (:foreground "#e0d400")))) + '(gnus-header-content ((t (:italic t :foreground "#8ae234")))) + '(gnus-header-newsgroups-face ((t (:italic t :bold t :foreground "LightSkyBlue3")))) + '(gnus-signature-face ((t (:italic t :foreground "OliveDrab1")))) + `(gnus-summary-cancelled-face ((t (:background "black" :foreground ,yellow)))) + '(gnus-summary-normal-ancient-face ((t (:foreground "medium sea green")))) + '(gnus-summary-normal-read-face ((t (:foreground "lime green")))) + `(gnus-summary-normal-ticked-face ((t (:foreground ,tomato)))) + '(gnus-summary-normal-unread-face ((t (:foreground "white")))) + '(gnus-summary-high-ancient-face ((t (:inherit 'gnus-summary-normal-ancient-face)))) + '(gnus-summary-high-read-face ((t (:inherit 'gnus-summary-normal-read-face)))) + `(gnus-summary-high-ticked-face ((t (:inherit 'gnus-summary-normal-ticked-face))))) + '(gnus-summary-high-unread-face ((t (:inherit 'gnus-summary-normal-unread-face)))) + '(gnus-summary-low-ancient-face ((t (:inherit 'gnus-summary-normal-ancient-face) :italic t))) + '(gnus-summary-low-read-face ((t (:inherit 'gnus-summary-normal-read-face :italic t)))) + '(gnus-summary-low-ticked-face ((t (:inherit 'gnus-summary-normal-ticked-face :italic t)))) + '(gnus-summary-low-unread-face ((t (:inherit 'gnus-summary-normal-unread-face :italic t)))) + '(spam-face ((t (:background "black" :foreground "magenta3")))) + `(gnus-summary-selected ((t (:background ,light-blue :foreground "white")))) + '(message-header-name-face ((t (:foreground "#729cfc")))) + '(message-header-newsgroups-face ((t (:italic t :bold t :foreground "LightSkyBlue3")))) + '(message-header-other-face ((t (:foreground "LightSkyBlue3")))) + '(message-header-xheader-face ((t (:foreground "DodgerBlue3")))) + '(message-header-subject ((t (:foreground "white")))) + '(message-header-to ((t (:foreground "white")))) + '(message-header-cc ((t (:foreground "white")))) + '(org-hide ((t (:foreground "#252a2b")))) + '(org-level-1 ((t (:bold t :foreground "#4788cc" :height 1.2)))) + '(org-level-2 ((t (:bold t :foreground "#6ac214" :height 1.1)))) + '(org-level-3 ((t (:bold t :foreground "#edd400" :height 1.0)))) + '(org-level-4 ((t (:bold t :foreground "tomato" :height 1.0)))) + '(org-footnote ((t (:underline t :foreground "magenta3")))) + '(org-link ((t (:foreground "SkyBlue2")))) + '(org-special-keyword ((t (:foreground "brown1")))) + '(org-verbatim ((t (:foreground "#eeeeec" :underline t :slant italic)))) + '(org-block ((t (:foreground "#bbbbbc")))) + '(org-quote ((t (:inherit org-block :slant italic)))) + '(org-verse ((t (:inherit org-block :slant italic)))) + '(org-todo ((t (:bold t :foreground "#ff2020")))) + '(org-done ((t (:bold t :foreground "forest green")))) + '(org-mode-line-clock ((t (:foreground "#cc77ff" :background nil)))) + '(org-date ((t (:underline nil :foreground "#edd466" :background nil)))) + '(org-agenda-date ((t (:underline nil :foreground "SkyBlue2" :height 1.2)))) + '(org-agenda-date-today ((t (:inherit org-agenda-date :foreground "#edd466" :weight bold)))) + '(org-agenda-date-telecommuting ((t (:inherit org-agenda-date :foreground "#ffbb22" :weight bold)))) + '(org-agenda-date-weekend ((t (:inherit org-agenda-date :foreground "brown3" :weight bold)))) + '(anything-header ((t (:bold t :background "gray15" :foreground "#edd400")))) + '(egocentric-face ((t (:foreground "#ff4289" :weight bold)))) + '(erc-direct-msg-face ((t (:foreground "#ee5577")))) + '(erc-header-line ((t (:background "black" :foreground "white")))) + '(erc-input-face ((t (:foreground "gray70")))) + '(erc-my-nick-face ((t (:inherit egocentric-face :weight thin :foreground nil)))) + '(erc-notice-face ((t (:foreground "light blue" :weight thin)))) + '(erc-prompt-face ((t (:background "black" :foreground "gray80" :weight bold)))) + '(erc-timestamp-face ((t (:foreground "gray70" :weight bold)))) + '(erc-pal-face ((t (:foreground "DarkOliveGreen3" :weight bold)))) + '(erc-fool-face ((t (:foreground "gray60" :weight thin)))) + '(erc-current-nick-face ((t (:inherit egocentric-face :weight thin :foreground nil)))) + '(ido-subdir ((t (:foreground "orange1")))) + '(which-func ((t (:foreground "#729cfc")))) + '(mm-uu-extract ((t (:background "#404040")))) + `(diff-added ((t (:foreground ,green)))) + `(diff-changed ((t (:foreground ,orange)))) + `(diff-removed ((t (:foreground ,red)))) + '(diff-hunk-header ((t (:bold t)))) + `(diff-function ((t (:foreground ,orange)))) + '(diff-header ((t (:background "grey10")))) + '(diff-file-header ((t (:background nil :foreground "white")))) + '(git-commit-summary-face ((t (:bold t)))) + `(git-commit-branch-face ((t (:foreground ,orange :bold t)))) + '(git-commit-nonempty-second-line-face ((t (:foreground "red")))) + '(git-commit-comment-face ((t (:inherit font-lock-comment-face)))) + '(git-commit-known-pseudo-header-face ((t (:inherit gnus-header-name-face)))) + '(git-commit-pseudo-header-face ((t (:inherit gnus-header-content)))) + '(rst-level-1-face ((t (:inherit org-level-1 :background nil)))) + '(rst-level-2-face ((t (:inherit org-level-2 :background nil)))) + '(rst-level-3-face ((t (:inherit org-level-3 :background nil)))) + '(rst-level-4-face ((t (:inherit org-level-4 :background nil))))) + +(provide-theme 'naquadah) + +;; Local Variables: +;; no-byte-compile: t +;; End: + +;;; naquadah-theme.el ends here diff --git a/emacs/notify.el b/emacs/notify.el new file mode 100644 index 0000000..599d0e5 --- /dev/null +++ b/emacs/notify.el @@ -0,0 +1,99 @@ +;;; notify.el --- notification frontend + +;; Copyright (C) 2008 Mark A. Hershberger + +;; Original Author: Mark A. Hershberger +;; Keywords: extensions, convenience, lisp + +;; This file is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; This file is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; This provides a single function, notify, that will produce a notify +;; pop-up via DBus. + +;;; Code: + +(defvar notify-last '(0 0 0)) + +(defvar notify-defaults + (list :app "GNU Emacs" + :icon "/usr/share/icons/emacs22/emacs_48.png" + :timeout 10000 + :urgency "low" + :category "emacs.message")) + +(defvar notify-id 0) + +(defvar notify-delay '(0 5 0)) + +(defvar notify-last-notification '(0 5 0)) + +;; We could set up other notification methods like notify-via-shell or +;; notify-via-pointer +(defvar notify-method 'notify-via-dbus) + +(defun notify-next-id () + "Return the next notification id." + (setq notify-id (+ notify-id 1))) + +(defun notify-via-dbus (title body params) + "Send notification via DBus." + (when (and (fboundp 'dbus-ping) + (dbus-ping :session "org.freedesktop.Notifications")) + (dbus-call-method :session "org.freedesktop.Notifications" + "/org/freedesktop/Notifications" + "org.freedesktop.Notifications" "Notify" + (get 'params :app) + (notify-next-id) + (get 'params :icon) + title + body + '(:array) + '(:array :signature "{sv}") + ':int32 (get 'params :timeout)))) + +(defun notify (title body &rest args) + "Use pop-up notifications for events." + (when (and + (time-less-p notify-delay + (time-since notify-last-notification)) + (let ((params)) + (keywords-to-properties 'params args notify-defaults) + (setq notify-last-notification (current-time)) + (funcall notify-method title body params))))) + +(defun keywords-to-properties (symbol args &optional defaults) + "Convert a list in the form (:keywordA valueA + :keywordB valueB ...) +to a list of propertys with the given values" + (when (car-safe defaults) ; probably need to avoid recursion + (keywords-to-properties symbol defaults)) + (while args + (let ((arg (car args))) + (setq args (cdr args)) + (unless (symbolp arg) + (error "Junk in args %S" args)) + (let ((keyword arg) + (value (car args))) + (unless args + (error "Keyword %s is missing an argument" keyword)) + (setq args (cdr args)) + (put symbol keyword value))))) + +(provide 'notify) + +;;; notify.el ends here diff --git a/emacs/nxhtml/README.txt b/emacs/nxhtml/README.txt new file mode 100644 index 0000000..e9204b4 --- /dev/null +++ b/emacs/nxhtml/README.txt @@ -0,0 +1,46 @@ +To install nXhtml put this in your .emacs: + + (load "YOUR-PATH-TO/nxhtml/autostart.el") + +where autostart.el is the file in the same directory as this +readme.txt file. + +Note 1: If you are using Emacs+EmacsW32 then nXhtml is already + installed. + +Note 2: If you are using Emacs 22 then you need to install nXml + separately. (It is included in Emacs 23.) + +Note 3: You may optionally also byte compile nXhtml from the nXhtml + menu (recommended). + + + +Files that are now in Emacs' development (CVS/Bazaar) repository +================================================================ + +Some files that were previously distributed with nXhtml are now in +Emacs' development repository. Distributing them also with nXhtml is +a bad idea since that can lead to that the wrong file is loaded. They +are therefore not distributed with nXhtml anymore. + +Instead you can (if you do not have the files in your Emacs) in many +cases use the version from the repository. To do that you can +currently start from + + http://cvs.savannah.gnu.org/viewvc/emacs/emacs/lisp/ + +Files you can download and use this way are for example + + js.el (JavaScript, formerly called espresso.el) + htmlfontify.el + +If you do that I suggest that you put these files in a special +directory and add that to load-path in your .emacs and make that +adding to load-path depend on your Emacs version so that they will not +be loaded when you have upgraded your Emacs. + +Note that if you want to use nxml-mode (and it is not in your Emacs) +you should not download it from Emacs' development directory. Instead go to + + http://www.thaiopensource.com/download/ diff --git a/emacs/nxhtml/alts/find-recursive-orig.el b/emacs/nxhtml/alts/find-recursive-orig.el new file mode 100644 index 0000000..509a038 --- /dev/null +++ b/emacs/nxhtml/alts/find-recursive-orig.el @@ -0,0 +1,137 @@ +;; find-recursive.el -- Find files recursively into a directory +;; +;; Copyright (C) 2001 Ovidiu Predescu +;; +;; Author: Ovidiu Predescu +;; Date: March 26, 2001 +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License +;; as published by the Free Software Foundation; either version 2 +;; of the License, or (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, write to the Free Software +;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +;; +;; Setup: put this file in your Lisp path and add the following line in +;; your .emacs: +;; +;; (require 'find-recursive) +;; + +(require 'cl) + +(defcustom find-recursive-exclude-files '(".*.class$" ".*~$" ".*.elc$") + "List of regular expressions of files to be excluded when recursively searching for files." + :type '(repeat (string :tag "File regexp"))) + +(defun find-file-recursively (file-regexp directory) + (interactive "sFile name to search for recursively: \nDIn directory: ") + (let ((directory (if (equal (substring directory -1) "/") + directory + (concat directory "/"))) + (matches + (find-recursive-filter-out + find-recursive-exclude-files + (find-recursive-directory-relative-files directory "" file-regexp)))) + (cond ((eq (length matches) 0) (message "No file(s) found!")) + ((eq (length matches) 1) + (find-file (concat directory (car matches)))) + (t + (run-with-timer 0.001 nil + (lambda () + (dispatch-event + (make-event 'key-press '(key tab))))) + (let ((file (completing-read "Choose file: " + (mapcar 'list matches) + nil t))) + (if (or (eq file nil) (equal file "")) + (message "No file selected.") + (find-file (concat directory file)))))))) + +(defun find-recursive-directory-relative-files (directory + relative-directory + file-regexp) + (let* ((full-dir (concat directory "/" relative-directory)) + (matches + (mapcar + (function (lambda (x) + (concat relative-directory x))) + (find-recursive-filter-out '(nil) + (directory-files full-dir nil + file-regexp nil t)))) + (inner + (mapcar + (function + (lambda (dir) + (find-recursive-directory-relative-files directory + (concat relative-directory + dir "/") + file-regexp))) + (find-recursive-filter-out '(nil "\\." "\\.\\.") + (directory-files full-dir nil ".*" + nil 'directories))))) + (mapcar (function (lambda (dir) (setq matches (append matches dir)))) + inner) + matches)) + +(defun find-recursive-filter-out (remove-list list) + "Remove all the elements in *remove-list* from *list*" + (if (eq list nil) + nil + (let ((elem (car list)) + (rest (cdr list))) + (if (some + (lambda (regexp) + (if (or (eq elem nil) (eq regexp nil)) + nil + (not (eq (string-match regexp elem) nil)))) + remove-list) + (find-recursive-filter-out remove-list rest) + (cons elem (find-recursive-filter-out remove-list rest)))))) + +(defvar find-recursive-running-xemacs (string-match "XEmacs\\|Lucid" emacs-version)) + +(if find-recursive-running-xemacs + nil + (defadvice directory-files (after + directory-files-xemacs + (dirname &optional full match nosort files-only) + activate) + "Add an additional argument, FILES-ONLY to the list of arguments +for GNU Emacs. If the symbol is t, then only the files in the +directory will be returned. If FILES-ONLY is nil, then both files and +directories are selected. If FILES-ONLY is not nil and not t, then +only sundirectories are returned." + (setq ad-return-value + (cond ((null files-only) ad-return-value) + ((eq files-only t) + (find-recursive-remove-if (lambda (f) + (file-directory-p + (concat dirname "/" f))) + ad-return-value)) + (t + (find-recursive-remove-if (lambda (f) + (not (file-directory-p + (concat dirname "/" f)))) + ad-return-value))))) + + (defun find-recursive-remove-if (func list) + "Removes all elements satisfying FUNC from LIST." + (let ((result nil)) + (while list + (if (not (funcall func (car list))) + (setq result (cons (car list) result))) + (setq list (cdr list))) + (nreverse result)))) + +(global-set-key [(control x) (meta f)] 'find-file-recursively) + +(provide 'find-recursive) diff --git a/emacs/nxhtml/alts/javascript-mozlab.el b/emacs/nxhtml/alts/javascript-mozlab.el new file mode 100644 index 0000000..bcec39b --- /dev/null +++ b/emacs/nxhtml/alts/javascript-mozlab.el @@ -0,0 +1,712 @@ +;;; javascript.el --- Major mode for editing JavaScript source text + +;; Copyright (C) 2006 Karl Landström + +;; Author: Karl Landström +;; Maintainer: Karl Landström +;; Version: 2.0 Beta 8 +;; Date: 2006-12-26 +;; Keywords: languages, oop + +;; This file is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; This file is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: +;; +;; The main features of this JavaScript mode are syntactic +;; highlighting (enabled with `font-lock-mode' or +;; `global-font-lock-mode'), automatic indentation and filling of +;; comments. +;; +;; This package has (only) been tested with GNU Emacs 21.4 (the latest +;; stable release). +;; +;; Installation: +;; +;; Put this file in a directory where Emacs can find it (`C-h v +;; load-path' for more info). Then add the following lines to your +;; Emacs initialization file: +;; +;; (add-to-list 'auto-mode-alist '("\\.js\\'" . javascript-mode)) +;; (autoload 'javascript-mode "javascript" nil t) +;; +;; General Remarks: +;; +;; This mode assumes that block comments are not nested inside block +;; comments and that strings do not contain line breaks. +;; +;; Exported names start with "javascript-" whereas private names start +;; with "js-". +;; +;; Changes: +;; +;; See javascript.el.changelog. + +;;; Code: + +(require 'cc-mode) +(require 'font-lock) +(require 'newcomment) + +(defgroup javascript nil + "Customization variables for `javascript-mode'." + :tag "JavaScript" + :group 'languages) + +(defcustom javascript-indent-level 4 + "Number of spaces for each indentation step." + :type 'integer + :group 'javascript) + +(defcustom javascript-auto-indent-flag t + "Automatic indentation with punctuation characters. If non-nil, the +current line is indented when certain punctuations are inserted." + :type 'boolean + :group 'javascript) + + +;; --- Keymap --- + +(defvar javascript-mode-map nil + "Keymap used in JavaScript mode.") + +(unless javascript-mode-map + (setq javascript-mode-map (make-sparse-keymap))) + +(when javascript-auto-indent-flag + (mapc (lambda (key) + (define-key javascript-mode-map key 'javascript-insert-and-indent)) + '("{" "}" "(" ")" ":" ";" ","))) + +(defun javascript-insert-and-indent (key) + "Run command bound to key and indent current line. Runs the command +bound to KEY in the global keymap and indents the current line." + (interactive (list (this-command-keys))) + (call-interactively (lookup-key (current-global-map) key)) + (indent-according-to-mode)) + + +;; --- Syntax Table And Parsing --- + +(defvar javascript-mode-syntax-table + (let ((table (make-syntax-table))) + (c-populate-syntax-table table) + + ;; The syntax class of underscore should really be `symbol' ("_") + ;; but that makes matching of tokens much more complex as e.g. + ;; "\\" matches part of e.g. "_xyz" and "xyz_abc". Defines + ;; it as word constituent for now. + (modify-syntax-entry ?_ "w" table) + + table) + "Syntax table used in JavaScript mode.") + + +(defun js-re-search-forward-inner (regexp &optional bound count) + "Auxiliary function for `js-re-search-forward'." + (let ((parse) + (saved-point (point-min))) + (while (> count 0) + (re-search-forward regexp bound) + (setq parse (parse-partial-sexp saved-point (point))) + (cond ((nth 3 parse) + (re-search-forward + (concat "\\([^\\]\\|^\\)" (string (nth 3 parse))) + (save-excursion (end-of-line) (point)) t)) + ((nth 7 parse) + (forward-line)) + ((or (nth 4 parse) + (and (eq (char-before) ?\/) (eq (char-after) ?\*))) + (re-search-forward "\\*/")) + (t + (setq count (1- count)))) + (setq saved-point (point)))) + (point)) + + +(defun js-re-search-forward (regexp &optional bound noerror count) + "Search forward but ignore strings and comments. Invokes +`re-search-forward' but treats the buffer as if strings and +comments have been removed." + (let ((saved-point (point)) + (search-expr + (cond ((null count) + '(js-re-search-forward-inner regexp bound 1)) + ((< count 0) + '(js-re-search-backward-inner regexp bound (- count))) + ((> count 0) + '(js-re-search-forward-inner regexp bound count))))) + (condition-case err + (eval search-expr) + (search-failed + (goto-char saved-point) + (unless noerror + (error (error-message-string err))))))) + + +(defun js-re-search-backward-inner (regexp &optional bound count) + "Auxiliary function for `js-re-search-backward'." + (let ((parse) + (saved-point (point-min))) + (while (> count 0) + (re-search-backward regexp bound) + (when (and (> (point) (point-min)) + (save-excursion (backward-char) (looking-at "/[/*]"))) + (forward-char)) + (setq parse (parse-partial-sexp saved-point (point))) + (cond ((nth 3 parse) + (re-search-backward + (concat "\\([^\\]\\|^\\)" (string (nth 3 parse))) + (save-excursion (beginning-of-line) (point)) t)) + ((nth 7 parse) + (goto-char (nth 8 parse))) + ((or (nth 4 parse) + (and (eq (char-before) ?/) (eq (char-after) ?*))) + (re-search-backward "/\\*")) + (t + (setq count (1- count)))))) + (point)) + + +(defun js-re-search-backward (regexp &optional bound noerror count) + "Search backward but ignore strings and comments. Invokes +`re-search-backward' but treats the buffer as if strings and +comments have been removed." + (let ((saved-point (point)) + (search-expr + (cond ((null count) + '(js-re-search-backward-inner regexp bound 1)) + ((< count 0) + '(js-re-search-forward-inner regexp bound (- count))) + ((> count 0) + '(js-re-search-backward-inner regexp bound count))))) + (condition-case err + (eval search-expr) + (search-failed + (goto-char saved-point) + (unless noerror + (error (error-message-string err))))))) + + +(defun js-continued-var-decl-list-p () + "Return non-nil if point is inside a continued variable declaration +list." + (interactive) + (let ((start (save-excursion (js-re-search-backward "\\" nil t)))) + (and start + (save-excursion (re-search-backward "\n" start t)) + (not (save-excursion + (js-re-search-backward + ";\\|[^, \t][ \t]*\\(/[/*]\\|$\\)" start t)))))) + + +;; --- Font Lock --- + +(defun js-inside-param-list-p () + "Return non-nil if point is inside a function parameter list." + (condition-case err + (save-excursion + (up-list -1) + (and (looking-at "(") + (progn (backward-word 1) + (or (looking-at "function") + (progn (backward-word 1) (looking-at "function")))))) + (error nil))) + + +(defconst js-function-heading-1-re + "^[ \t]*function[ \t]+\\(\\w+\\)" + "Regular expression matching the start of a function header.") + +(defconst js-function-heading-2-re + "^[ \t]*\\(\\w+\\)[ \t]*:[ \t]*function\\>" + "Regular expression matching the start of a function entry in + an associative array.") + +(defconst js-keyword-re + (regexp-opt '("abstract" "break" "case" "catch" "class" "const" + "continue" "debugger" "default" "delete" "do" "else" + "enum" "export" "extends" "final" "finally" "for" + "function" "goto" "if" "implements" "import" "in" + "instanceof" "interface" "native" "new" "package" + "private" "protected" "public" "return" "static" + "super" "switch" "synchronized" "this" "throw" + "throws" "transient" "try" "typeof" "var" "void" + "volatile" "while" "with" + "let") 'words) + "Regular expression matching any JavaScript keyword.") + +(defconst js-basic-type-re + (regexp-opt '("boolean" "byte" "char" "double" "float" "int" "long" + "short" "void") 'words) + "Regular expression matching any predefined type in JavaScript.") + +(defconst js-constant-re + (regexp-opt '("false" "null" "true") 'words) + "Regular expression matching any future reserved words in JavaScript.") + + +(defconst js-font-lock-keywords-1 + (list + "\\" + (list js-function-heading-1-re 1 font-lock-function-name-face) + (list js-function-heading-2-re 1 font-lock-function-name-face) + (list "[=(][ \t]*\\(/.*?[^\\]/\\w*\\)" 1 font-lock-string-face)) + "Level one font lock.") + +(defconst js-font-lock-keywords-2 + (append js-font-lock-keywords-1 + (list (list js-keyword-re 1 font-lock-keyword-face) + (cons js-basic-type-re font-lock-type-face) + (cons js-constant-re font-lock-constant-face))) + "Level two font lock.") + + +;; Limitations with variable declarations: There seems to be no +;; sensible way to highlight variables occuring after an initialized +;; variable in a variable list. For instance, in +;; +;; var x, y = f(a, b), z +;; +;; z will not be highlighted. + +(defconst js-font-lock-keywords-3 + (append + js-font-lock-keywords-2 + (list + + ;; variable declarations + (list + (concat "\\<\\(const\\|var\\)\\>\\|" js-basic-type-re) + (list "\\(\\w+\\)[ \t]*\\([=;].*\\|,\\|/[/*]\\|$\\)" + nil + nil + '(1 font-lock-variable-name-face))) + + ;; continued variable declaration list + (list + (concat "^[ \t]*\\w+[ \t]*\\([,;=]\\|/[/*]\\|$\\)") + (list "\\(\\w+\\)[ \t]*\\([=;].*\\|,\\|/[/*]\\|$\\)" + '(if (save-excursion (backward-char) (js-continued-var-decl-list-p)) + (backward-word 1) + (end-of-line)) + '(end-of-line) + '(1 font-lock-variable-name-face))) + + ;; formal parameters + (list + (concat "\\\\([ \t]+\\w+\\)?[ \t]*([ \t]*\\w") + (list "\\(\\w+\\)\\([ \t]*).*\\)?" + '(backward-char) + '(end-of-line) + '(1 font-lock-variable-name-face))) + + ;; continued formal parameter list + (list + (concat "^[ \t]*\\w+[ \t]*[,)]") + (list "\\w+" + '(if (save-excursion (backward-char) (js-inside-param-list-p)) + (backward-word 1) + (end-of-line)) + '(end-of-line) + '(0 font-lock-variable-name-face))))) + "Level three font lock.") + +(defconst js-font-lock-keywords + '(js-font-lock-keywords-3 js-font-lock-keywords-1 js-font-lock-keywords-2 + js-font-lock-keywords-3) + "See `font-lock-keywords'.") + + +;; --- Indentation --- + +(defconst js-possibly-braceless-keyword-re + (regexp-opt + '("catch" "do" "else" "finally" "for" "if" "try" "while" "with" "let") + 'words) + "Regular expression matching keywords that are optionally + followed by an opening brace.") + +(defconst js-indent-operator-re + (concat "[-+*/%<>=&^|?:.]\\([^-+*/]\\|$\\)\\|" + (regexp-opt '("in" "instanceof") 'words)) + "Regular expression matching operators that affect indentation + of continued expressions.") + + +(defun js-looking-at-operator-p () + "Return non-nil if text after point is an operator (that is not +a comma)." + (save-match-data + (and (looking-at js-indent-operator-re) + (or (not (looking-at ":")) + (save-excursion + (and (js-re-search-backward "[?:{]\\|\\" nil t) + (looking-at "?"))))))) + + +(defun js-continued-expression-p () + "Returns non-nil if the current line continues an expression." + (save-excursion + (back-to-indentation) + (or (js-looking-at-operator-p) + (and (js-re-search-backward "\n" nil t) + (progn + (skip-chars-backward " \t") + (backward-char) + (and (> (point) (point-min)) + (save-excursion (backward-char) (not (looking-at "[/*]/"))) + (js-looking-at-operator-p) + (and (progn (backward-char) + (not (looking-at "++\\|--\\|/[/*]")))))))))) + + +(defun js-end-of-do-while-loop-p () + "Returns non-nil if word after point is `while' of a do-while +statement, else returns nil. A braceless do-while statement +spanning several lines requires that the start of the loop is +indented to the same column as the current line." + (interactive) + (save-excursion + (save-match-data + (when (looking-at "\\s-*\\") + (if (save-excursion + (skip-chars-backward "[ \t\n]*}") + (looking-at "[ \t\n]*}")) + (save-excursion + (backward-list) (backward-word 1) (looking-at "\\")) + (js-re-search-backward "\\" (point-at-bol) t) + (or (looking-at "\\") + (let ((saved-indent (current-indentation))) + (while (and (js-re-search-backward "^[ \t]*\\<" nil t) + (/= (current-indentation) saved-indent))) + (and (looking-at "[ \t]*\\") + (not (js-re-search-forward + "\\" (point-at-eol) t)) + (= (current-indentation) saved-indent))))))))) + + +(defun js-ctrl-statement-indentation () + "Returns the proper indentation of the current line if it +starts the body of a control statement without braces, else +returns nil." + (save-excursion + (back-to-indentation) + (when (save-excursion + (and (not (looking-at "[{]")) + (progn + (js-re-search-backward "[[:graph:]]" nil t) + (forward-char) + (when (= (char-before) ?\)) (backward-list)) + (skip-syntax-backward " ") + (skip-syntax-backward "w") + (looking-at js-possibly-braceless-keyword-re)) + (not (js-end-of-do-while-loop-p)))) + (save-excursion + (goto-char (match-beginning 0)) + (+ (current-indentation) javascript-indent-level))))) + + +(defun js-proper-indentation (parse-status) + "Return the proper indentation for the current line." + (save-excursion + (back-to-indentation) + (let ((ctrl-stmt-indent (js-ctrl-statement-indentation)) + (same-indent-p (looking-at "[]})]\\|\\\\|\\")) + (continued-expr-p (js-continued-expression-p))) + (cond (ctrl-stmt-indent) + ((js-continued-var-decl-list-p) + (js-re-search-backward "\\" nil t) + (+ (current-indentation) javascript-indent-level)) + ((nth 1 parse-status) + (goto-char (nth 1 parse-status)) + (if (looking-at "[({[][ \t]*\\(/[/*]\\|$\\)") + (progn + (skip-syntax-backward " ") + (when (= (char-before) ?\)) (backward-list)) + (back-to-indentation) + (cond (same-indent-p + (current-column)) + (continued-expr-p + (+ (current-column) (* 2 javascript-indent-level))) + (t + (+ (current-column) javascript-indent-level)))) + (unless same-indent-p + (forward-char) + (skip-chars-forward " \t")) + (current-column))) + (continued-expr-p javascript-indent-level) + (t 0))))) + + +(defun javascript-indent-line () + "Indent the current line as JavaScript source text." + (interactive) + (let ((parse-status + (save-excursion (parse-partial-sexp (point-min) (point-at-bol)))) + (offset (- (current-column) (current-indentation)))) + (when (not (nth 8 parse-status)) + (indent-line-to (js-proper-indentation parse-status)) + (when (> offset 0) (forward-char offset))))) + + +;; --- Filling --- + +;; FIXME: It should be possible to use the more sofisticated function +;; `c-fill-paragraph' in `cc-cmds.el' instead. However, just setting +;; `fill-paragraph-function' to `c-fill-paragraph' does not work; +;; inside `c-fill-paragraph', `fill-paragraph-function' evaluates to +;; nil!? + +(defun js-backward-paragraph () + "Move backward to start of paragraph. Postcondition: Point is at +beginning of buffer or the previous line contains only whitespace." + (forward-line -1) + (while (not (or (bobp) (looking-at "^[ \t]*$"))) + (forward-line -1)) + (when (not (bobp)) (forward-line 1))) + + +(defun js-forward-paragraph () + "Move forward to end of paragraph. Postcondition: Point is at +end of buffer or the next line contains only whitespace." + (forward-line 1) + (while (not (or (eobp) (looking-at "^[ \t]*$"))) + (forward-line 1)) + (when (not (eobp)) (backward-char 1))) + + +(defun js-fill-block-comment-paragraph (parse-status justify) + "Fill current paragraph as a block comment. PARSE-STATUS is the +result of `parse-partial-regexp' from beginning of buffer to +point. JUSTIFY has the same meaning as in `fill-paragraph'." + (let ((offset (save-excursion + (goto-char (nth 8 parse-status)) (current-indentation)))) + (save-excursion + (save-restriction + (narrow-to-region (save-excursion + (goto-char (nth 8 parse-status)) (point-at-bol)) + (save-excursion + (goto-char (nth 8 parse-status)) + (re-search-forward "*/"))) + (narrow-to-region (save-excursion + (js-backward-paragraph) + (when (looking-at "^[ \t]*$") (forward-line 1)) + (point)) + (save-excursion + (js-forward-paragraph) + (when (looking-at "^[ \t]*$") (backward-char)) + (point))) + (goto-char (point-min)) + (while (not (eobp)) + (delete-horizontal-space) + (forward-line 1)) + (let ((fill-column (- fill-column offset)) + (fill-paragraph-function nil)) + (fill-paragraph justify)) + + ;; In Emacs 21.4 as opposed to CVS Emacs 22, + ;; `fill-paragraph' seems toadd a newline at the end of the + ;; paragraph. Remove it! + (goto-char (point-max)) + (when (looking-at "^$") (backward-delete-char 1)) + + (goto-char (point-min)) + (while (not (eobp)) + (indent-to offset) + (forward-line 1)))))) + + +(defun js-sline-comment-par-start () + "Return point at the beginning of the line where the current +single-line comment paragraph starts." + (save-excursion + (beginning-of-line) + (while (and (not (bobp)) + (looking-at "^[ \t]*//[ \t]*[[:graph:]]")) + (forward-line -1)) + (unless (bobp) (forward-line 1)) + (point))) + + +(defun js-sline-comment-par-end () + "Return point at end of current single-line comment paragraph." + (save-excursion + (beginning-of-line) + (while (and (not (eobp)) + (looking-at "^[ \t]*//[ \t]*[[:graph:]]")) + (forward-line 1)) + (unless (bobp) (backward-char)) + (point))) + + +(defun js-sline-comment-offset (line) + "Return the column at the start of the current single-line +comment paragraph." + (save-excursion + (goto-line line) + (re-search-forward "//" (point-at-eol)) + (goto-char (match-beginning 0)) + (current-column))) + + +(defun js-sline-comment-text-offset (line) + "Return the column at the start of the text of the current +single-line comment paragraph." + (save-excursion + (goto-line line) + (re-search-forward "//[ \t]*" (point-at-eol)) + (current-column))) + + +(defun js-at-empty-sline-comment-p () + "Return non-nil if inside an empty single-line comment." + (and (save-excursion + (beginning-of-line) + (not (looking-at "^.*//.*[[:graph:]]"))) + (save-excursion + (re-search-backward "//" (point-at-bol) t)))) + + +(defun js-fill-sline-comments (parse-status justify) + "Fill current paragraph as a sequence of single-line comments. +PARSE-STATUS is the result of `parse-partial-regexp' from +beginning of buffer to point. JUSTIFY has the same meaning as in +`fill-paragraph'." + (when (not (js-at-empty-sline-comment-p)) + (let* ((start (js-sline-comment-par-start)) + (start-line (1+ (count-lines (point-min) start))) + (end (js-sline-comment-par-end)) + (offset (js-sline-comment-offset start-line)) + (text-offset (js-sline-comment-text-offset start-line))) + (save-excursion + (save-restriction + (narrow-to-region start end) + (goto-char (point-min)) + (while (re-search-forward "^[ \t]*//[ \t]*" nil t) + (replace-match "") + (forward-line 1)) + (let ((fill-paragraph-function nil) + (fill-column (- fill-column text-offset))) + (fill-paragraph justify)) + + ;; In Emacs 21.4 as opposed to CVS Emacs 22, + ;; `fill-paragraph' seems toadd a newline at the end of the + ;; paragraph. Remove it! + (goto-char (point-max)) + (when (looking-at "^$") (backward-delete-char 1)) + + (goto-char (point-min)) + (while (not (eobp)) + (indent-to offset) + (insert "//") + (indent-to text-offset) + (forward-line 1))))))) + + +(defun js-trailing-comment-p (parse-status) + "Return non-nil if inside a trailing comment. PARSE-STATUS is +the result of `parse-partial-regexp' from beginning of buffer to +point." + (save-excursion + (when (nth 4 parse-status) + (goto-char (nth 8 parse-status)) + (skip-chars-backward " \t") + (not (bolp))))) + + +(defun js-block-comment-p (parse-status) + "Return non-nil if inside a block comment. PARSE-STATUS is the +result of `parse-partial-regexp' from beginning of buffer to +point." + (save-excursion + (save-match-data + (when (nth 4 parse-status) + (goto-char (nth 8 parse-status)) + (looking-at "/\\*"))))) + + +(defun javascript-fill-paragraph (&optional justify) + "If inside a comment, fill the current comment paragraph. +Trailing comments are ignored." + (interactive) + (let ((parse-status (parse-partial-sexp (point-min) (point)))) + (when (and (nth 4 parse-status) + (not (js-trailing-comment-p parse-status))) + (if (js-block-comment-p parse-status) + (js-fill-block-comment-paragraph parse-status justify) + (js-fill-sline-comments parse-status justify)))) + t) + + +;; --- Imenu --- + +(defconst js-imenu-generic-expression + (list + (list + nil + "function\\s-+\\(\\w+\\)\\s-*(" + 1)) + "Regular expression matching top level procedures. Used by imenu.") + + +;; --- Main Function --- + +;;;###autoload +(defun javascript-mode () + "Major mode for editing JavaScript source text. + +Key bindings: + +\\{javascript-mode-map}" + (interactive) + (kill-all-local-variables) + + (use-local-map javascript-mode-map) + (set-syntax-table javascript-mode-syntax-table) + (set (make-local-variable 'indent-line-function) 'javascript-indent-line) + (set (make-local-variable 'font-lock-defaults) (list js-font-lock-keywords)) + + (set (make-local-variable 'parse-sexp-ignore-comments) t) + + ;; Comments + (setq comment-start "// ") + (setq comment-end "") + (set (make-local-variable 'fill-paragraph-function) + 'javascript-fill-paragraph) + + ;; Make c-mark-function work + (setq c-nonsymbol-token-regexp "!=\\|%=\\|&[&=]\\|\\*[/=]\\|\\+[+=]\\|-[=-]\\|/[*/=]\\|<\\(?:<=\\|[<=]\\)\\|==\\|>\\(?:>\\(?:>=\\|[=>]\\)\\|[=>]\\)\\|\\^=\\||[=|]\\|[]!%&(-,./:-?[{-~^-]" + c-stmt-delim-chars "^;{}?:" + c-syntactic-ws-end "[ \n + \f/]" + c-syntactic-eol "\\(\\s \\|/\\*\\([^*\n +]\\|\\*[^/\n +]\\)*\\*/\\)*\\(\\(/\\*\\([^*\n +]\\|\\*[^/\n +]\\)*\\|\\\\\\)?$\\|//\\)") + + ;; Imenu + (setq imenu-case-fold-search nil) + (set (make-local-variable 'imenu-generic-expression) + js-imenu-generic-expression) + + (setq major-mode 'javascript-mode) + (setq mode-name "JavaScript") + (run-hooks 'javascript-mode-hook)) + + +(provide 'javascript-mode) +;;; javascript.el ends here diff --git a/emacs/nxhtml/alts/smarty-mode-vdebout.el b/emacs/nxhtml/alts/smarty-mode-vdebout.el new file mode 100644 index 0000000..94d7352 --- /dev/null +++ b/emacs/nxhtml/alts/smarty-mode-vdebout.el @@ -0,0 +1,2715 @@ +;;; smarty-mode.el --- major mode for editing Smarty templates + +;; Author: Vincent DEBOUT +;; Maintainer: Vincent DEBOUT +;; Keywords: languages smarty templates +;; WWW: http://deboutv.free.fr/lisp/smarty/ + +;;; License + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License +;; as published by the Free Software Foundation; either version 2 +;; of the License, or (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, write to the Free Software +;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +;;; History + +;; $Log: smarty-mode.el,v $ +;; Revision 1.6 2006/12/16 19:54:26 vincent +;; Update release version +;; +;; Revision 1.5 2006/12/16 19:53:00 vincent +;; Fix bug #15 +;; +;; Revision 1.4 2006/12/16 14:59:46 vincent +;; Fix bugs for release +;; +;; Revision 1.3 2006/11/19 12:29:53 vincent +;; Fix highlight bug, add templates +;; +;; Revision 1.2 2006/11/12 11:44:18 vincent +;; First release commit +;; + +(defconst smarty-version "0.0.4" + "Smarty Mode version number.") + +(defconst smarty-time-stamp "2006-12-16" + "Smarty Mode time stamp for last update.") + +(require 'font-lock) +(require 'cc-mode) +(require 'custom) +(require 'etags) +(eval-when-compile +(require 'regexp-opt)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Customization +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defgroup smarty nil + "Customizations for Smarty mode." + :prefix "smarty-" + :group 'languages) + +(defgroup smarty-mode nil + "Customizations for Smarty mode." + :group 'smarty) + +(defcustom smarty-electric-mode t + "*Non-nil enables electrification (automatic template generation). +If nil, template generators can still be invoked through key bindings and +menu. Is indicated in the modeline by \"/e\" after the mode name and can be +toggled by `\\[smarty-electric-mode]'." + :type 'boolean + :group 'smarty-mode) + +(defcustom smarty-stutter-mode t + "*Non-nil enables stuttering. +Is indicated in the modeline by \"/s\" after the mode name and can be toggled +by `\\[smarty-stutter-mode]'." + :type 'boolean + :group 'smarty-mode) + +(defgroup smarty-menu nil + "Customizations for menues." + :group 'smarty) + +(defcustom smarty-source-file-menu t + "*Non-nil means add a menu of all source files in current directory." + :type 'boolean + :group 'smarty-menu) + +(defgroup smarty-highlight nil + "Customizations for highlight." + :group 'smarty) + +(defcustom smarty-highlight-plugin-functions t + "*Non-nil means highlight the plugin functions in the buffer." + :type 'boolean + :group 'smarty-highlight) + +(defgroup smarty-template nil + "Customizations for templates." + :group 'smarty) + +(defgroup smarty-header nil + "Customizations for header template." + :group 'smarty-template) + +(defcustom smarty-file-header "" + "*String or file to insert as file header. +If the string specifies an existing file name, the contents of the file is +inserted, otherwise the string itself is inserted as file header. +Type `C-j' for newlines. +If the header contains RCS keywords, they may be written as Keyword +if the header needs to be version controlled. + +The following keywords for template generation are supported: + : replaced by the name of the buffer + : replaced by the user name and email address + \(`user-full-name',`mail-host-address', `user-mail-address') + : replaced by user login name (`user-login-name') + : replaced by contents of option `smarty-company-name' + : replaced by the current date + : replaced by the current year + : replaced by copyright string (`smarty-copyright-string') + : final cursor position." + :type 'string + :group 'smarty-header) + +(defcustom smarty-file-footer "" + "*String or file to insert as file footer. +If the string specifies an existing file name, the contents of the file is +inserted, otherwise the string itself is inserted as file footer (i.e. at +the end of the file). +Type `C-j' for newlines. +The same keywords as in option `smarty-file-header' can be used." + :type 'string + :group 'smarty-header) + +(defcustom smarty-company-name "" + "*Name of company to insert in file header. +See option `smarty-file-header'." + :type 'string + :group 'smarty-header) + +(defcustom smarty-copyright-string "" + "*Copyright string to insert in file header. +Can be multi-line string (type `C-j' for newline) and contain other file +header keywords (see option `smarty-file-header')." + :type 'string + :group 'smarty-header) + +(defcustom smarty-date-format "%Y-%m-%d" + "*Specifies the date format to use in the header. +This string is passed as argument to the command `format-time-string'. +For more information on format strings, see the documentation for the +`format-time-string' command (C-h f `format-time-string')." + :type 'string + :group 'smarty-header) + +(defcustom smarty-modify-date-prefix-string "" + "*Prefix string of modification date in Smarty file header. +If actualization of the modification date is called (menu, +`\\[smarty-template-modify]'), this string is searched and the rest +of the line replaced by the current date." + :type 'string + :group 'smarty-header) + +(defcustom smarty-modify-date-on-saving nil + "*Non-nil means update the modification date when the buffer is saved. +Calls function `\\[smarty-template-modify]'). + +NOTE: Activate the new setting in a Smarty buffer by using the menu entry + \"Activate Options\"." + :type 'boolean + :group 'smarty-header) + +(defgroup smarty-misc nil + "Miscellaneous customizations." + :group 'smarty) + +(defcustom smarty-left-delimiter "{" + "Left escaping delimiter." + :type 'string + :group 'smarty-misc) + +(defcustom smarty-right-delimiter "}" + "Right escaping delimiter." + :type 'string + :group 'smarty-misc) + +(defcustom smarty-intelligent-tab t + "*Non-nil means `TAB' does indentation, word completion and tab insertion. +That is, if preceding character is part of a word then complete word, +else if not at beginning of line then insert tab, +else if last command was a `TAB' or `RET' then dedent one step, +else indent current line (i.e. `TAB' is bound to `smarty-electric-tab'). +If nil, TAB always indents current line (i.e. `TAB' is bound to +`indent-according-to-mode'). + +NOTE: Activate the new setting in a Smarty buffer by using the menu entry + \"Activate Options\"." + :type 'boolean + :group 'smarty-misc) + +(defcustom smarty-word-completion-in-minibuffer t + "*Non-nil enables word completion in minibuffer (for template prompts). + +NOTE: Activate the new setting by restarting Emacs." + :type 'boolean + :group 'smarty-misc) + +(defcustom smarty-word-completion-case-sensitive nil + "*Non-nil means word completion using `TAB' is case sensitive. +That is, `TAB' completes words that start with the same letters and case. +Otherwise, case is ignored." + :type 'boolean + :group 'smarty-misc) + +;; Functions + +(defun smarty-customize () + "Call the customize function with `smarty' as argument." + (interactive) + (customize-browse 'smarty)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Variables +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defvar smarty-menu-max-size 20 + "*Specifies the maximum size of a menu before splitting it into submenues.") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Menu tools functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun smarty-menu-split (list title) + "Split menu LIST into several submenues, if number of +elements > `smarty-menu-max-size'." + (if (> (length list) smarty-menu-max-size) + (let ((remain list) + (result '()) + (sublist '()) + (menuno 1) + (i 0)) + (while remain + (setq sublist (cons (car remain) sublist)) + (setq remain (cdr remain)) + (setq i (+ i 1)) + (if (= i smarty-menu-max-size) + (progn + (setq result (cons (cons (format "%s %s" title menuno) + (nreverse sublist)) result)) + (setq i 0) + (setq menuno (+ menuno 1)) + (setq sublist '())))) + (and sublist + (setq result (cons (cons (format "%s %s" title menuno) + (nreverse sublist)) result))) + (nreverse result)) + list)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Source file menu +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defvar smarty-sources-menu nil) + +;; Create the source menu +(defun smarty-add-source-files-menu () + "Scan directory for all Smarty source files and generate menu. +The directory of the current source file is scanned." + (interactive) + (message "Scanning directory for source files ...") + (let ((newmap (current-local-map)) + (file-list (smarty-get-source-files)) + menu-list found) + ;; Create list for menu + (setq found nil) + (while file-list + (setq found t) + (setq menu-list (cons (vector (car file-list) + (list 'find-file (car file-list)) t) + menu-list)) + (setq file-list (cdr file-list))) + (setq menu-list (smarty-menu-split menu-list "Sources")) + (when found (setq menu-list (cons "--" menu-list))) + (setq menu-list (cons ["*Rescan*" smarty-add-source-files-menu t] menu-list)) + (setq menu-list (cons "Sources" menu-list)) + ;; Create menu + (easy-menu-add menu-list) + (easy-menu-define smarty-sources-menu newmap + "Smarty source files menu" menu-list)) + (message "")) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Smarty menu +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun smarty-create-mode-menu () + "Create Smarty Mode menu." + `("Smarty" + ("Templates" + ("Built-in Functions" + ["capture" smarty-template-capture t] + ["config_load" smarty-template-config-load t] + ["else" smarty-template-else t] + ["elseif" smarty-template-elseif t] + ["foreach" smarty-template-foreach t] + ["foreachelse" smarty-template-foreachelse t] + ["if" smarty-template-if t] + ["include" smarty-template-include t] + ["include_php" smarty-template-include-php t] + ["insert" smarty-template-insert t] + ["ldelim" smarty-template-ldelim t] + ["literal" smarty-template-literal t] + ["php" smarty-template-php t] + ["rdelim" smarty-template-rdelim t] + ["section" smarty-template-section t] + ["sectionelse" smarty-template-sectionelse t] + ["strip" smarty-template-strip t]) + ("Custom Functions" + ["assign" smarty-template-assign t] + ["counter" smarty-template-counter t] + ["cycle" smarty-template-cycle t] + ["debug" smarty-template-debug t] + ["eval" smarty-template-eval t] + ["fetch" smarty-template-fetch t] + ["html_checkboxes" smarty-template-html-checkboxes t] + ["html_image" smarty-template-html-image t] + ["html_options" smarty-template-html-options t] + ["html_radios" smarty-template-html-radios t] + ["html_select_date" smarty-template-html-select-date t] + ["html_select_time" smarty-template-html-select-time t] + ["html_table" smarty-template-html-table t] + ["mailto" smarty-template-mailto t] + ["math" smarty-template-math t] + ["popup" smarty-template-popup t] + ["popup_init" smarty-template-popup-init t] + ["textformat" smarty-template-textformat t]) + ("Variable Modifiers" + ["capitalize" smarty-template-capitalize t] + ["cat" smarty-template-cat t] + ["count_characters" smarty-template-count-characters t] + ["count_paragraphs" smarty-template-count-paragraphs t] + ["count_sentences" smarty-template-count-sentences t] + ["count_words" smarty-template-count-words t] + ["date_format" smarty-template-date-format t] + ["default" smarty-template-default t] + ["escape" smarty-template-escape t] + ["indent" smarty-template-indent t] + ["lower" smarty-template-lower t] + ["nl2br" smarty-template-nl2br t] + ["regex_replace" smarty-template-regex-replace t] + ["replace" smarty-template-replace t] + ["spacify" smarty-template-spacify t] + ["string_format" smarty-template-string-format t] + ["strip" smarty-template-vstrip t] + ["strip_tags" smarty-template-strip-tags t] + ["truncate" smarty-template-truncate t] + ["upper" smarty-template-upper t] + ["wordwrap" smarty-template-wordwrap t]) + ("Plugins (Functions)" + ("SmartyFormtool" + ["formtool_checkall" smarty-template-formtool-checkall t] + ["formtool_copy" smarty-template-formtool-copy t] + ["formtool_count_chars" smarty-template-formtool-count-chars t] + ["formtool_init" smarty-template-formtool-init t] + ["formtool_move" smarty-template-formtool-move t] + ["formtool_moveall" smarty-template-formtool-moveall t] + ["formtool_movedown" smarty-template-formtool-movedown t] + ["formtool_moveup" smarty-template-formtool-moveup t] + ["formtool_remove" smarty-template-formtool-remove t] + ["formtool_rename" smarty-template-formtool-rename t] + ["formtool_save" smarty-template-formtool-save t] + ["formtool_selectall" smarty-template-formtool-selectall t]) + ("SmartyPaginate" + ["paginate_first" smarty-template-paginate-first t] + ["paginate_last" smarty-template-paginate-last t] + ["paginate_middle" smarty-template-paginate-middle t] + ["paginate_next" smarty-template-paginate-next t] + ["paginate_prev" smarty-template-paginate-prev t]) + ("SmartyValidate" + ["validate" smarty-template-validate t])) + ("Plugins (Variable Modifiers)" + ("AlternativeDateModifierPlugin" + ["date_format2" smarty-template-date-formatto t]) + ("B2Smilies" + ["B2Smilies" smarty-template-btosmilies t]) + ("BBCodePlugin" + ["bbcode2html" smarty-template-bbcodetohtml t]) + ) + "--" + ["Insert Header" smarty-template-header t] + ["Insert Footer" smarty-template-footer t] + ["Insert Date" smarty-template-insert-date t] + ["Modify Date" smarty-template-modify t]) + "--" + ["Show Messages" smarty-show-messages :keys "C-c M-m"] + ["Smarty Mode Documentation" smarty-doc-mode :keys "C-c C-h"] + ["Version" smarty-version :keys "C-c C-v"] + "--" + ("Options" + ("Mode" + ["Electric Mode" + (progn (customize-set-variable 'smarty-electric-mode + (not smarty-electric-mode)) + (smarty-mode-line-update)) + :style toggle :selected smarty-electric-mode :keys "C-c C-m C-e"] + ["Stutter Mode" + (progn (customize-set-variable 'smarty-stutter-mode + (not smarty-stutter-mode)) + (smarty-mode-line-update)) + :style toggle :selected smarty-stutter-mode :keys "C-c C-m C-s"] + "--" + ["Customize Group..." (customize-group 'smarty-mode) t]) + ("Menu" + ["Source Menu" + (customize-set-variable 'smarty-source-file-menu + (not smarty-source-file-menu)) + :style toggle :selected smarty-source-file-menu] + "--" + ["Customize Group..." (customize-group 'smarty-menu) t]) + ("Highlight" + ["Highlight plugin functions" + (progn (customize-set-variable 'smarty-highlight-plugin-functions + (not smarty-highlight-plugin-functions))) + :style toggle :selected smarty-highlight-plugin-functions] + "--" + ["Customize Group..." (customize-group 'smarty-highlight) t]) + ("Template" + ("Header" + ["Header template..." + (customize-option 'smarty-file-header) t] + ["Footer template..." + (customize-option 'smarty-file-footer) t] + ["Company..." + (customize-option 'smarty-company-name) t] + ["Copyright..." + (customize-option 'smarty-copyright-string) t] + ["Date format..." + (customize-option 'smarty-date-format) t] + ["Modify date prefix..." + (customize-option 'smarty-modify-date-prefix-string) t] + ["Modify date on saving" + (customize-set-variable 'smarty-modify-date-on-saving + (not smarty-modify-date-on-saving)) + :style toggle :selected smarty-modify-date-on-saving] + "--" + ["Customize Group..." (customize-group 'smarty-header) t]) + "--" + ["Customize Group..." (customize-group 'smarty-template) t]) + ("Miscellaneous" + ["Left delimiter..." + (customize-option 'smarty-left-delimiter) t] + ["Right delimiter..." + (customize-option 'smarty-right-delimiter) t] + ["Use Intelligent Tab" + (progn (customize-set-variable 'smarty-intelligent-tab + (not smarty-intelligent-tab)) + (smarty-activate-customizations)) + :style toggle :selected smarty-intelligent-tab] + ["Word Completion in Minibuffer" + (progn (customize-set-variable 'smarty-word-completion-in-minibuffer + (not smarty-word-completion-in-minibuffer)) + (message "Activate new setting by saving options and restarting Emacs")) + :style toggle :selected smarty-word-completion-in-minibuffer] + ["Completion is case sensitive" + (customize-set-variable 'smarty-word-completion-case-sensitive + (not smarty-word-completion-case-sensitive)) + :style toggle :selected smarty-word-completion-case-sensitive] + "--" + ["Customize Group..." (customize-group 'smarty-misc) t]) + "--" + ["Save Options" customize-save-customized t] + ["Activate Options" smarty-activate-customizations t] + ["Browse Options..." smarty-customize t]))) + +(defvar smarty-mode-menu-list (smarty-create-mode-menu) + "Smarty Mode menu.") + +(defvar smarty-mode-map nil + "Keymap for Smarty Mode.") + +(defun smarty-update-mode-menu () + "Update Smarty Mode menu." + (interactive) + (easy-menu-remove smarty-mode-menu-list) + (setq smarty-mode-menu-list (smarty-create-mode-menu)) + (easy-menu-add smarty-mode-menu-list) + (easy-menu-define smarty-mode-menu smarty-mode-map + "Menu keymap for Smarty Mode." smarty-mode-menu-list)) + + + + +(defvar smarty-mode-hook nil) + +(defvar smarty-functions nil + "List of Smarty functions.") + +(defvar smarty-functions-regexp nil + "Regexp for Smarty functions.") + +(defconst smarty-01-functions + '("capture" "config_load" "foreach" "foreachelse" "include" + "include_php" "insert" "if" "elseif" "else" "ldelim" "rdelim" + "literal" "php" "section" "sectionelse" "strip" "assign" "counter" + "cycle" "debug" "eval" "fetch" "html_checkboxes" "html_image" + "html_options" "html_radios" "html_select_date" "html_select_time" + "html_table" "math" "mailto" "popup_init" "popup" "textformat") + "Smarty built-in & custom functions.") + +(defvar smarty-modifiers nil + "List of Smarty variable modifiers.") + +(defvar smarty-modifiers-regexp nil + "Regexp for Smarty variable modifiers.") + +(defconst smarty-01-modifiers + '("capitalize" "cat" "count_characters" "count_paragraphs" + "count_sentences" "count_words" "date_format" "default" + "escape" "indent" "lower" "nl2br" "regex_replace" "replace" + "spacify" "string_format" "strip" "strip_tags" "truncate" + "upper" "wordwrap") + "Smarty variable modifiers.") + +(defvar smarty-plugins-functions nil + "List of Smarty functions.") + +(defvar smarty-plugins-functions-regexp nil + "Regexp for Smarty functions.") + +(defconst smarty-01-plugins-functions + '("validate" "formtool_checkall" "formtool_copy" "formtool_count_chars" + "formtool_init" "formtool_move" "formtool_moveall" + "formtool_movedown" "formtool_moveup" "formtool_remove" + "formtool_rename" "formtool_save" "formtool_selectall" + "paginate_first" "paginate_last" "paginate_middle" + "paginate_next" "paginate_prev") + "Smarty plugins functions.") + +(defvar smarty-plugins-modifiers nil + "List of Smarty variable modifiers.") + +(defvar smarty-plugins-modifiers-regexp nil + "Regexp for Smarty functions.") + +(defconst smarty-01-plugins-modifiers + '("B2Smilies" "bbcode2html" "date_format2") + "Smarty plugins modifiers.") + +(defconst smarty-constants + (eval-when-compile + (regexp-opt + '("TRUE" "FALSE" "NULL") t)) + "Smarty constants.") + + +;; Syntax table creation +(defvar smarty-mode-syntax-table nil + "Syntax table for smarty-mode.") + +(defvar smarty-mode-ext-syntax-table nil + "Syntax table extended by `_' used in `smarty-mode' buffers.") + +(defun smarty-create-syntax-table () + (if smarty-mode-syntax-table + () + (setq smarty-mode-syntax-table (make-syntax-table)) + + ;; Make | a punctuation character + (modify-syntax-entry ?| "." smarty-mode-syntax-table) + ;; Make " a punctuation character so highlighing works withing html strings + (modify-syntax-entry ?\" "." smarty-mode-syntax-table) + ;; define parentheses to match + (modify-syntax-entry ?\( "()" smarty-mode-syntax-table) + (modify-syntax-entry ?\) ")(" smarty-mode-syntax-table) + (modify-syntax-entry ?\[ "(]" smarty-mode-syntax-table) + (modify-syntax-entry ?\] ")[" smarty-mode-syntax-table) + (modify-syntax-entry ?\{ "(}" smarty-mode-syntax-table) + (modify-syntax-entry ?\} "){" smarty-mode-syntax-table) + ) + (set-syntax-table smarty-mode-syntax-table) + ;; extended syntax table including '_' (for simpler search regexps) + (setq smarty-mode-ext-syntax-table (copy-syntax-table smarty-mode-syntax-table)) + (modify-syntax-entry ?_ "w" smarty-mode-ext-syntax-table)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; File/directory manipulation +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun smarty-directory-files (directory &optional full match) + "Call `directory-files' if DIRECTORY exists, otherwise generate error +message." + (if (not (file-directory-p directory)) + (smarty-warning-when-idle "No such directory: \"%s\"" directory) + (let ((dir (directory-files directory full match))) + (setq dir (delete "." dir)) + (setq dir (delete ".." dir)) + dir))) + +(defun smarty-get-source-files (&optional full directory) + "Get list of SMARTY source files in DIRECTORY or current directory." + (let ((mode-alist auto-mode-alist) + filename-regexp) + ;; create regular expressions for matching file names + (setq filename-regexp "\\`[^.].*\\(") + (while mode-alist + (when (eq (cdar mode-alist) 'smarty-mode) + (setq filename-regexp + (concat filename-regexp (caar mode-alist) "\\|"))) + (setq mode-alist (cdr mode-alist))) + (setq filename-regexp + (concat (substring filename-regexp 0 + (string-match "\\\\|$" filename-regexp)) "\\)")) + ;; find files + (smarty-directory-files + (or directory default-directory) full filename-regexp))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Messages reporting +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defvar smarty-warnings nil + "Warnings to tell the user during start up.") + +(defun smarty-run-when-idle (secs repeat function) + "Wait until idle, then run FUNCTION." + (if (fboundp 'start-itimer) + (start-itimer "smarty-mode" function secs repeat t) +; (run-with-idle-timer secs repeat function))) + ;; explicitely activate timer (necessary when Emacs is already idle) + (aset (run-with-idle-timer secs repeat function) 0 nil))) + +(defun smarty-warning-when-idle (&rest args) + "Wait until idle, then print out warning STRING and beep." + (if noninteractive + (smarty-warning (apply 'format args) t) + (unless smarty-warnings + (smarty-run-when-idle .1 nil 'smarty-print-warnings)) + (setq smarty-warnings (cons (apply 'format args) smarty-warnings)))) + +(defun smarty-warning (string &optional nobeep) + "Print out warning STRING and beep." + (message (concat "WARNING: " string)) + (unless (or nobeep noninteractive) (beep))) + +(defun smarty-print-warnings () + "Print out messages in variable `smarty-warnings'." + (let ((no-warnings (length smarty-warnings))) + (setq smarty-warnings (nreverse smarty-warnings)) + (while smarty-warnings + (message (concat "WARNING: " (car smarty-warnings))) + (setq smarty-warnings (cdr smarty-warnings))) + (beep) + (when (> no-warnings 1) + (message "WARNING: See warnings in message buffer (type `C-c M-m').")))) + +(defun smarty-show-messages () + "Get *Messages* buffer to show recent messages." + (interactive) + (display-buffer " *Message-Log*")) + +(defun smarty-version () + "Echo the current version of Smarty Mode in the minibuffer." + (interactive) + (message "Smarty Mode %s (%s)" smarty-version smarty-time-stamp) + (smarty-keep-region-active)) + +;; active regions +(defun smarty-keep-region-active () + "Do whatever is necessary to keep the region active in XEmacs. +Ignore byte-compiler warnings you might see." + (and (boundp 'zmacs-region-stays) + (setq zmacs-region-stays t))) + +(defmacro smarty-prepare-search-1 (&rest body) + "Enable case insensitive search and switch to syntax table that includes '_', +then execute BODY, and finally restore the old environment. Used for +consistent searching." + `(let ((case-fold-search t) ; case insensitive search + (current-syntax-table (syntax-table)) + result + (restore-prog ; program to restore enviroment + '(progn + ;; restore syntax table + (set-syntax-table current-syntax-table)))) + ;; use extended syntax table + (set-syntax-table smarty-mode-ext-syntax-table) + ;; execute BODY safely + (setq result + (condition-case info + (progn ,@body) + (error (eval restore-prog) ; restore environment on error + (error (cadr info))))) ; pass error up + ;; restore environment + (eval restore-prog) + result)) + +(defmacro smarty-prepare-search-2 (&rest body) + "Enable case insensitive search, switch to syntax table that includes '_', +and remove `intangible' overlays, then execute BODY, and finally restore the +old environment. Used for consistent searching." + `(let ((case-fold-search t) ; case insensitive search + (current-syntax-table (syntax-table)) + result overlay-all-list overlay-intangible-list overlay + (restore-prog ; program to restore enviroment + '(progn + ;; restore syntax table + (set-syntax-table current-syntax-table) + ;; restore `intangible' overlays + (when (fboundp 'overlay-lists) + (while overlay-intangible-list + (overlay-put (car overlay-intangible-list) 'intangible t) + (setq overlay-intangible-list + (cdr overlay-intangible-list))))))) + ;; use extended syntax table + (set-syntax-table smarty-mode-ext-syntax-table) + ;; remove `intangible' overlays + (when (fboundp 'overlay-lists) + (setq overlay-all-list (overlay-lists)) + (setq overlay-all-list + (append (car overlay-all-list) (cdr overlay-all-list))) + (while overlay-all-list + (setq overlay (car overlay-all-list)) + (when (memq 'intangible (overlay-properties overlay)) + (setq overlay-intangible-list + (cons overlay overlay-intangible-list)) + (overlay-put overlay 'intangible nil)) + (setq overlay-all-list (cdr overlay-all-list)))) + ;; execute BODY safely + (setq result + (condition-case info + (progn ,@body) + (error (eval restore-prog) ; restore environment on error + (error (cadr info))))) ; pass error up + ;; restore environment + (eval restore-prog) + result)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Enabling/disabling + +(defun smarty-mode-line-update () + "Update the modeline string for Smarty major mode." + (setq mode-name (concat "Smarty" + (and (or smarty-electric-mode smarty-stutter-mode) "/") + (and smarty-electric-mode "e") + (and smarty-stutter-mode "s"))) + (force-mode-line-update t)) + +(defun smarty-electric-mode (arg) + "Toggle Smarty electric mode. +Turn on if ARG positive, turn off if ARG negative, toggle if ARG zero or nil." + (interactive "P") + (setq smarty-electric-mode + (cond ((or (not arg) (zerop arg)) (not smarty-electric-mode)) + ((> arg 0) t) (t nil))) + (smarty-mode-line-update)) + +(defun smarty-stutter-mode (arg) + "Toggle Smarty stuttering mode. +Turn on if ARG positive, turn off if ARG negative, toggle if ARG zero or nil." + (interactive "P") + (setq smarty-stutter-mode + (cond ((or (not arg) (zerop arg)) (not smarty-stutter-mode)) + ((> arg 0) t) (t nil))) + (smarty-mode-line-update)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Smarty code delimitation +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun smarty-in-literal () + "Determine if point is in a Smarty literal." + (save-excursion + (let ((here (point)) + start state) + (beginning-of-line) + (setq start (point)) + (goto-char here) + (setq state (parse-partial-sexp start (point))) + (cond + ((nth 3 state) 'string) + ((nth 4 state) 'comment) + (t nil))))) + +(defun smarty-in-comment-p () + "Check if point is in a comment." + (let ((result nil) (here (point-marker)) found) + (save-excursion + (setq found (re-search-backward (regexp-quote (concat smarty-left-delimiter "*")) nil t)) + (when found + (setq result (re-search-forward (regexp-quote (concat "*" smarty-right-delimiter)) here t)) + (setq result (not result)))) + result)) + +(defun smarty-after-ldelim () + "Check that the previous character is the left delimiter." + (let ((here (point-marker)) ldelim-found ldelim-point) + (save-excursion + (setq ldelim-found (re-search-backward (regexp-quote smarty-left-delimiter) nil t)) + (re-search-forward (regexp-quote smarty-left-delimiter) here t) + (setq ldelim-point (point-marker)) + (goto-char here) + (if (and (= here ldelim-point) ldelim-found) + t + nil)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Words to expand +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun smarty-words-init () + "Initialize reserved words." + (setq smarty-functions smarty-01-functions) + (setq smarty-modifiers smarty-01-modifiers) + (setq smarty-plugins-functions smarty-01-plugins-functions) + (setq smarty-plugins-modifiers smarty-01-plugins-modifiers) + (setq smarty-functions-regexp (concat "\\<\\(" (regexp-opt smarty-functions) "\\)\\>")) + (setq smarty-modifiers-regexp (concat "\\<\\(" (regexp-opt smarty-modifiers) "\\)\\>")) + (setq smarty-plugins-functions-regexp (concat "\\<\\(" (regexp-opt smarty-plugins-functions) "\\)\\>")) + (setq smarty-plugins-modifiers-regexp (concat "\\<\\(" (regexp-opt smarty-plugins-modifiers) "\\)\\>")) + (smarty-abbrev-list-init)) + +(defvar smarty-abbrev-list nil + "Predefined abbreviations for Smarty.") + +(defun smarty-abbrev-list-init () + (setq smarty-abbrev-list + (append + (list nil) smarty-functions + (list nil) smarty-modifiers + (list nil) smarty-plugins-functions + (list nil) smarty-plugins-modifiers))) + +(defvar smarty-expand-upper-case nil) + +(defun smarty-try-expand-abbrev (old) + "Try expanding abbreviations from `smarty-abbrev-list'." + (unless old + (he-init-string (he-dabbrev-beg) (point)) + (setq he-expand-list + (let ((abbrev-list smarty-abbrev-list) + (sel-abbrev-list '())) + (while abbrev-list + ; (if (stringp (car abbrev-list)) + ; (insert (concat " " (car abbrev-list)))) + (when (or (not (stringp (car abbrev-list))) + (string-match + (concat "^" he-search-string) (car abbrev-list))) + (setq sel-abbrev-list + (cons (car abbrev-list) sel-abbrev-list))) + (setq abbrev-list (cdr abbrev-list))) + (nreverse sel-abbrev-list)))) + (while (and he-expand-list + (or (not (stringp (car he-expand-list))) + (he-string-member (car he-expand-list) he-tried-table t))) + (unless (stringp (car he-expand-list)) + (setq smarty-expand-upper-case (car he-expand-list))) + (setq he-expand-list (cdr he-expand-list))) + (if (null he-expand-list) + (progn (when old (he-reset-string)) + nil) + (he-substitute-string + (if smarty-expand-upper-case + (upcase (car he-expand-list)) + (car he-expand-list)) + t) + (setq he-expand-list (cdr he-expand-list)) + t)) + +;; initialize reserved words for Smarty Mode +(smarty-words-init) + +;; function for expanding abbrevs and dabbrevs +(defun smarty-expand-abbrev (arg)) +(fset 'smarty-expand-abbrev (make-hippie-expand-function + '(try-expand-dabbrev + try-expand-dabbrev-all-buffers + smarty-try-expand-abbrev))) + +;; function for expanding parenthesis +(defun smarty-expand-paren (arg)) +(fset 'smarty-expand-paren (make-hippie-expand-function + '(try-expand-list + try-expand-list-all-buffers))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Stuttering +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun smarty-electric-tab (&optional prefix-arg) + "If preceding character is part of a word or a paren then hippie-expand, +else if right of non whitespace on line then insert tab, +else if last command was a tab or return then dedent one step or if a comment +toggle between normal indent and inline comment indent, +else indent `correctly'." + (interactive "*P") + (smarty-prepare-search-2 + (cond + ;; expand word + ((= (char-syntax (preceding-char)) ?w) + (let ((case-fold-search (not smarty-word-completion-case-sensitive)) + (case-replace nil) + (hippie-expand-only-buffers + (or (and (boundp 'hippie-expand-only-buffers) + hippie-expand-only-buffers) + '(smarty-mode)))) + (smarty-expand-abbrev prefix-arg))) + ;; expand parenthesis + ((or (= (preceding-char) ?\() (= (preceding-char) ?\))) + (let ((case-fold-search (not smarty-word-completion-case-sensitive)) + (case-replace nil)) + (smarty-expand-paren prefix-arg)))) + (setq this-command 'smarty-electric-tab))) + +(defun smarty-electric-space (count) + "Expand abbreviations and self-insert space(s)." + (interactive "p") + (let ((here (point-marker)) ldelim-found ldelim-point rdelim-found rdelim-point + delete-a) + (setq ldelim-found (re-search-backward (regexp-quote smarty-left-delimiter) nil t)) + (re-search-forward (regexp-quote smarty-left-delimiter) here t) + (setq ldelim-point (point-marker)) + (goto-char here) + (setq rdelim-found (re-search-backward (regexp-quote (concat " " smarty-right-delimiter)) nil t)) + (re-search-forward (regexp-quote (concat " " smarty-right-delimiter)) here t) + (setq rdelim-point (point-marker)) + (goto-char here) + (cond ((and (= here ldelim-point) ldelim-found) (insert (concat "ldelim" smarty-right-delimiter))) + ((and (= here rdelim-point) rdelim-found) + (re-search-backward (regexp-quote (concat " " smarty-right-delimiter)) nil t) + (delete-char 1) + (insert (concat " " smarty-left-delimiter "rdelim")) + (goto-char here)) + ((smarty-in-comment-p) + (self-insert-command count) + (cond ((>= (current-column) (+ 2 end-comment-column)) + (backward-char 1) + (skip-chars-backward "^ \t\n") + (indent-new-comment-line) + (skip-chars-forward "^ \t\n") + (forward-char 1)) + ((>= (current-column) end-comment-column) + (indent-new-comment-line)) + (t nil))) + ((or (and (>= (preceding-char) ?a) (<= (preceding-char) ?z)) + (and (>= (preceding-char) ?A) (<= (preceding-char) ?Z)) + (and (>= (preceding-char) ?0) (<= (preceding-char) ?9))) + (progn + (setq here (point-marker)) + (insert " ") + (setq delete-a t) + (if (re-search-backward "|" nil t) + (progn + (setq found (re-search-forward (regexp-quote "B2Smilies") here t)) + (if (and found (= here (point-marker))) + (replace-match "btosmilies") + (setq found (re-search-forward (regexp-quote "bbcode2html") here t)) + (if (and found (= here (point-marker))) + (replace-match "bbcodetohtml") + (setq found (re-search-forward (regexp-quote "date_format2") here t)) + (if (and found (= here (point-marker))) + (replace-match "date_formatto") + (goto-char here) + (setq delete-a nil) + (delete-char 1))))) + (goto-char here) + (setq delete-a nil) + (delete-char 1))) + (smarty-prepare-search-1 (expand-abbrev)) + (self-insert-command count) + (if (and delete-a (looking-at " ")) + (delete-char 1))) + (t (self-insert-command count))))) + +(defun smarty-electric-open-bracket (count) + "'(' --> '(', '((' --> '[', '[(' --> '{'" + (interactive "p") + (if (and smarty-stutter-mode (= count 1) (not (smarty-in-literal))) + (if (= (preceding-char) ?\() + (progn (delete-char -1) (insert-char ?\[ 1)) + (if (= (preceding-char) ?\[) + (progn (delete-char -1) (insert-char ?\{ 1)) + (insert-char ?\( 1))) + (self-insert-command count))) + +(defun smarty-electric-close-bracket (count) + "')' --> ')', '))' --> ']', '])' --> '}'" + (interactive "p") + (if (and smarty-stutter-mode (= count 1) (not (smarty-in-literal))) + (progn + (if (= (preceding-char) ?\)) + (progn (delete-char -1) (insert-char ?\] 1)) + (if (= (preceding-char) ?\]) + (progn (delete-char -1) (insert-char ?} 1)) + (insert-char ?\) 1))) + (blink-matching-open)) + (self-insert-command count))) + +(defun smarty-electric-star (count) + "After a left delimiter add a right delemiter to close the comment" + (interactive "p") + (let ((here (point-marker)) found) + (if (and smarty-stutter-mode (= count 1) (not (smarty-in-literal))) + (progn + (setq found (re-search-backward (regexp-quote smarty-left-delimiter) nil t)) + (re-search-forward (regexp-quote smarty-left-delimiter) here t) + (if (not (and (= here (point-marker)) found)) + (progn (goto-char here) + (self-insert-command count)) + (self-insert-command count) + (insert " ") + (setq here (point-marker)) + (insert " *") + (insert smarty-right-delimiter) + (goto-char here))) + (self-insert-command count)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Electrification +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defconst smarty-template-prompt-syntax "[^ =<>][^<>@.\n]*[^ =<>]" + "Syntax of prompt inserted by template generators.") + +(defvar smarty-template-invoked-by-hook nil + "Indicates whether a template has been invoked by a hook or by key or menu. +Used for undoing after template abortion.") + +(defun smarty-minibuffer-tab (&optional prefix-arg) + "If preceding character is part of a word or a paren then hippie-expand, +else insert tab (used for word completion in Smarty minibuffer)." + (interactive "P") + (cond + ;; expand word + ((= (char-syntax (preceding-char)) ?w) + (let ((case-fold-search (not smarty-word-completion-case-sensitive)) + (case-replace nil) + (hippie-expand-only-buffers + (or (and (boundp 'hippie-expand-only-buffers) + hippie-expand-only-buffers) + '(smarty-mode)))) + (smarty-expand-abbrev prefix-arg))) + ;; expand parenthesis + ((or (= (preceding-char) ?\() (= (preceding-char) ?\))) + (let ((case-fold-search (not smarty-word-completion-case-sensitive)) + (case-replace nil)) + (smarty-expand-paren prefix-arg))) + ;; insert tab + (t (insert-tab)))) + +;; correct different behavior of function `unread-command-events' in XEmacs +(defun smarty-character-to-event (arg)) +(defalias 'smarty-character-to-event + (if (fboundp 'character-to-event) 'character-to-event 'identity)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Abbrev ook bindings +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defvar smarty-mode-abbrev-table nil + "Abbrev table to use in `smarty-mode' buffers.") + +(defun smarty-mode-abbrev-table-init () + "Initialize `smarty-mode-abbrev-table'." + (when smarty-mode-abbrev-table (clear-abbrev-table smarty-mode-abbrev-table)) + (define-abbrev-table 'smarty-mode-abbrev-table + (append + '( + ("capture" "" smarty-template-capture-hook 0) + ("config_load" "" smarty-template-config-load-hook 0) + ("else" "" smarty-template-else-hook 0) + ("elseif" "" smarty-template-elseif-hook 0) + ("foreach" "" smarty-template-foreach-hook 0) + ("foreachelse" "" smarty-template-foreachelse-hook 0) + ("if" "" smarty-template-if-hook 0) + ("include" "" smarty-template-include-hook 0) + ("include_php" "" smarty-template-include-php-hook 0) + ("insert" "" smarty-template-insert-hook 0) + ("ldelim" "" smarty-template-ldelim-hook 0) + ("literal" "" smarty-template-literal-hook 0) + ("php" "" smarty-template-php-hook 0) + ("rdelim" "" smarty-template-rdelim-hook 0) + ("section" "" smarty-template-section-hook 0) + ("sectionelse" "" smarty-template-sectionelse-hook 0) + ("strip" "" smarty-template-strip-hook 0) + ("assign" "" smarty-template-assign-hook 0) + ("counter" "" smarty-template-counter-hook 0) + ("cycle" "" smarty-template-cycle-hook 0) + ("debug" "" smarty-template-debug-hook 0) + ("eval" "" smarty-template-eval-hook 0) + ("fetch" "" smarty-template-fetch-hook 0) + ("html_checkboxes" "" smarty-template-html-checkboxes-hook 0) + ("html_image" "" smarty-template-html-image-hook 0) + ("html_options" "" smarty-template-html-options-hook 0) + ("html_radios" "" smarty-template-html-radios-hook 0) + ("html_select_date" "" smarty-template-html-select-date-hook 0) + ("html_select_time" "" smarty-template-html-select-time-hook 0) + ("html_table" "" smarty-template-html-table-hook 0) + ("mailto" "" smarty-template-mailto-hook 0) + ("math" "" smarty-template-math-hook 0) + ("popup" "" smarty-template-popup-hook 0) + ("popup_init" "" smarty-template-popup-init-hook 0) + ("textformat" "" smarty-template-textformat-hook 0) + ("capitalize" "" smarty-template-capitalize-hook 0) + ("cat" "" smarty-template-cat-hook 0) + ("count_characters" "" smarty-template-count-characters-hook 0) + ("count_paragraphs" "" smarty-template-count-paragraphs-hook 0) + ("count_sentences" "" smarty-template-count-sentences-hook 0) + ("count_words" "" smarty-template-count-words-hook 0) + ("date_format" "" smarty-template-date-format-hook 0) + ("default" "" smarty-template-default-hook 0) + ("escape" "" smarty-template-escape-hook 0) + ("indent" "" smarty-template-indent-hook 0) + ("lower" "" smarty-template-lower-hook 0) + ("nl2br" "" smarty-template-nl2br-hook 0) + ("regex_replace" "" smarty-template-regex-replace-hook 0) + ("replace" "" smarty-template-replace-hook 0) + ("spacify" "" smarty-template-spacify-hook 0) + ("string_format" "" smarty-template-string-format-hook 0) + ("strip" "" smarty-template-vstrip-hook 0) + ("strip_tags" "" smarty-template-strip-tags-hook 0) + ("truncate" "" smarty-template-truncate-hook 0) + ("upper" "" smarty-template-upper-hook 0) + ("wordwrap" "" smarty-template-wordwrap-hook 0) + ("validate" "" smarty-template-validate-hook 0) + ("formtool_checkall" "" smarty-template-formtool-checkall-hook 0) + ("formtool_copy" "" smarty-template-formtool-copy-hook 0) + ("formtool_count_chars" "" smarty-template-formtool-count-chars-hook 0) + ("formtool_init" "" smarty-template-formtool-init-hook 0) + ("formtool_move" "" smarty-template-formtool-move-hook 0) + ("formtool_moveall" "" smarty-template-formtool-moveall-hook 0) + ("formtool_movedown" "" smarty-template-formtool-movedown-hook 0) + ("formtool_moveup" "" smarty-template-formtool-moveup-hook 0) + ("formtool_remove" "" smarty-template-formtool-remove-hook 0) + ("formtool_rename" "" smarty-template-formtool-rename-hook 0) + ("formtool_save" "" smarty-template-formtool-save-hook 0) + ("formtool_selectall" "" smarty-template-formtool-selectall-hook 0) + ("paginate_first" "" smarty-template-paginate-first-hook 0) + ("paginate_last" "" smarty-template-paginate-last-hook 0) + ("paginate_middle" "" smarty-template-paginate-middle-hook 0) + ("paginate_next" "" smarty-template-paginate-next-hook 0) + ("paginate_prev" "" smarty-template-paginate-prev-hook 0) + ("btosmilies" "" smarty-template-btosmilies-hook 0) + ("bbcodetohtml" "" smarty-template-bbcodetohtml-hook 0) + ("date_formatto" "" smarty-template-date-formatto-hook 0))))) + +;; initialize abbrev table for Smarty Mode +(smarty-mode-abbrev-table-init) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Abbrev hooks +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun smarty-hooked-abbrev (func) + "Do function, if syntax says abbrev is a keyword, invoked by hooked abbrev, +but not if inside a comment or quote)." + (if (or (smarty-in-literal) + (smarty-in-comment-p)) + (progn + (insert " ") + (unexpand-abbrev) + (delete-char -1)) + (if (not smarty-electric-mode) + (progn + (insert " ") + (unexpand-abbrev) + (backward-word 1) + (delete-char 1)) + (let ((invoke-char last-command-char) + (abbrev-mode -1) + (smarty-template-invoked-by-hook t)) + (let ((caught (catch 'abort + (funcall func)))) + (when (stringp caught) (message caught))) + (when (= invoke-char ?-) (setq abbrev-start-location (point))) + ;; delete CR which is still in event queue + (if (fboundp 'enqueue-eval-event) + (enqueue-eval-event 'delete-char -1) + (setq unread-command-events ; push back a delete char + (list (smarty-character-to-event ?\177)))))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Fontification +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defvar smarty-font-lock-keywords-1 + (list + + ;; Fontify built-in functions + (cons + (concat (regexp-quote smarty-left-delimiter) "[/]*" smarty-functions-regexp) + '(1 font-lock-keyword-face)) + + (cons + (concat "\\<\\(" smarty-constants "\\)\\>") + 'font-lock-constant-face) + + (cons (concat "\\(" (regexp-quote (concat smarty-left-delimiter "*")) "\\(\\s-\\|\\w\\|\\s.\\|\\s_\\|\\s(\\|\\s)\\|\\s\\\\)*" (regexp-quote (concat "*" smarty-right-delimiter)) "\\)") + 'font-lock-comment-face) + + ) + "Subdued level highlighting for Smarty mode.") + +(defconst smarty-font-lock-keywords-2 + (append + smarty-font-lock-keywords-1 + (list + + ;; Fontify variable names (\\sw\\|\\s_\\) matches any word character + + ;; underscore + '("\\$\\(\\(?:\\sw\\|\\s_\\)+\\)" (1 font-lock-variable-name-face)) ; $variable + '("->\\(\\(?:\\sw\\|\\s_\\)+\\)" (1 font-lock-variable-name-face t t)) ; ->variable + '("\\.\\(\\(?:\\sw\\|\\s_\\)+\\)" (1 font-lock-variable-name-face t t)) ; .variable + '("->\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(" (1 font-lock-function-name-face t t)) ; ->function_call + '("\\<\\(\\(?:\\sw\\|\\s_\\)+\\s-*\\)(" (1 font-lock-function-name-face)) ; word( + '("\\<\\(\\(?:\\sw\\|\\s_\\)+\\s-*\\)[[]" (1 font-lock-variable-name-face)) ; word[ + '("\\<[0-9]+" . default) ; number (also matches word) + + ;; Fontify strings + ;;'("\"\\([^\"]*\\)\"[^\"]+" (1 font-lock-string-face t t)) + )) + + "Medium level highlighting for Smarty mode.") + +(defconst smarty-font-lock-keywords-3 + (append + smarty-font-lock-keywords-2 + (list + ;; Fontify modifiers + (cons (concat "|\\(" smarty-modifiers-regexp "\\)[:|]+") '(1 font-lock-function-name-face)) + (cons (concat "|\\(" smarty-modifiers-regexp "\\)" (regexp-quote smarty-right-delimiter)) '(1 font-lock-function-name-face)) + + ;; Fontify config vars + (cons (concat (regexp-quote smarty-left-delimiter) "\\(#\\(?:\\sw\\|\\s_\\)+#\\)") '(1 font-lock-constant-face)))) + "Balls-out highlighting for Smarty mode.") + +(defconst smarty-font-lock-keywords-4 + (append + smarty-font-lock-keywords-3 + (list + ;; Fontify plugin functions + (cons + (concat (regexp-quote smarty-left-delimiter) "[/]*" smarty-plugins-functions-regexp) + '(1 font-lock-keyword-face)) + + (cons (concat "|\\(" smarty-plugins-modifiers-regexp "\\)[:|]+") '(1 font-lock-function-name-face)) + (cons (concat "|\\(" smarty-plugins-modifiers-regexp "\\)" (regexp-quote smarty-right-delimiter)) '(1 font-lock-function-name-face))))) + +(defvar smarty-font-lock-keywords smarty-font-lock-keywords-3 + "Default highlighting level for Smarty mode") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Mode map +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defvar smarty-template-map nil + "Keymap for Smarty templates.") + +(defun smarty-template-map-init () + "Initialize `smarty-template-map'." + (setq smarty-template-map (make-sparse-keymap)) + ;; key bindings for Smarty templates + (define-key smarty-template-map "\C-ba" 'smarty-template-capture) + (define-key smarty-template-map "\C-bc" 'smarty-template-config-load) + (define-key smarty-template-map "\C-b\M-e" 'smarty-template-else) + (define-key smarty-template-map "\C-b\C-e" 'smarty-template-elseif) + (define-key smarty-template-map "\C-b\C-f" 'smarty-template-foreach) + (define-key smarty-template-map "\C-b\M-f" 'smarty-template-foreachelse) + (define-key smarty-template-map "\C-bf" 'smarty-template-if) + (define-key smarty-template-map "\C-b\C-i" 'smarty-template-include) + (define-key smarty-template-map "\C-b\M-i" 'smarty-template-include-php) + (define-key smarty-template-map "\C-bi" 'smarty-template-insert) + (define-key smarty-template-map "\C-bl" 'smarty-template-ldelim) + (define-key smarty-template-map "\C-b\C-l" 'smarty-template-literal) + (define-key smarty-template-map "\C-bp" 'smarty-template-php) + (define-key smarty-template-map "\C-br" 'smarty-template-rdelim) + (define-key smarty-template-map "\C-b\C-s" 'smarty-template-section) + (define-key smarty-template-map "\C-b\M-s" 'smarty-template-sectionelse) + (define-key smarty-template-map "\C-bs" 'smarty-template-strip) + (define-key smarty-template-map "\C-ca" 'smarty-template-assign) + (define-key smarty-template-map "\C-co" 'smarty-template-counter) + (define-key smarty-template-map "\C-cc" 'smarty-template-cycle) + (define-key smarty-template-map "\C-cd" 'smarty-template-debug) + (define-key smarty-template-map "\C-ce" 'smarty-template-eval) + (define-key smarty-template-map "\C-cf" 'smarty-template-fetch) + (define-key smarty-template-map "\C-c\C-hc" 'smarty-template-html-checkboxes) + (define-key smarty-template-map "\C-c\C-hi" 'smarty-template-html-image) + (define-key smarty-template-map "\C-c\C-ho" 'smarty-template-html-options) + (define-key smarty-template-map "\C-c\C-hr" 'smarty-template-html-radios) + (define-key smarty-template-map "\C-c\C-hd" 'smarty-template-html-select-date) + (define-key smarty-template-map "\C-c\C-hm" 'smarty-template-html-select-time) + (define-key smarty-template-map "\C-c\C-ht" 'smarty-template-html-table) + (define-key smarty-template-map "\C-ci" 'smarty-template-mailto) + (define-key smarty-template-map "\C-ch" 'smarty-template-math) + (define-key smarty-template-map "\C-c\C-p" 'smarty-template-popup) + (define-key smarty-template-map "\C-c\M-p" 'smarty-template-popup-init) + (define-key smarty-template-map "\C-ct" 'smarty-template-textformat) + (define-key smarty-template-map "\C-vp" 'smarty-template-capitalize) + (define-key smarty-template-map "\C-vc" 'smarty-template-cat) + (define-key smarty-template-map "\C-v\C-cc" 'smarty-template-count-characters) + (define-key smarty-template-map "\C-v\C-cp" 'smarty-template-count-paragraphs) + (define-key smarty-template-map "\C-v\C-cs" 'smarty-template-count-sentences) + (define-key smarty-template-map "\C-v\C-cw" 'smarty-template-count-words) + (define-key smarty-template-map "\C-vf" 'smarty-template-date-format) + (define-key smarty-template-map "\C-vd" 'smarty-template-default) + (define-key smarty-template-map "\C-ve" 'smarty-template-escape) + (define-key smarty-template-map "\C-vi" 'smarty-template-indent) + (define-key smarty-template-map "\C-vl" 'smarty-template-lower) + (define-key smarty-template-map "\C-vn" 'smarty-template-nl2br) + (define-key smarty-template-map "\C-vx" 'smarty-template-regex-replace) + (define-key smarty-template-map "\C-v\C-p" 'smarty-template-replace) + (define-key smarty-template-map "\C-vy" 'smarty-template-spacify) + (define-key smarty-template-map "\C-vs" 'smarty-template-string-format) + (define-key smarty-template-map "\C-v\C-s" 'smarty-template-vstrip) + (define-key smarty-template-map "\C-v\M-s" 'smarty-template-strip-tags) + (define-key smarty-template-map "\C-vt" 'smarty-template-truncate) + (define-key smarty-template-map "\C-vu" 'smarty-template-upper) + (define-key smarty-template-map "\C-vw" 'smarty-template-wordwrap) + (define-key smarty-template-map "\C-h" 'smarty-template-header) + (define-key smarty-template-map "\C-f" 'smarty-template-footer) + (define-key smarty-template-map "\C-di" 'smarty-template-insert-date) + (define-key smarty-template-map "\C-dm" 'smarty-template-modify)) + +;; initialize template map for Smarty Mode +(smarty-template-map-init) + +(defun smarty-mode-map-init () + "Initialize `smarty-mode-map'." + (setq smarty-mode-map (make-sparse-keymap)) + ;; template key bindings + (define-key smarty-mode-map "\C-c\C-t" smarty-template-map) + ;; mode specific key bindings + (define-key smarty-mode-map "\C-c\C-m\C-e" 'smarty-electric-mode) + (define-key smarty-mode-map "\C-c\C-m\C-s" 'smarty-stutter-mode) + (define-key smarty-mode-map "\C-c\C-s\C-u" 'smarty-add-source-files-menu) + (define-key smarty-mode-map "\C-c\M-m" 'smarty-show-messages) + (define-key smarty-mode-map "\C-c\C-h" 'smarty-doc-mode) + (define-key smarty-mode-map "\C-c\C-v" 'smarty-version) + ;; electric key bindings + (when smarty-intelligent-tab + (define-key smarty-mode-map "\t" 'smarty-electric-tab)) + (define-key smarty-mode-map " " 'smarty-electric-space) + (define-key smarty-mode-map "(" 'smarty-electric-open-bracket) + (define-key smarty-mode-map ")" 'smarty-electric-close-bracket) + (define-key smarty-mode-map "*" 'smarty-electric-star)) + +;; initialize mode map for Smarty Mode +(smarty-mode-map-init) + +(defvar smarty-minibuffer-local-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map minibuffer-local-map) + (when smarty-word-completion-in-minibuffer + (define-key map "\t" 'smarty-minibuffer-tab)) + map) + "Keymap for minibuffer used in Smarty Mode.") + +(mapcar + (function + (lambda (sym) + (put sym 'delete-selection t) ; for `delete-selection-mode' (Emacs) + (put sym 'pending-delete t))) ; for `pending-delete-mode' (XEmacs) + '(smarty-electric-space + smarty-electric-tab + smarty-electric-open-bracket + smarty-electric-close-bracket + smarty-electric-star)) + +;;;###autoload +(defun smarty-mode () + "Smarty Mode +*********** + +Smarty Mode is a GNU XEmacs major mode for editing Smarty templates. + +1 Introduction +************** + +Smarty-Mode is a mode allowing easy edit of Smarty templates: +highlight, templates, navigation into source files... + + + +Features (new features in bold) : + + * Completion + + * Customizable + + * Highlight + + * Menu + + * Stuttering + + * Templates + - Built-in Functions + + - User Functions + + - Variable Modifiers + + - Plugin (Functions) + * Smarty Formtool + + * Smarty Paginate + + * Smarty Validate + + - Plugin (Variable Modifiers) + * AlternativeDateModifierPlugin + + * B2Smilies + + * BBCodePlugin + + - Fonctions Non-Smarty + + + +This manual describes Smarty Mode version 0.0.4. + +2 Installation +************** + +2.1 Requirements +================ + +Smarty Mode is a XEmacs major mode that needs the following +software/packages: + + * XEmacs (http://www.xemacs.org/). + + * `font-lock' mode generaly installed with XEmacs. + + * `assoc' mode generaly installed with XEmacs. + + * `easymenu' mode generaly installed with XEmacs. + + * `hippie-exp' mode generaly installed with XEmacs. + +Before continuing, you must be sure to have all this packages +installed. + +2.2 Download +============ + +Two internet address to download Smarty Mode : + + * Principal: Smarty-Mode 0.0.4 + (http://deboutv.free.fr/lisp/smarty/download/smarty-0.0.4.tar.gz) + (http://deboutv.free.fr/lisp/smarty/) + + * Secondary: Smarty-Mode 0.0.4 + (http://www.morinie.fr/lisp/smarty/download/smarty-0.0.4.tar.gz) + (http://www.morinie.fr/lisp/smarty/) + + * Old releases: Smarty-Mode + (http://deboutv.free.fr/lisp/smarty/download.php) + (http://deboutv.free.fr/lisp/smarty/) + +2.3 Installation +================ + +2.3.1 Installation +------------------ + +To install Smarty Mode you need to choose an installation directory +(for example `/usr/local/share/lisp' or `c:\lisp'). The administrator +must have the write rights on this directory. + +With your favorite unzip software, unzip the archive in the +installation directory. + +Example: + cd /usr/local/share/lisp + tar zxvf smarty-0.0.4.tar.gz +Now you have a `smarty' directory in the installation directory. This +directory contains 2 files `smarty-mode.el' and `smarty-mode.elc' and +another directory `docs' containing the documentation. + +You need to configure XEmacs. open you initialization file `init.el' +(open the file or start XEmacs then choose the Options menu and Edit +Init File). Add the following lines (the installation directory in +this example is `/usr/local/share/lisp') : + + (setq load-path + (append (list \"/usr/local/share/lisp/\") load-path)) + (autoload 'smarty-mode \"smarty-mode\" \"Smarty Mode\" t) + +2.3.2 Update +------------ + +The update is easy. You need to unzip the archive in the installation +directory to remove the old release. + +Example: + cd /usr/local/share/lisp + rm -rf smarty + tar zxvf smarty-0.0.4.tar.gz + +2.4 Invoke Smarty-Mode +====================== + +You have two possibilities to invoke the Smarty Mode. + + - Manually: At each file opening you need to launch Smarty Mode + with the following command: + + `M-x smarty-mode' + + - Automatically: Add the following linesin your initialization + file `init.el' : + + (setq auto-mode-alist + (append + '((\"\\.tpl$\" . smarty-mode)) + auto-mode-alist)) + + +3 Customization +*************** + +This chapter describes the differents parameters and functions that +you can change to customize Smarty Mode. To do that, open a Smarty +file, click on the Smarty menu and choose Options then Browse +Options.... + +3.1 Parameters +============== + +3.1.1 Mode +---------- + +Smarty Mode has 2 modes allowing to simplify the writing of Smarty +templates. You can enable/disable each mode individually. + +`smarty-electric-mode' + Type: boolean + Default value: `t' + Description: If `t'; enable automatic generation of template. + If `nil'; template generators can still be invoked through key + bindings and menu. Is indicated in the modeline by \"/e\" after + the mode name and can be toggled by `smarty-electric-mode'. + +`smarty-stutter-mode' + Type: boolean + Default value: `t' + Description: If `t'; enable the stuttering. Is indicated in the + modeline by \"/s\" after the mode name and can be toggled by + `smarty-stutter-mode'. + +3.1.2 Menu +---------- + +Smarty Mode has also 1 menu that you can enable/disable. The menu +Sources is specific to each Smarty files opened. + +`smarty-source-file-menu' + Type: boolean + Default value: `t' + Description: If `t'; the Sources menu is enabled. This menu + contains the list of Smarty file located in the current + directory. The Sources menu scans the directory when a file is + opened. + +3.1.3 Menu +---------- + +`smarty-highlight-plugin-functions' + Type: boolean + Default value: `t' + Description: If `t'; the functions described in the smarty + plugins are highlighted. + +3.1.4 Templates +--------------- + +3.1.4.1 Header +.............. + +`smarty-file-header' + Type: string + Default value: `\"\"' + Description: String or file to insert as file header. If the + string specifies an existing file name the contents of the file + is inserted; otherwise the string itself is inserted as file + header. + Type `C-j' for newlines. + The follonwing keywords are supported: + : replaced by the file name. + : replaced by the user name and email address. + : replaced by `user-login-name'. + : replaced by `smarty-company-name' content. + : replaced by the current date. + : replaced by the current year. + : replaced by `smarty-copyright-string' content. + : final cursor position. + +`smarty-file-footer' + Type: string + Default value: `\"\"' + Description: String or file to insert as file footer. See + `smarty-file-header' + +`smarty-company-name' + Type: string + Default value: `\"\"' + Description: Name of the company to insert in file header. + +`smarty-copyright-string' + Type: string + Default value: `\"\"' + Description: Coryright string to insert in file header. + +`smarty-date-format' + Type: string + Default value: `\"%Y-%m-%d\"' + Description: Date format. + +`smarty-modify-date-prefix-string' + Type: string + Default value: `\"\"' + Description: Prefix string of modification date in Smarty file + header. + +`smarty-modify-date-on-saving' + Type: bool + Default value: `nil' + Description: If `t'; update the modification date when the + buffer is saved. + +3.1.5 Miscellaneous +------------------- + +`smarty-left-delimiter' + Type: string + Default value: `\"\"' + Description: Left escaping delimiter for Smarty templates. + +`smarty-right-delimiter' + Type: string + Default value: `\"\"' + Description: Right escaping delimiter for Smarty templates. + +`smarty-intelligent-tab' + Type: bool + Default value: `t' + Description: If `t'; TAB does indentation; completion and insert + tabulations. If `nil'; TAB does only indentation. + +`smarty-word-completion-in-minibuffer' + Type: bool + Default value: `t' + Description: If `t'; enable completion in the minibuffer. + +`smarty-word-completion-case-sensitive' + Type: bool + Default value: `nil' + Description: If `t'; completion is case sensitive. + +3.2 Functions +============= + +3.2.1 Mode +---------- + +`smarty-electric-mode' + Menu: Smarty -> Options -> Mode -> Electric Mode + Keybinding: `C-c C-m C-e' + Description: This functions is used to enable/disable the + electric mode. + +`smarty-stutter-mode' + Menu: Smarty -> Options -> Mode -> Stutter Mode + Keybinding: `C-c C-m C-s' + Description: This function is used to enable/disable the stutter + mode. + +4 Menus +******* + +There are 2 menus: Smarty and Sources. All theses menus can be +accessed from the menubar or from the right click. This chapter +describes each menus. + +4.1 Smarty +========== + +This is the main menu of Smarty Mode. It allows an easy access to the +main features of the Smarty Mode: Templates (see *Note Templates::) +and Options (see *Note Customization::). + +This menu contains also 3 functions that are discussed in the next +part. + +4.1.1 Functions +--------------- + +`smarty-show-messages' + Menu: Smarty -> Show Messages + Keybinding: `C-c M-m' + Description: This function opens the *Messages* buffer to + display previous error messages. + +`smarty-doc-mode' + Menu: Smarty -> Smarty Mode Documentation + Keybinding: `C-c C-h' + Description: This function opens the *Help* buffer and prints in + it the Smarty Mode documentation. + +`smarty-version' + Menu: Smarty -> Version + Keybinding: `C-c C-v' + Description: This function displays in the minibuffer the + current Smarty Mode version with the timestamp. + +4.2 Sources +=========== + +The Sources menu shows the Smarty files in the current directory. If +you add or delete a file in the current directory, you need to +refresh the menu. + +4.2.1 Customization +------------------- + +`smarty-source-file-menu' + Type: boolean + Default value: `t' + Description: If `t'; the Sources menu is enabled. This menu + contains the list of Smarty file located in the current + directory. The Sources menu scans the directory when a file is + opened. + +4.2.2 Functions +--------------- + +`smarty-add-source-files-menu' + Menu: Sources -> *Rescan* + Keybinding: `C-c C-s C-u' + Description: This function is used to refresh the Sources menu. + +5 Stuttering +************ + +The stutter mode is a mode that affects a function to a key. For +example, when you use the `ENTER' key, the associated function will +create a new line and indent it. + +5.1 Customization +================= + +`smarty-stutter-mode' + Type: boolean + Default value: `t' + Description: If `t'; enable the stuttering. Is indicated in the + modeline by \"/s\" after the mode name and can be toggled by + `smarty-stutter-mode'. + +5.2 Functions +============= + +`SPACE' + If in comment, indent the comment and add new line if necessary. + In other case, add a space. + +`(' + If the previous character is a `(', the `((' will be replaced by + `['. + If the previous character is a `[', the `[(' will be replaced by + `{'. + In other case, insert a `('. + +`)' + If the previous character is a `)', the `))' will be replaced by + `]'. + If the previous character is a `]', the `])' will be replaced by + `}'. + In other case, insert a `)'. + +6 Templates +*********** + +In the Smarty Mode, the Smarty functions (like if, while, for, fopen, +fclose) are predefined in functions called \"Templates\". + +Each template can be invoked by the function name or by using the + key after the Smarty function name in the buffer (Note, using +`M-' disable the template). + +A template can be aborted by using the `C-g' or by lefting empty the +tempate prompt (in the minibuffer). + +6.1 Customization +================= + +`smarty-electric-mode' + Type: boolean + Default value: `t' + Description: If `t'; enable automatic generation of template. + If `nil'; template generators can still be invoked through key + bindings and menu. Is indicated in the modeline by \"/e\" after + the mode name and can be toggled by `smarty-electric-mode'. + +For a complete description of the template customizable variables, +see *Note Cu01-Pa01-Template:: + +6.2 Functions +============= + +6.2.1 Smarty Functions +---------------------- + +For Smarty functions, see PDF or HTML documentation. + +6.2.2 Non-Smarty Functions +-------------------------- + +`smarty-template-header' + Menu: Smarty -> Templates -> Insert Header + Keybinding: `C-c C-t C-h' + Description: This function is used to insert a header in the + current buffer. + +`smarty-template-footer' + Menu: Smarty -> Templates -> Insert Footer + Keybinding: `C-c C-t C-f' + Description: This function is used to insert a footer in the + current buffer. + +`smarty-template-insert-date' + Menu: Smarty -> Templates -> Insert Date + Keybinding: `C-c C-t C-d i' + Description: This function is used to insert the date in the + current buffer. + +`smarty-template-modify' + Menu: Smarty -> Templates -> Modify Date + Keybinding: `C-c C-t C-d m' + Description: This function is used to modify the last + modification date in the current buffer. + +7 Bugs, Help +************ + + * To report bugs: Bugtracker + (http://bugtracker.morinie.fr/lisp/set_project.php?project_id=2) + + * To obtain help you can post on the dedicated forum: Forum + (http://forum.morinie.fr/lisp/) + +8 Key bindings +************** + +\\{smarty-mode-map}" + (interactive) + (kill-all-local-variables) + (setq major-mode 'smarty-mode) + (setq mode-name "Smarty") + + (smarty-create-syntax-table) + + ;; set maps and tables + (use-local-map smarty-mode-map) + (set-syntax-table smarty-mode-syntax-table) + (setq local-abbrev-table smarty-mode-abbrev-table) + + (set (make-local-variable 'comment-start) (concat smarty-left-delimiter "*")) + (set (make-local-variable 'comment-end) (concat "*" smarty-right-delimiter)) + (set (make-local-variable 'comment-multi-line) t) + (set (make-local-variable 'end-comment-column) 80) + + (make-local-variable 'font-lock-defaults) + (if smarty-highlight-plugin-functions + (setq smarty-font-lock-keywords smarty-font-lock-keywords-4) + (setq smarty-font-lock-keywords smarty-font-lock-keywords-3)) + (setq font-lock-defaults + '((smarty-font-lock-keywords) + nil ; Keywords only (i.e. no comment or string highlighting + t ; case fold + nil ; syntax-alist + nil ; syntax-begin + )) + + (setq font-lock-maximum-decoration t + case-fold-search t) + + ;; add source file menu + (if smarty-source-file-menu (smarty-add-source-files-menu)) + ;; add Smarty menu + (easy-menu-add smarty-mode-menu-list) + (easy-menu-define smarty-mode-menu smarty-mode-map + "Menu keymap for Smarty Mode." smarty-mode-menu-list) + + (message "Smarty Mode %s.%s" smarty-version + (if noninteractive "" " See menu for documentation and release notes.")) + (smarty-mode-line-update) + (run-hooks 'smarty-mode-hook)) + +(defun smarty-doc-mode () + "Display Smarty Mode documentation in *Help* buffer." + (interactive) + (with-output-to-temp-buffer + (if (fboundp 'help-buffer) (help-buffer) "*Help*") + (princ mode-name) + (princ " mode:\n") + (princ (documentation 'smarty-mode)) + (with-current-buffer standard-output + (help-mode)) + (print-help-return-message))) + +(defun smarty-activate-customizations () + "Activate all customizations on local variables." + (interactive) + (smarty-mode-map-init) + (use-local-map smarty-mode-map) + (set-syntax-table smarty-mode-syntax-table) + (smarty-update-mode-menu) + (run-hooks 'menu-bar-update-hook) + (smarty-mode-line-update)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Templates +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun smarty-template-field (prompt &optional follow-string optional + begin end is-string string-char default) + "Prompt for string and insert it in buffer with optional FOLLOW-STRING. +If OPTIONAL is nil, the prompt is left if an empty string is inserted. If +an empty string is inserted, return nil and call `smarty-template-undo' for +the region between BEGIN and END. IS-STRING indicates whether a string +with double-quotes is to be inserted. DEFAULT specifies a default string." + (let ((position (point)) + string) + (insert "<" prompt ">") + (if (not (> (length string-char) 0)) + (setq string-char "\"")) + (setq string + (condition-case () + (read-from-minibuffer (concat prompt ": ") + (or (and is-string (cons (concat string-char string-char) 1)) default) + smarty-minibuffer-local-map) + (quit (if (and optional begin end) + (progn (beep) "") + (keyboard-quit))))) + (when (or (not (equal string "")) optional) + (delete-region position (point))) + (when (and (equal string "") optional begin end) + (smarty-template-undo begin end) + (message "Template aborted")) + (unless (equal string "") + (insert string)) + (when (or (not (equal string "")) (not optional)) + (insert (or follow-string ""))) + (if (equal string "") nil string))) + +(defun smarty-template-undo (begin end) + "Undo aborted template by deleting region and unexpanding the keyword." + (cond (smarty-template-invoked-by-hook + (goto-char end) + (insert " ") + (delete-region begin end) + (unexpand-abbrev)) + (t (delete-region begin end)))) + +(defun smarty-template-generic-function (label close-label field mandatory-count &optional infinite special-field) + "Generic function template 'label field1= field2=..." + (interactive) + (let ((start (point)) found here result-value elt continue field-count stop prompt) + (if smarty-template-invoked-by-hook + (setq found (smarty-after-ldelim)) + (insert smarty-left-delimiter) + (setq found t)) + (insert label) + (setq here (point-marker)) + (insert " ") + (when found + (setq elt field) + (setq continue t) + (setq field-count 0) + (setq stop nil) + (while (and elt continue) + (setq prompt (car elt)) + (when (not special-field) + (insert prompt "=")) + (setq result-value (smarty-template-field prompt nil t)) + (if (and (not result-value) + (< field-count mandatory-count)) + (progn (setq continue nil) + (delete-region start (point)) + (insert (concat label " ")) + (setq stop t)) + (if (not result-value) + (setq continue nil) + (setq here (point-marker)) + (insert " "))) + (setq field-count (+ 1 field-count)) + (setq elt (cdr elt))) + (when (and infinite continue) + (while continue + (setq result-value (smarty-template-field "var_name" "=" t here)) + (if (not result-value) + (setq continue nil) + (setq continue (smarty-template-field "var_value" nil t here)) + (setq here (point-marker)) + (insert " ")))) + (when (not stop) + (delete-region here (point)) + (if (> 0 mandatory-count) + (delete-char -1)) + (if special-field + (delete-char -1)) + (insert smarty-right-delimiter) + (setq here (point-marker)) + (if close-label + (insert smarty-left-delimiter "/" label smarty-right-delimiter)) + (goto-char here))))) + +(defun smarty-template-generic-modifier (label field mandatory-count) + "Generic modifier template '|label:field1:field2..." + (interactive) + (let ((start (point)) found here result-value elt continue field-count stop prompt) + (setq found (re-search-backward (concat (regexp-quote smarty-left-delimiter) "\\$\\(\\w+\\)" (regexp-quote "|")) nil t)) + (if found + (progn + (setq found (re-search-forward (regexp-quote smarty-right-delimiter) start t)) + (if (not found) + (progn + (goto-char start) + (insert label) + (setq here (point-marker)) + (setq elt field) + (setq continue t) + (setq field-count 0) + (setq stop nil) + (while (and elt continue) + (setq prompt (car elt)) + (insert ":") + (setq result-value (smarty-template-field prompt nil t)) + (if (and (not result-value) + (< field-count mandatory-count)) + (progn (setq continue nil) + (delete-region start (point)) + (insert (concat label " ")) + (setq stop t)) + (if (not result-value) + (setq continue nil) + (setq here (point-marker)) + (insert ":"))) + (setq field-count (+ 1 field-count)) + (setq elt (cdr elt))) + (when (not stop) + (delete-region here (point)) + (if (not (or (looking-at smarty-right-delimiter) + (looking-at "|"))) + (insert smarty-right-delimiter)))) + (goto-char start) + (insert label " "))) + (goto-char start) + (insert label " ")))) + +(defun smarty-template-capture-hook () + (smarty-hooked-abbrev 'smarty-template-capture)) +(defun smarty-template-config-load-hook () + (smarty-hooked-abbrev 'smarty-template-config-load)) +(defun smarty-template-else-hook () + (smarty-hooked-abbrev 'smarty-template-else)) +(defun smarty-template-elseif-hook () + (smarty-hooked-abbrev 'smarty-template-elseif)) +(defun smarty-template-foreach-hook () + (smarty-hooked-abbrev 'smarty-template-foreach)) +(defun smarty-template-foreachelse-hook () + (smarty-hooked-abbrev 'smarty-template-foreachelse)) +(defun smarty-template-if-hook () + (smarty-hooked-abbrev 'smarty-template-if)) +(defun smarty-template-include-hook () + (smarty-hooked-abbrev 'smarty-template-include)) +(defun smarty-template-include-php-hook () + (smarty-hooked-abbrev 'smarty-template-include-php)) +(defun smarty-template-insert-hook () + (smarty-hooked-abbrev 'smarty-template-insert)) +(defun smarty-template-ldelim-hook () + (smarty-hooked-abbrev 'smarty-template-ldelim)) +(defun smarty-template-literal-hook () + (smarty-hooked-abbrev 'smarty-template-literal)) +(defun smarty-template-php-hook () + (smarty-hooked-abbrev 'smarty-template-php)) +(defun smarty-template-rdelim-hook () + (smarty-hooked-abbrev 'smarty-template-rdelim)) +(defun smarty-template-section-hook () + (smarty-hooked-abbrev 'smarty-template-section)) +(defun smarty-template-sectionelse-hook () + (smarty-hooked-abbrev 'smarty-template-sectionelse)) +(defun smarty-template-strip-hook () + (smarty-hooked-abbrev 'smarty-template-strip)) + +(defun smarty-template-assign-hook () + (smarty-hooked-abbrev 'smarty-template-assign)) +(defun smarty-template-counter-hook () + (smarty-hooked-abbrev 'smarty-template-counter)) +(defun smarty-template-cycle-hook () + (smarty-hooked-abbrev 'smarty-template-cycle)) +(defun smarty-template-debug-hook () + (smarty-hooked-abbrev 'smarty-template-debug)) +(defun smarty-template-eval-hook () + (smarty-hooked-abbrev 'smarty-template-eval)) +(defun smarty-template-fetch-hook () + (smarty-hooked-abbrev 'smarty-template-fetch)) +(defun smarty-template-html-checkboxes-hook () + (smarty-hooked-abbrev 'smarty-template-html-checkboxes)) +(defun smarty-template-html-image-hook () + (smarty-hooked-abbrev 'smarty-template-html-image)) +(defun smarty-template-html-options-hook () + (smarty-hooked-abbrev 'smarty-template-html-options)) +(defun smarty-template-html-radios-hook () + (smarty-hooked-abbrev 'smarty-template-html-radios)) +(defun smarty-template-html-select-date-hook () + (smarty-hooked-abbrev 'smarty-template-html-select-date)) +(defun smarty-template-html-select-time-hook () + (smarty-hooked-abbrev 'smarty-template-html-select-time)) +(defun smarty-template-html-table-hook () + (smarty-hooked-abbrev 'smarty-template-html-table)) +(defun smarty-template-mailto-hook () + (smarty-hooked-abbrev 'smarty-template-mailto)) +(defun smarty-template-math-hook () + (smarty-hooked-abbrev 'smarty-template-math)) +(defun smarty-template-popup-hook () + (smarty-hooked-abbrev 'smarty-template-popup)) +(defun smarty-template-popup-init-hook () + (smarty-hooked-abbrev 'smarty-template-popup-init)) +(defun smarty-template-textformat-hook () + (smarty-hooked-abbrev 'smarty-template-textformat)) + +(defun smarty-template-capitalize-hook () + (smarty-hooked-abbrev 'smarty-template-capitalize)) +(defun smarty-template-cat-hook () + (smarty-hooked-abbrev 'smarty-template-cat)) +(defun smarty-template-count-characters-hook () + (smarty-hooked-abbrev 'smarty-template-count-characters)) +(defun smarty-template-count-paragraphs-hook () + (smarty-hooked-abbrev 'smarty-template-count-paragraphs)) +(defun smarty-template-count-sentences-hook () + (smarty-hooked-abbrev 'smarty-template-count-sentences)) +(defun smarty-template-count-words-hook () + (smarty-hooked-abbrev 'smarty-template-count-words)) +(defun smarty-template-date-format-hook () + (smarty-hooked-abbrev 'smarty-template-date-format)) +(defun smarty-template-default-hook () + (smarty-hooked-abbrev 'smarty-template-default)) +(defun smarty-template-escape-hook () + (smarty-hooked-abbrev 'smarty-template-escape)) +(defun smarty-template-indent-hook () + (smarty-hooked-abbrev 'smarty-template-indent)) +(defun smarty-template-lower-hook () + (smarty-hooked-abbrev 'smarty-template-lower)) +(defun smarty-template-nl2br-hook () + (smarty-hooked-abbrev 'smarty-template-nl2br)) +(defun smarty-template-regex-replace-hook () + (smarty-hooked-abbrev 'smarty-template-regex-replace)) +(defun smarty-template-replace-hook () + (smarty-hooked-abbrev 'smarty-template-replace)) +(defun smarty-template-spacify-hook () + (smarty-hooked-abbrev 'smarty-template-spacify)) +(defun smarty-template-string-format-hook () + (smarty-hooked-abbrev 'smarty-template-string-format)) +(defun smarty-template-vstrip-hook () + (smarty-hooked-abbrev 'smarty-template-vstrip)) +(defun smarty-template-strip-tags-hook () + (smarty-hooked-abbrev 'smarty-template-strip-tags)) +(defun smarty-template-truncate-hook () + (smarty-hooked-abbrev 'smarty-template-truncate)) +(defun smarty-template-upper-hook () + (smarty-hooked-abbrev 'smarty-template-upper)) +(defun smarty-template-wordwrap-hook () + (smarty-hooked-abbrev 'smarty-template-wordwrap)) + +(defun smarty-template-validate-hook () + (smarty-hooked-abbrev 'smarty-template-validate)) +(defun smarty-template-formtool-checkall-hook () + (smarty-hooked-abbrev 'smarty-template-formtool-checkall)) +(defun smarty-template-formtool-copy-hook () + (smarty-hooked-abbrev 'smarty-template-formtool-copy)) +(defun smarty-template-formtool-count-chars-hook () + (smarty-hooked-abbrev 'smarty-template-formtool-count-chars)) +(defun smarty-template-formtool-init-hook () + (smarty-hooked-abbrev 'smarty-template-formtool-init)) +(defun smarty-template-formtool-move-hook () + (smarty-hooked-abbrev 'smarty-template-formtool-move)) +(defun smarty-template-formtool-moveall-hook () + (smarty-hooked-abbrev 'smarty-template-formtool-moveall)) +(defun smarty-template-formtool-movedown-hook () + (smarty-hooked-abbrev 'smarty-template-formtool-movedown)) +(defun smarty-template-formtool-moveup-hook () + (smarty-hooked-abbrev 'smarty-template-formtool-moveup)) +(defun smarty-template-formtool-remove-hook () + (smarty-hooked-abbrev 'smarty-template-formtool-remove)) +(defun smarty-template-formtool-rename-hook () + (smarty-hooked-abbrev 'smarty-template-formtool-rename)) +(defun smarty-template-formtool-save-hook () + (smarty-hooked-abbrev 'smarty-template-formtool-save)) +(defun smarty-template-formtool-selectall-hook () + (smarty-hooked-abbrev 'smarty-template-formtool-selectall)) +(defun smarty-template-paginate-first-hook () + (smarty-hooked-abbrev 'smarty-template-paginate-first)) +(defun smarty-template-paginate-last-hook () + (smarty-hooked-abbrev 'smarty-template-paginate-last)) +(defun smarty-template-paginate-middle-hook () + (smarty-hooked-abbrev 'smarty-template-paginate-middle)) +(defun smarty-template-paginate-next-hook () + (smarty-hooked-abbrev 'smarty-template-paginate-next)) +(defun smarty-template-paginate-prev-hook () + (smarty-hooked-abbrev 'smarty-template-paginate-prev)) + +(defun smarty-template-btosmilies-hook () + (smarty-hooked-abbrev 'smarty-template-btosmilies)) +(defun smarty-template-bbcodetohtml-hook () + (smarty-hooked-abbrev 'smarty-template-bbcodetohtml)) +(defun smarty-template-date-formatto-hook () + (smarty-hooked-abbrev 'smarty-template-date-formatto)) + +(defun smarty-template-capture () + "Insert a capture statement." + (interactive) + (smarty-template-generic-function "capture" t '("name" "assign") 0)) + +(defun smarty-template-config-load () + "Insert a config_load statement." + (interactive) + (smarty-template-generic-function "config_load" nil '("file" "section" "scope" "global") 1)) + +(defun smarty-template-else () + "Insert a else statement." + (interactive) + (smarty-template-generic-function "else" nil '() 0)) + +(defun smarty-template-elseif () + "Insert a elseif statement." + (interactive) + (smarty-template-generic-function "elseif" nil '("condition") 1 nil t)) + +(defun smarty-template-foreach () + "Insert a foreach statement." + (interactive) + (smarty-template-generic-function "foreach" t '("from" "item" "key" "name") 2)) + +(defun smarty-template-foreachelse () + "Insert a foreachelse statement." + (interactive) + (smarty-template-generic-function "foreachelse" nil '() 0)) + +(defun smarty-template-if () + "Insert a if statement." + (interactive) + (smarty-template-generic-function "if" t '("condition") 1 nil t)) + +(defun smarty-template-include () + "Insert a include statement." + (interactive) + (smarty-template-generic-function "include" nil '("file" "assign") 1 t)) + +(defun smarty-template-include-php () + "Insert a include_php statement." + (interactive) + (smarty-template-generic-function "include_php" nil '("file" "once" "assign") 1)) + +(defun smarty-template-insert () + "Insert a insert statement." + (interactive) + (smarty-template-generic-function "insert" nil '("name" "assign" "script") 1 t)) + +(defun smarty-template-ldelim () + "Insert a ldelim statement." + (interactive) + (smarty-template-generic-function "ldelim" nil '() 0)) + +(defun smarty-template-literal () + "Insert a literal statement." + (interactive) + (smarty-template-generic-function "literal" t '() 0)) + +(defun smarty-template-php () + "Insert a php statement." + (interactive) + (smarty-template-generic-function "php" t '() 0)) + +(defun smarty-template-rdelim () + "Insert a rdelim statement." + (interactive) + (smarty-template-generic-function "rdelim" nil '() 0)) + +(defun smarty-template-section () + "Insert a section statement." + (interactive) + (smarty-template-generic-function "section" t '("name" "loop" "start" "step" "max" "show") 2)) + +(defun smarty-template-sectionelse () + "Insert a sectionelse statement." + (interactive) + (smarty-template-generic-function "sectionelse" nil '() 0)) + +(defun smarty-template-strip () + "Insert a strip statement." + (interactive) + (smarty-template-generic-function "strip" t '() 0)) + + +(defun smarty-template-assign () + "Insert a assign statement." + (interactive) + (smarty-template-generic-function "assign" nil '("var" "value") 2)) + +(defun smarty-template-counter () + "Insert a counter statement." + (interactive) + (smarty-template-generic-function "counter" nil '("name" "start" "skip" "direction" "print" "assign") 0)) + +(defun smarty-template-cycle () + "Insert a cycle statement." + (interactive) + (smarty-template-generic-function "cycle" nil '("values" "name" "print" "advance" "delimiter" "assign" "reset") 1)) + +(defun smarty-template-debug () + "Insert a debug statement." + (interactive) + (smarty-template-generic-function "debug" nil '("output") 0)) + +(defun smarty-template-eval () + "Insert a eval statement." + (interactive) + (smarty-template-generic-function "eval" nil '("var" "assign") 1)) + +(defun smarty-template-fetch () + "Insert a fetch statement." + (interactive) + (smarty-template-generic-function "fetch" nil '("file" "assign") 1)) + +(defun smarty-template-html-checkboxes () + "Insert a html_checkboxes statement." + (interactive) + (smarty-template-generic-function "html_checkboxes" nil '("name" "values" "output" "selected" "options" "separator" "assign" "labels") 0)) + +(defun smarty-template-html-image () + "Insert a html_image statement." + (interactive) + (smarty-template-generic-function "html_image" nil '("file" "height" "width" "basedir" "alt" "href" "path_prefix") 1)) + +(defun smarty-template-html-options () + "Insert a html_options statement." + (interactive) + (smarty-template-generic-function "html_options" nil '("name" "values" "output" "selected" "options") 0)) + +(defun smarty-template-html-radios () + "Insert a html_radios statement." + (interactive) + (smarty-template-generic-function "html_radios" nil '("name" "values" "output" "selected" "options" "separator" "assign") 0)) + +(defun smarty-template-html-select-date () + "Insert a html_select_date statement." + (interactive) + (smarty-template-generic-function "html_select_date" nil '("prefix" "time" "start_year" "end_year" "display_days" "display_months" "display_years" "month_format" "day_format" "day_value_format" "year_as_text" "reverse_years" "field_array" "day_size" "month_size" "year_size" "all_extra" "day_extra" "month_extra" "year_extra" "field_order" "field_separator" "month_value_format" "year_empty" "month_empty" "day_empty") 0)) + +(defun smarty-template-html-select-time () + "Insert a html_select_time statement." + (interactive) + (smarty-template-generic-function "html_select_time" nil '("prefix" "time" "display_hours" "display_minutes" "display_seconds" "display_meridian" "use_24_hours" "minute_interval" "second_interval" "field_array" "all_extra" "hour_extra" "minute_extra" "second_extra" "meridian_extra") 0)) + +(defun smarty-template-html-table () + "Insert a html_table statement." + (interactive) + (smarty-template-generic-function "html_table" nil '("loop" "cols" "rows" "inner" "caption" "table_attr" "th_attr" "tr_attr" "td_attr" "trailpad" "hdir" "vdir") 1)) + +(defun smarty-template-mailto () + "Insert a mailto statement." + (interactive) + (smarty-template-generic-function "mailto" nil '("address" "text" "encode" "cc" "bcc" "subject" "newsgroups" "followupto" "extra") 1)) + +(defun smarty-template-math () + "Insert a math statement." + (interactive) + (smarty-template-generic-function "math" nil '("equation" "var" "format" "assign") 2 t)) + +(defun smarty-template-popup () + "Insert a popup statement." + (interactive) + (smarty-template-generic-function "popup" nil '("text" "trigger" "sticky" "caption" "fgcolor" "bgcolor" "textcolor" "capcolor" "closecolor" "textfont" "captionfont" "closefont" "textsize" "captionsize" "closesize" "width" "height" "left" "right" "center" "above" "below" "border" "offsetx" "offsety" "fgbackground" "bgbackground" "closetext" "noclose" "status" "autostatus" "autostatuscap" "inarray" "caparray" "capicon" "snapx" "snapy" "fixx" "fixy" "background" "padx" "pady" "fullhtml" "frame" "function" "delay" "hauto" "vauto") 1)) + +(defun smarty-template-popup-init () + "Insert a popup_init statement." + (interactive) + (smarty-template-generic-function "popup_init" nil '("src") 1)) + +(defun smarty-template-textformat () + "Insert a textformat statement." + (interactive) + (smarty-template-generic-function "textformat" t '("style" "indent" "indent_first" "indent_char" "wrap" "wrap_char" "wrap_cut" "assign") 0)) + +(defun smarty-template-capitalize () + "Insert a capitalize statement." + (interactive) + (smarty-template-generic-modifier "capitalize" '("upcase_numeric") 0)) + +(defun smarty-template-cat () + "Insert a cat statement." + (interactive) + (smarty-template-generic-modifier "cat" '("value") 0)) + +(defun smarty-template-count-characters () + "Insert a count_characters statement." + (interactive) + (smarty-template-generic-modifier "count_characters" '("include_whitespace") 0)) + +(defun smarty-template-count-paragraphs () + "Insert a count_paragraphs statement." + (interactive) + (smarty-template-generic-modifier "count_paragraphs" '() 0)) + +(defun smarty-template-count-sentences () + "Insert a count_sentences statement." + (interactive) + (smarty-template-generic-modifier "count_sentences" '() 0)) + +(defun smarty-template-count-words () + "Insert a count_words statement." + (interactive) + (smarty-template-generic-modifier "count_words" '() 0)) + +(defun smarty-template-date-format () + "Insert a date_format statement." + (interactive) + (smarty-template-generic-modifier "date_format" '("format" "default") 0)) + +(defun smarty-template-default () + "Insert a default statement." + (interactive) + (smarty-template-generic-modifier "default" '("value") 0)) + +(defun smarty-template-escape () + "Insert a escape statement." + (interactive) + (smarty-template-generic-modifier "escape" '("html|htmlall|url|urlpathinfo|quotes|hex|hexentity|javascript|mail" "charset") 0)) + +(defun smarty-template-indent () + "Insert a indent statement." + (interactive) + (smarty-template-generic-modifier "indent" '("value" "character") 0)) + +(defun smarty-template-lower () + "Insert a lower statement." + (interactive) + (smarty-template-generic-modifier "lower" '() 0)) + +(defun smarty-template-nl2br () + "Insert a nl2br statement." + (interactive) + (smarty-template-generic-modifier "nl2br" '() 0)) + +(defun smarty-template-regex-replace () + "Insert a regex_replace statement." + (interactive) + (smarty-template-generic-modifier "regex_replace" '("regexp" "string_to_replace") 2)) + +(defun smarty-template-replace () + "Insert a replace statement." + (interactive) + (smarty-template-generic-modifier "replace" '("string" "string_to_replace_with") 2)) + +(defun smarty-template-spacify () + "Insert a spacify statement." + (interactive) + (smarty-template-generic-modifier "spacify" '("character") 0)) + +(defun smarty-template-string-format () + "Insert a string_format statement." + (interactive) + (smarty-template-generic-modifier "string_format" '("format") 1)) + +(defun smarty-template-vstrip () + "Insert a strip statement." + (interactive) + (smarty-template-generic-modifier "strip" '() 0)) + +(defun smarty-template-strip-tags () + "Insert a strip_tags statement." + (interactive) + (smarty-template-generic-modifier "strip_tags" '("replace_by_space") 0)) + +(defun smarty-template-truncate () + "Insert a truncate statement." + (interactive) + (smarty-template-generic-modifier "truncate" '("count" "text_to_replace" "character_boundary" "middle_string") 0)) + +(defun smarty-template-upper () + "Insert a upper statement." + (interactive) + (smarty-template-generic-modifier "upper" '() 0)) + +(defun smarty-template-wordwrap () + "Insert a wordwrap statement." + (interactive) + (smarty-template-generic-modifier "wordwrap" '("count" "string" "character_boundary") 0)) + + +(defun smarty-template-validate () + "Insert a validate statement." + (interactive) + (smarty-template-generic-function "validate" nil '("field" "criteria" "message" "form" "transform" "trim" "empty" "halt" "assign" "append" "page") 3)) + +(defun smarty-template-formtool-checkall () + "Insert a formtool_checkall statement." + (interactive) + (smarty-template-generic-function "formtool_checkall" nil '("name" "class" "style") 1)) + +(defun smarty-template-formtool-copy () + "Insert a formtool_copy statement." + (interactive) + (smarty-template-generic-function "formtool_copy" nil '("from" "to" "save" "button_text" "all" "counter" "class" "style") 3)) + +(defun smarty-template-formtool-count-chars () + "Insert a formtool_count_chars statement." + (interactive) + (smarty-template-generic-function "formtool_count_chars" nil '("name" "limit" "alert") 3)) + +(defun smarty-template-formtool-init () + "Insert a formtool_init statement." + (interactive) + (smarty-template-generic-function "formtool_init" nil '("src") 1)) + +(defun smarty-template-formtool-move () + "Insert a formtool_move statement." + (interactive) + (smarty-template-generic-function "formtool_move" nil '("from" "to" "save_from" "save_to" "all" "count_to" "count_from" "class" "style") 4)) + +(defun smarty-template-formtool-moveall () + "Insert a formtool_moveall statement." + (interactive) + (smarty-template-generic-function "formtool_moveall" nil '("from" "to" "save_from" "save_to" "all" "count_to" "count_from" "class" "style") 4)) + +(defun smarty-template-formtool-movedown () + "Insert a formtool_movedown statement." + (interactive) + (smarty-template-generic-function "formtool_movedown" nil '("save" "name" "class" "style") 2)) + +(defun smarty-template-formtool-moveup () + "Insert a formtool_moveup statement." + (interactive) + (smarty-template-generic-function "formtool_moveup" nil '("save" "name" "class" "style") 2)) + +(defun smarty-template-formtool-remove () + "Insert a formtool_remove statement." + (interactive) + (smarty-template-generic-function "formtool_remove" nil '("from" "save" "all" "counter" "class" "style") 2)) + +(defun smarty-template-formtool-rename () + "Insert a formtool_rename statement." + (interactive) + (smarty-template-generic-function "formtool_rename" nil '("name" "from" "save" "class" "style") 3)) + +(defun smarty-template-formtool-save () + "Insert a formtool_save statement." + (interactive) + (smarty-template-generic-function "formtool_save" nil '("from" "name" "save") 3)) + +(defun smarty-template-formtool-selectall () + "Insert a formtool_selectall statement." + (interactive) + (smarty-template-generic-function "formtool_selectall" nil '("name" "class" "style") 1)) + +(defun smarty-template-paginate-first () + "Insert a paginate_first statement." + (interactive) + (smarty-template-generic-function "paginate_first" nil '("id" "text") 0)) + +(defun smarty-template-paginate-last () + "Insert a paginate_last statement." + (interactive) + (smarty-template-generic-function "paginate_last" nil '("id" "text") 0)) + +(defun smarty-template-paginate-middle () + "Insert a paginate_middle statement." + (interactive) + (smarty-template-generic-function "paginate_middle" nil '("id" "format" "prefix" "page_limit" "link_prefix" "link_suffix") 0)) + +(defun smarty-template-paginate-next () + "Insert a paginate_next statement." + (interactive) + (smarty-template-generic-function "paginate_next" nil '("id" "text") 0)) + +(defun smarty-template-paginate-prev () + "Insert a paginate_prev statement." + (interactive) + (smarty-template-generic-function "paginate_prev" nil '("id" "text") 0)) + + +(defun smarty-template-btosmilies () + "Insert a B2Smilies statement." + (interactive) + (smarty-template-generic-modifier "B2Smilies" '() 0)) + +(defun smarty-template-bbcodetohtml () + "Insert a bbcode2html statement." + (interactive) + (smarty-template-generic-modifier "bbcode2html" '() 0)) + +(defun smarty-template-date-formatto () + "Insert a date_format2 statement." + (interactive) + (smarty-template-generic-modifier "date_format2" '("format" "default") 0)) + +;; + +(defun smarty-resolve-env-variable (string) + "Resolve environment variables in STRING." + (while (string-match "\\(.*\\)${?\\(\\(\\w\\|_\\)+\\)}?\\(.*\\)" string) + (setq string (concat (match-string 1 string) + (getenv (match-string 2 string)) + (match-string 4 string)))) + string) + +(defun smarty-insert-string-or-file (string) + "Insert STRING or file contents if STRING is an existing file name." + (unless (equal string "") + (let ((file-name + (progn (string-match "^\\([^\n]+\\)" string) + (smarty-resolve-env-variable (match-string 1 string))))) + (if (file-exists-p file-name) + (forward-char (cadr (insert-file-contents file-name))) + (insert string))))) + +(defun smarty-template-insert-date () + "Insert date in appropriate format." + (interactive) + (insert + (cond + ;; 'american, 'european, 'scientific kept for backward compatibility + ((eq smarty-date-format 'american) (format-time-string "%m/%d/%Y" nil)) + ((eq smarty-date-format 'european) (format-time-string "%d.%m.%Y" nil)) + ((eq smarty-date-format 'scientific) (format-time-string "%Y/%m/%d" nil)) + (t (format-time-string smarty-date-format nil))))) + +(defun smarty-template-header (&optional file-title) + "Insert a Smarty file header." + (interactive) + (unless (equal smarty-file-header "") + (let (pos) + (save-excursion + (smarty-insert-string-or-file smarty-file-header) + (setq pos (point-marker))) + (smarty-template-replace-header-keywords + (point-min-marker) pos file-title)))) + +(defun smarty-template-footer () + "Insert a Smarty file footer." + (interactive) + (unless (equal smarty-file-footer "") + (let (pos) + (save-excursion + (setq pos (point-marker)) + (smarty-insert-string-or-file smarty-file-footer) + (unless (= (preceding-char) ?\n) + (insert "\n"))) + (smarty-template-replace-header-keywords pos (point-max-marker))))) + +(defun smarty-template-replace-header-keywords (beg end &optional file-title is-model) + "Replace keywords in header and footer." + (let () + (smarty-prepare-search-2 + (save-excursion + (goto-char beg) + (while (search-forward "" end t) + (replace-match (buffer-name) t t)) + (goto-char beg) + (while (search-forward "" end t) + (replace-match smarty-copyright-string t t)) + (goto-char beg) + (while (search-forward "" end t) + (replace-match "" t t) + (insert (user-full-name)) + (when user-mail-address (insert " <" user-mail-address ">"))) + (goto-char beg) + (while (search-forward "" end t) + (replace-match (user-login-name) t t)) + (goto-char beg) + (while (search-forward "" end t) + (replace-match smarty-company-name t t)) + (goto-char beg) + ;; Replace with $, so that RCS for the source is + ;; not over-enthusiastic with replacements + (while (search-forward "" end t) + (replace-match "$" nil t)) + (goto-char beg) + (while (search-forward "" end t) + (replace-match "" t t) + (smarty-template-insert-date)) + (goto-char beg) + (while (search-forward "" end t) + (replace-match (format-time-string "%Y" nil) t t)) + (goto-char beg) + (let (string) + (while + (re-search-forward "<\\(\\(\\w\\|\\s_\\)*\\) string>" end t) + (setq string (read-string (concat (match-string 1) ": "))) + (replace-match string t t))) + (goto-char beg) + (when (and (not is-model) (search-forward "" end t)) + (replace-match "" t t)))))) + +(provide 'smarty-mode) +;;; smarty-mode.el ends here \ No newline at end of file diff --git a/emacs/nxhtml/autostart.el b/emacs/nxhtml/autostart.el new file mode 100644 index 0000000..44a6901 --- /dev/null +++ b/emacs/nxhtml/autostart.el @@ -0,0 +1,194 @@ +;;; autostart.el --- Load nxhtml +;; +;; Author: By: Lennart Borgman +;; Created: Fri Dec 15 2006 +;; Version: +;; Last-Updated: 2009-04-30 Thu +;; Keywords: +;; Compatibility: +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; Fix-me: Split out the definitions from this file so it can be +;; loaded during byte compilation. + +;;(eval-when-compile (require 'web-vcs nil t)) +;;(eval-when-compile (require 'nxhtml-web-vcs nil t)) + +(message "Nxml/Nxhtml Autostart.el loading ...") + +(defconst nxhtml-autostart-trace nil) +(defsubst nxhtml-autostart-trace (format-string &rest args) + (when nxhtml-autostart-trace + (apply 'message format-string args))) + +(defconst nxhtml-load-time-start (float-time)) + +;; Add this dir to load-path +(add-to-list 'load-path + (file-name-directory (or load-file-name + (when (boundp 'bytecomp-filename) bytecomp-filename) + buffer-file-name))) + +(require 'nxhtml-base) +(eval-and-compile (when (fboundp 'nxml-mode) + (load (expand-file-name "etc/schema/schema-path-patch" + nxhtml-install-dir)))) + +;; (defun nxhtml-custom-load-and-get-value (symbol) +;; (custom-load-symbol symbol) +;; (symbol-value symbol)) + +(defun nxhtml-list-loaded-features (use-message) + (interactive (list t)) + (let ((buf (when use-message ;(called-interactively-p) + (get-buffer-create "*nXhtml loaded features*")))) + (if buf + (with-current-buffer buf (erase-buffer)) + (message "") + (message "=== Loaded at nxhtml/autostart.el end:")) + (dolist (feature '( + as-external + html-chklnk + html-imenu + html-move + html-pagetoc + html-quote + html-site + html-toc + html-upl + html-wtoc + inlimg + mumamo + nxhtml-bug + nxhtml-menu + nxhtml-mode + nxhtml-mumamo + nxhtml-strval + nxhtml + nxhtml-js + nxml-where + outline-magic + rngalt + tidy-xhtml + xhtml-help + )) + (when (featurep feature) + (if buf + (with-current-buffer buf + (insert (format "(feature '%s)=%s\n" feature (featurep feature)))) + (message "(feature '%s)=%s" feature (featurep feature))))) + (if buf + (display-buffer buf) + (message "")))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Code that will run on loading this file + +(if (< emacs-major-version 23) + (unless (featurep 'autostart22) + (load (expand-file-name "autostart22" nxhtml-install-dir))) + ;; Check that the nxml-mode included with Emacs is used. There + ;; has been some problems on Debian with this. + (let ((nxml-mode-file (locate-library "nxml-mode")) + (help-file (locate-library "help"))) + (unless (string= (expand-file-name ".." help-file) + (expand-file-name "../.." nxml-mode-file)) + (error "Wrong nxml-mode=%s used, please use the one that comes with Emacs" nxml-mode-file)))) + +(let* ((util-dir (file-name-as-directory (expand-file-name "util" nxhtml-install-dir))) + (related-dir (file-name-as-directory (expand-file-name "related" nxhtml-install-dir))) + (nxhtml-dir (file-name-as-directory (expand-file-name "nxhtml" nxhtml-install-dir))) + ;;(company-dir (file-name-as-directory (expand-file-name "util/nxhtml-company-mode" nxhtml-install-dir))) + (tests-dir (file-name-as-directory (expand-file-name "tests" nxhtml-install-dir)))) + (add-to-list 'load-path nxhtml-dir) + (add-to-list 'load-path related-dir) + (add-to-list 'load-path util-dir) + (add-to-list 'load-path nxhtml-install-dir) + ;;(add-to-list 'load-path company-dir) + (add-to-list 'load-path tests-dir) + + (nxhtml-autostart-trace "... nXhtml loading %.1f seconds elapsed ..." (- (float-time) nxhtml-load-time-start)) + + ;; Autoloading etc + ;; (unless (featurep 'web-vcs) + ;; (load (expand-file-name "web-vcs" nxhtml-install-dir) (not nxhtml-autoload-web))) + + ;; (when (catch 'miss + ;; (dolist (file nxhtml-basic-files) + ;; (let ((dl-file (expand-file-name file nxhtml-install-dir))) + ;; (unless (file-exists-p dl-file) + ;; (throw 'miss t)))) + ;; nil) + ;; (nxhtml-setup-auto-download nxhtml-install-dir)) + + (unless (featurep 'web-autoload) + (load (expand-file-name "web-autoload" nxhtml-install-dir) (not nxhtml-autoload-web))) + + (when nxhtml-autoload-web + (ad-activate 'require t)) + + ;; Fix-me: Why must as-external be loaded? Why doesn't it work in batch? + ;;(unless noninteractive (require 'as-external)) + + (unless (featurep 'nxhtml-loaddefs) + (load (expand-file-name "nxhtml-loaddefs" nxhtml-install-dir) nxhtml-autoload-web)) + (nxhtml-autostart-trace "... nXhtml loading %.1f seconds elapsed ..." (- (float-time) nxhtml-load-time-start)) + + ;; Turn on `nxhtml-menu-mode' unconditionally + (nxhtml-autostart-trace "Turn on `nxhtml-menu-mode' unconditionally") + (nxhtml-menu-mode 1) + (nxhtml-autostart-trace "... nXhtml loading %.1f seconds elapsed ..." (- (float-time) nxhtml-load-time-start)) + + ;; Patch the rnc include paths + (when (fboundp 'rncpp-patch-xhtml-loader) (rncpp-patch-xhtml-loader)) + (nxhtml-autostart-trace "... nXhtml loading %.1f seconds elapsed ..." (- (float-time) nxhtml-load-time-start)) + + ;; Load nXhtml + (unless (featurep 'nxhtml-autoload) + (load (expand-file-name "nxhtml/nxhtml-autoload" nxhtml-install-dir)))) +(nxhtml-autostart-trace "... nXhtml loading %.1f seconds elapsed ..." (- (float-time) nxhtml-load-time-start)) + + +(unless (featurep 'nxhtml-autostart) + ;; Provide the feature here to avoid loading looping on error. + (provide 'nxhtml-autostart) + + ;; Tell what have been loaded of nXhtml: + (when nxhtml-autostart-trace (nxhtml-list-loaded-features nil)) + + ;; How long time did it all take? + (message "Nxml/Nxhtml Autostart.el loaded in %.1f seconds" (- (float-time) nxhtml-load-time-start))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; autostart.el ends here diff --git a/emacs/nxhtml/autostart22.el b/emacs/nxhtml/autostart22.el new file mode 100644 index 0000000..2376d43 --- /dev/null +++ b/emacs/nxhtml/autostart22.el @@ -0,0 +1,71 @@ +;;; autostart22.el --- Example of autostart file for Emacs22 +;; +;; Author: Lennart Borgman (lennart O borgman A gmail O com) +;; Created: 2009-01-01 Thu +;; Version: +;; Last-Updated: 2009-01-05 Mon +;; URL: +;; Keywords: +;; Compatibility: +;; +;; Features that might be required by this library: +;; +;; This file is for Emacs 22 only. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; Change this file according to the path of your nxml-mode dir. If +;; you do not use nxml-mode then just use autostart.el. +;; +;; NOTICE: You need to enter the path to your nxml-mode installation +;; below. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(let ((debug-on-error t)) + (if (/= emacs-major-version 22) + (message "This file (autostart22.el) is for Emacs 22 only") + + (defalias 'Custom-mode 'custom-mode) + + (let* ((this-file (or load-file-name buffer-file-name)) + (this-dir (file-name-directory this-file)) + ;; FIX-ME: Download nXml (since it is not included in Emacs + ;; 22) and place the path to rng-auto.el in your downloaded + ;; nXml HERE: + (rng-auto-file (or (locate-library "rng-auto.el") + "c:/emacs/u/081231/EmacsW32/nxhtml/nxml-mode-20041004/rng-auto.el"))) + (unless (file-exists-p rng-auto-file) + (error "Can't find rng-auto.el, please edit %s" this-file)) + (load rng-auto-file)))) + +(provide 'autostart22) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; autostart22.el ends here diff --git a/emacs/nxhtml/emacs22.cmd b/emacs/nxhtml/emacs22.cmd new file mode 100644 index 0000000..d50ac96 --- /dev/null +++ b/emacs/nxhtml/emacs22.cmd @@ -0,0 +1 @@ +c:\emacs\emacs-22.3\bin\emacs.exe -Q --debug-init -l autostart.el diff --git a/emacs/nxhtml/etc/img/pause/pause.jpg b/emacs/nxhtml/etc/img/pause/pause.jpg new file mode 100644 index 0000000..ff92075 Binary files /dev/null and b/emacs/nxhtml/etc/img/pause/pause.jpg differ diff --git a/emacs/nxhtml/etc/img/pause/pause2.jpg b/emacs/nxhtml/etc/img/pause/pause2.jpg new file mode 100644 index 0000000..6411344 Binary files /dev/null and b/emacs/nxhtml/etc/img/pause/pause2.jpg differ diff --git a/emacs/nxhtml/etc/schema/FDA-2009-N-0392-0396.1.doc b/emacs/nxhtml/etc/schema/FDA-2009-N-0392-0396.1.doc new file mode 100644 index 0000000..aa2eff3 Binary files /dev/null and b/emacs/nxhtml/etc/schema/FDA-2009-N-0392-0396.1.doc differ diff --git a/emacs/nxhtml/etc/schema/genshi-old.rnc b/emacs/nxhtml/etc/schema/genshi-old.rnc new file mode 100644 index 0000000..5384fe1 --- /dev/null +++ b/emacs/nxhtml/etc/schema/genshi-old.rnc @@ -0,0 +1,27 @@ +namespace py = "http://genshi.edgewall.org/" + +genshi.expr-type = xsd:string { minLength = "1" } +genshi.with-type = xsd:string { minLength = "1" } +genshi.choose-type = xsd:string +genshi.def-type = xsd:string +genshi.xpath-type = xsd:anyURI + +genshi.attrib = attribute py:if { genshi.expr-type }?, + attribute py:choose { genshi.choose-type }?, + attribute py:when { genshi.expr-type }?, + attribute py:otherwise { genshi.expr-type }?, + attribute py:for { genshi.expr-type }?, + attribute py:def { genshi.def-type }?, + attribute py:match { genshi.xpath-type }?, + attribute py:with { genshi.with-type }?, + attribute py:attrs { genshi.expr-type }?, + attribute py:content { genshi.expr-type }?, + attribute py:replace { genshi.expr-type }?, + attribute py:strip { genshi.expr-type }? + +genshi.if.attlist = attribute expr { genshi.expr-type } +genshi.for.attlist = attribute each { genshi.expr-type } +genshi.def.attlist = attribute each { genshi.expr-type } +genshi.with.attlist = attribute vars { genshi.with-type } + + diff --git a/emacs/nxhtml/etc/schema/genshi-schemas.xml b/emacs/nxhtml/etc/schema/genshi-schemas.xml new file mode 100644 index 0000000..89fe05f --- /dev/null +++ b/emacs/nxhtml/etc/schema/genshi-schemas.xml @@ -0,0 +1,3 @@ + + + diff --git a/emacs/nxhtml/etc/schema/genshi.rnc b/emacs/nxhtml/etc/schema/genshi.rnc new file mode 100644 index 0000000..b9ddf76 --- /dev/null +++ b/emacs/nxhtml/etc/schema/genshi.rnc @@ -0,0 +1,84 @@ +default namespace = "http://genshi.edgewall.org/" +namespace py = "http://genshi.edgewall.org/" + +include "xinclude.rnc" + +# There's no way to just match the text part against a Genshi Python expression +# See: http://relaxng.org/compact-tutorial-20030326.html#id2814737 +python.expression = text + +genshi.expr-type = xsd:string { minLength = "1" } +genshi.xpath-type = xsd:anyURI + +genshi.attrib = + attribute py:if { genshi.expr-type }?, + attribute py:choose { text }?, + attribute py:when { genshi.expr-type }?, + attribute py:otherwise { text }?, + attribute py:for { genshi.expr-type }?, + attribute py:def { genshi.expr-type }?, + attribute py:match { genshi.xpath-type}?, + attribute py:with { genshi.expr-type }?, + attribute py:attrs { genshi.expr-type }?, + attribute py:content { text }?, + attribute py:replace { genshi.expr-type }?, + attribute py:strip { text }? + +genshi.if.attlist = attribute test { genshi.expr-type } +genshi.choose.attlist = attribute test { text } +genshi.when.attlist = attribute test { genshi.expr-type } +genshi.for.attlist = attribute each { genshi.expr-type } +genshi.def.attlist = attribute function { genshi.expr-type } +genshi.with.attlist = attribute vars { genshi.expr-type } +genshi.replace.attlist = attribute value { genshi.expr-type } +genshi.match.attlist = + attribute path { genshi.xpath-type }, + attribute buffer { "true" | "false" }?, + attribute once { "true" | "false" }?, + attribute recursive { "true" | "false" }? + +genshi.choose = + element py:choose { genshi.choose.attlist, + genshi.model + } +genshi.when = + element py:when { genshi.when.attlist, + genshi.model + } +genshi.otherwise = + element py:otherwise { + genshi.model + } +genshi.if = + element py:if { genshi.if.attlist, + genshi.model + } +genshi.for = + element py:for { genshi.for.attlist, + genshi.model + } +genshi.def = + element py:def { genshi.def.attlist, + genshi.model + } +genshi.with = + element py:with { genshi.with.attlist, + genshi.model + } +genshi.match = + element py:match { genshi.match.attlist, + genshi.model + } +genshi.replace = + element py:replace { genshi.replace.attlist, + genshi.model + } + +genshi.allowed.children = text + +genshi.class = genshi.if | genshi.choose | genshi.when | genshi.otherwise + | genshi.for | genshi.def | genshi.with | genshi.match | genshi.replace + | python.expression + | xi.include + +genshi.model = genshi.class* | genshi.allowed.children* \ No newline at end of file diff --git a/emacs/nxhtml/etc/schema/mjt.rnc b/emacs/nxhtml/etc/schema/mjt.rnc new file mode 100644 index 0000000..b37f01a --- /dev/null +++ b/emacs/nxhtml/etc/schema/mjt.rnc @@ -0,0 +1,74 @@ +include "xhtml-loader.rnc" + +MjtAll.attrib = + attribute mjt.def { Text.datatype }?, + attribute mjt.when { Text.datatype }?, + attribute mjt.otherwise { Text.datatype }?, + attribute mjt.for { Text.datatype }?, + attribute mjt.if { Text.datatype }?, + attribute mjt.elif { Text.datatype }?, + attribute mjt.else { Text.datatype }?, + attribute mjt.script { Text.datatype }?, + attribute mjt.choose { Text.datatype }?, + attribute mjt.replace { Text.datatype }?, + attribute mjt.content { Text.datatype }?, + attribute mjt.strip { Text.datatype }?, + attribute mjt.src { Text.datatype }?, + attribute mjt.style { Text.datatype }?, + attribute mjt.class { Text.datatype }?, + attribute mjt.id { Text.datatype }?, + attribute mjt.attrs { Text.datatype }?, + attribute mjt.task { Text.datatype }? + + +a.attlist &= + attribute mjt.onblur { Script.datatype }?, + attribute mjt.onfocus { Script.datatype }? +area.attlist &= + attribute mjt.onblur { Script.datatype }?, + attribute mjt.onfocus { Script.datatype }? +form.attlist &= + attribute mjt.onreset { Script.datatype }?, + attribute mjt.onsubmit { Script.datatype }? +body.attlist &= + attribute mjt.onload { Script.datatype }?, + attribute mjt.onunload { Script.datatype }? +label.attlist &= + attribute mjt.onblur { Script.datatype }?, + attribute mjt.onfocus { Script.datatype }? +input.attlist &= + attribute mjt.onblur { Script.datatype }?, + attribute mjt.onchange { Script.datatype }?, + attribute mjt.onfocus { Script.datatype }?, + attribute mjt.onselect { Script.datatype }? +select.attlist &= + attribute mjt.onblur { Script.datatype }?, + attribute mjt.onchange { Script.datatype }?, + attribute mjt.onfocus { Script.datatype }? +textarea.attlist &= + attribute mjt.onblur { Script.datatype }?, + attribute mjt.onchange { Script.datatype }?, + attribute mjt.onfocus { Script.datatype }?, + attribute mjt.onselect { Script.datatype }? +button.attlist &= + attribute mjt.onblur { Script.datatype }?, + attribute mjt.onfocus { Script.datatype }? + +MjtEvents.attrib = + attribute mjt.onclick { Script.datatype }?, + attribute mjt.ondblclick { Script.datatype }?, + attribute mjt.onmousedown { Script.datatype }?, + attribute mjt.onmouseup { Script.datatype }?, + attribute mjt.onmouseover { Script.datatype }?, + attribute mjt.onmousemove { Script.datatype }?, + attribute mjt.onmouseout { Script.datatype }?, + attribute mjt.onkeypress { Script.datatype }?, + attribute mjt.onkeydown { Script.datatype }?, + attribute mjt.onkeyup { Script.datatype }? + + +Common.attrib &= MjtAll.attrib +CommonIdRequired.attrib &= MjtAll.attrib + +Common.attrib &= MjtEvents.attrib +CommonIdRequired.attrib &= MjtEvents.attrib diff --git a/emacs/nxhtml/etc/schema/nxml-erb.patch b/emacs/nxhtml/etc/schema/nxml-erb.patch new file mode 100644 index 0000000..362913b --- /dev/null +++ b/emacs/nxhtml/etc/schema/nxml-erb.patch @@ -0,0 +1,37 @@ +--- nxml-mode-orig/xmltok.el 2005-10-16 15:32:53.000000000 -0400 ++++ nxml-mode-erb/xmltok.el 2006-09-01 01:02:55.000000000 -0400 +@@ -496,6 +496,9 @@ + (xmltok+ (xmltok-g markup-declaration "!") + (xmltok-g comment-first-dash "-" + (xmltok-g comment-open "-") opt) opt)) ++ (erb-section ++ (xmltok+ "%" ++ (xmltok-g erb-section-open "[^%]") opt)) + (cdata-section + (xmltok+ "!" + (xmltok-g marked-section-open "\\[") +@@ -526,6 +529,7 @@ + ;; by default + or cdata-section + or comment ++ or erb-section + or processing-instruction)) + (xmltok-defregexp + xmltok-attribute +@@ -693,6 +697,16 @@ + nil + "]]>") + 'not-well-formed))) ++ ((xmltok-after-lt start erb-section-open) ++ (setq xmltok-type ++ (if (re-search-forward "[^%]%>" nil t) ++ 'erb-section ++ (xmltok-add-error "No closing %>") ++ (xmltok-add-dependent 'xmltok-unclosed-reparse-p ++ nil ++ nil ++ "%>") ++ 'not-well-formed))) + ((xmltok-after-lt start processing-instruction-question) + (xmltok-scan-after-processing-instruction-open)) + ((xmltok-after-lt start comment-open) diff --git a/emacs/nxhtml/etc/schema/old-genshi.rnc b/emacs/nxhtml/etc/schema/old-genshi.rnc new file mode 100644 index 0000000..5a50385 --- /dev/null +++ b/emacs/nxhtml/etc/schema/old-genshi.rnc @@ -0,0 +1,31 @@ +namespace py = "http://genshi.edgewall.org/" + +genshi.expr-type = xsd:string { minLength = "1" } +genshi.with-type = xsd:string { minLength = "1" } +genshi.choose-type = xsd:string +genshi.def-type = xsd:string +genshi.xpath-type = xsd:anyURI + +genshi.attrib = attribute py:if { genshi.expr-type }?, + attribute py:choose { genshi.choose-type }?, + attribute py:when { genshi.expr-type }?, + attribute py:otherwise { genshi.expr-type }?, + attribute py:for { genshi.expr-type }?, + attribute py:def { genshi.def-type }?, + attribute py:match { genshi.xpath-type }?, + attribute py:with { genshi.with-type }?, + attribute py:attrs { genshi.expr-type }?, + attribute py:content { genshi.expr-type }?, + attribute py:replace { genshi.expr-type }?, + attribute py:strip { genshi.expr-type }? + +genshi.if.attlist = attribute test { genshi.expr-type } +genshi.for.attlist = attribute each { genshi.expr-type } +genshi.def.attlist = attribute function { genshi.expr-type } +genshi.with.attlist = attribute vars { genshi.with-type } +genshi.match.attlist = attribute path { genshi.xpath-type }, + attribute buffer { genshi.expr-type }?, + attribute once { genshi.expr-type }?, + attribute recursive { genshi.expr-type }? + + diff --git a/emacs/nxhtml/etc/schema/old-qtmstr-xhtml.rnc b/emacs/nxhtml/etc/schema/old-qtmstr-xhtml.rnc new file mode 100644 index 0000000..b5f84bd --- /dev/null +++ b/emacs/nxhtml/etc/schema/old-qtmstr-xhtml.rnc @@ -0,0 +1,61 @@ +namespace py = "http://genshi.edgewall.org/" +namespace xi = "http://www.w3.org/2001/XInclude" + +include "genshi.rnc" +include "xinclude.rnc" +include "xhtml-loader.rnc" + +start |= head|body|p|\div|h1|h2|h3|h4|h5|h6|hr|pre|dl|ol|ul|table|form + +Common.attrib &= genshi.attrib +head.attlist &= genshi.attrib +html.attlist &= genshi.attrib + +Head.class = base | isindex | link | meta | script | title | style | + if-head | for-head | def-head | with-head + +Head.model = Head.class* + +head.content &= Head.model* + +if-inline = element py:if { genshi.if.attlist, Inline.model } +if-block = element py:if { genshi.if.attlist, Block.model } +if-head = element py:if { genshi.if.attlist, Head.model } +for-inline = element py:for { genshi.for.attlist, Inline.model } +for-block = element py:for { genshi.for.attlist, Block.model } +for-head = element py:for { genshi.for.attlist, Head.model } +def-inline = element py:def { genshi.def.attlist, Inline.model } +def-block = element py:def { genshi.def.attlist, Block.model } +def-head = element py:def { genshi.def.attlist, Head.model } +with-inline = element py:with { genshi.with.attlist, Inline.model } +with-block = element py:with { genshi.with.attlist, Block.model } +with-head = element py:with { genshi.with.attlist, Head.model } +match-inline = element py:match { genshi.match.attlist, Inline.model } +match-block = element py:match { genshi.match.attlist, Block.model } +match-head = element py:match { genshi.match.attlist, Head.model } + +Inline.class |= if-inline | for-inline | def-inline | with-inline | match-inline +Block.class |= if-block | for-block | def-block | with-block | match-block + +xi-inline = element xi:include { + xinclude.include.attlist, + element xi:fallback { genshi.attrib, + (xi-inline | Inline.model)* + }? + } + +xi-block = element xi:include { xinclude.include.attlist, + element xi:fallback { genshi.attrib, + (xi-block | Block.model)* + }? + } + +xi-head = element xi:include { xinclude.include.attlist, + element xi:fallback { genshi.attrib, + (xi-head | Head.model)* + }? + } + +Inline.class |= xi-inline +Block.class |= xi-block +Head.class |= xi-head diff --git a/emacs/nxhtml/etc/schema/old-xinclude.rnc b/emacs/nxhtml/etc/schema/old-xinclude.rnc new file mode 100644 index 0000000..c45cf0c --- /dev/null +++ b/emacs/nxhtml/etc/schema/old-xinclude.rnc @@ -0,0 +1,11 @@ +namespace xi = "http://www.w3.org/2001/XInclude" +namespace local = "" + +xinclude.include.attlist = + attribute href { xsd:anyURI }?, + attribute parse { xsd:string }?, + attribute xpointer { xsd:string }?, + attribute encoding { xsd:string }?, + attribute accept { xsd:string }?, + attribute accept-language { xsd:string }? + diff --git a/emacs/nxhtml/etc/schema/qtmstr-xhtml-old.rnc b/emacs/nxhtml/etc/schema/qtmstr-xhtml-old.rnc new file mode 100644 index 0000000..61ab89e --- /dev/null +++ b/emacs/nxhtml/etc/schema/qtmstr-xhtml-old.rnc @@ -0,0 +1,58 @@ +namespace py = "http://genshi.edgewall.org/" +namespace xi = "http://www.w3.org/2001/XInclude" + +include "genshi.rnc" +include "xinclude.rnc" +include "xhtml-loader.rnc" + +start |= head|body|p|\div|h1|h2|h3|h4|h5|h6|hr|pre|dl|ol|ul|table|form + +Common.attrib &= genshi.attrib +head.attlist &= genshi.attrib +html.attlist &= genshi.attrib + +Head.class = base | isindex | link | meta | script | title | style | + if-head | for-head | def-head | with-head + +Head.model = Head.class* + +head.content &= Head.model* + +if-inline = element py:if { genshi.if.attlist, Inline.model } +if-block = element py:if { genshi.if.attlist, Block.model } +if-head = element py:if { genshi.if.attlist, Head.model } +for-inline = element py:for { genshi.for.attlist, Inline.model } +for-block = element py:for { genshi.for.attlist, Block.model } +for-head = element py:for { genshi.for.attlist, Head.model } +def-inline = element py:def { genshi.def.attlist, Inline.model } +def-block = element py:def { genshi.def.attlist, Block.model } +def-head = element py:def { genshi.def.attlist, Head.model } +with-inline = element py:with { genshi.with.attlist, Inline.model } +with-block = element py:with { genshi.with.attlist, Block.model } +with-head = element py:with { genshi.with.attlist, Head.model } + +Inline.class |= if-inline | for-inline | def-inline | with-inline +Block.class |= if-block | for-block | def-block | with-block + +xi-inline = element xi:include { + xinclude.include.attlist, + element xi:fallback { genshi.attrib, + (xi-inline | Inline.model)* + }? + } + +xi-block = element xi:include { xinclude.include.attlist, + element xi:fallback { genshi.attrib, + (xi-block | Block.model)* + }? + } + +xi-head = element xi:include { xinclude.include.attlist, + element xi:fallback { genshi.attrib, + (xi-head | Head.model)* + }? + } + +Inline.class |= xi-inline +Block.class |= xi-block +Head.class |= xi-head diff --git a/emacs/nxhtml/etc/schema/qtmstr-xhtml.rnc b/emacs/nxhtml/etc/schema/qtmstr-xhtml.rnc new file mode 100644 index 0000000..ff5d0a9 --- /dev/null +++ b/emacs/nxhtml/etc/schema/qtmstr-xhtml.rnc @@ -0,0 +1,66 @@ +default namespace = "http://www.w3.org/1999/xhtml" + +include "genshi.rnc" +include "xhtml-loader.rnc" { + start = html | head | head.content | body | frameset | frame | noframes | + Block.class | Inline.class | Table.class | Form.extra.class | genshi.class + html = element html { html.attlist, (genshi.model | (head, (body | frameset | genshi.model))) } + frameset = + element frameset { + frameset.attlist, + (((frameset | frame)+ & noframes?) | genshi.model) + } + noframes = element noframes { noframes.attlist, (body | genshi.model) } + title = element title { title.attlist, (text | genshi.model)* } + script = element script { script.attlist, (text | genshi.model)* } + style = element style { style.attlist, (text | genshi.model)* } + dl = element dl { dl.attlist, ((dt | dd)+ | genshi.model) } + ol = element ol { ol.attlist, (li+ | genshi.model) } + ul = element ul { ul.attlist, (li+ | genshi.model) } + dir = element dir { dir.attlist, (li.noblock+ | genshi.model) } + menu = element menu { menu.attlist, (li.noblock+ | genshi.model) } + select = element select { select.attlist, ((option | optgroup)+ | genshi.model) } + option = + element option { + Common.attrib, + attribute selected { "selected" }?, + attribute value { text }?, + (text | genshi.model)* + } + textarea = element textarea { textarea.attlist, (text & genshi.model)* } + optgroup = element optgroup { optgroup.attlist, (option+ | genshi.model) } + table = + element table { + table.attlist, + (caption? | genshi.model), + (col* | colgroup* | genshi.model), + (((thead? | genshi.model), + (tfoot? | genshi.model), + (tbody+ | genshi.model)) | (tr+ | genshi.model)) + } + colgroup = element colgroup { colgroup.attlist, (col* | genshi.model) } + tr = element tr { tr.attlist, ((th | td)+ | genshi.model) } + tbody = element tbody { tbody.attlist, (tr+ | genshi.model) } + thead = element thead { thead.attlist, (tr+ | genshi.model) } + tfoot = element tfoot { tfoot.attlist, (tr+ | genshi.model) } +} + +Table.class = caption | colgroup | col | tbody | thead | tfoot | th | tr | td +Form.extra.class = option | optgroup | legend + +Block.class |= genshi.class +Inline.class |= genshi.class +head.content &= genshi.class + +Core.attrib &= genshi.attrib +html.attlist &= genshi.attrib +head.attlist &= genshi.attrib +title.attlist &= genshi.attrib +base.attlist &= genshi.attrib +meta.attlist &= genshi.attrib +script.attlist &= genshi.attrib +param.attlist &= genshi.attrib +Edit.attrib &= genshi.attrib + +genshi.allowed.children |= html | head | head.content | body | frameset | frame + | noframes | Inline.class | Block.class | Table.class | Form.extra.class diff --git a/emacs/nxhtml/etc/schema/schema-path-patch.el b/emacs/nxhtml/etc/schema/schema-path-patch.el new file mode 100644 index 0000000..a6d59fc --- /dev/null +++ b/emacs/nxhtml/etc/schema/schema-path-patch.el @@ -0,0 +1,95 @@ +;;; schema-path-patch.el --- Patch schema paths +;; +;; Author: Lennart Borgman (lennart O borgman A gmail O com) +;; Created: 2008-08-08T20:21:31+0200 Fri +;; Version: 0.2 +;; Last-Updated: 2008-08-19T00:21:25+0200 Mon +;; URL: +;; Keywords: +;; Compatibility: +;; +;; Features that might be required by this library: +;; +;; Cannot open load file: schema-path-patch. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; Schemas here may include parts from nxml and need to know the path. +;; This file can be used to patch the paths. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(defvar rncpp-this-dir + (file-name-as-directory + (file-name-directory + (if load-file-name load-file-name buffer-file-name)))) + +(defun rncpp-get-nxml-schema-dir () + ;; First look for nxml-mode included with Emacs + (let ((schema-dir (file-name-as-directory + (expand-file-name "schema" data-directory)))) + (unless (file-directory-p schema-dir) + ;; This is an old nxml-mode, look for its schemas dir. + (let ((nxml-mode-dir (file-name-as-directory + (file-name-directory (locate-library "nxml-mode"))))) + (setq schema-dir (file-name-as-directory + (expand-file-name "schema" nxml-mode-dir))))) + (unless (file-directory-p schema-dir) + (error "Can't find schema-dir=%s" schema-dir)) + schema-dir)) + +;; Use xhtml-loader.rnc (an idea from Bryan Waite): +(defun rncpp-patch-xhtml-loader () + "Patch xhtml-loader.rnc so genshi and mjt rnc files works." + ;;(interactive) + (let* ((default-directory rncpp-this-dir) + (loader-path (expand-file-name "xhtml-loader.rnc")) + (loader-buf (find-buffer-visiting loader-path)) + (schema-dir (rncpp-get-nxml-schema-dir)) + (schema-relative-dir (file-relative-name schema-dir)) + (loader-string (concat "include \"" + schema-relative-dir + "xhtml.rnc\"\n"))) + (when loader-buf (kill-buffer loader-buf)) + (setq loader-buf (find-file-noselect loader-path)) + (with-current-buffer loader-buf + (unless (file-exists-p loader-path) + (insert loader-string)) + ;; Test if correct + (if (string= (buffer-substring-no-properties (point-min) (point-max)) + loader-string) + (message "xhtml-loader.rnc was ok") + (message "Patching xhtml-loader.rnc") + (delete-region (point-min) (point-max)) + (insert loader-string)) + (basic-save-buffer) + (kill-buffer (current-buffer))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; schema-path-patch.el ends here diff --git a/emacs/nxhtml/etc/schema/xinclude.rnc b/emacs/nxhtml/etc/schema/xinclude.rnc new file mode 100644 index 0000000..cbda979 --- /dev/null +++ b/emacs/nxhtml/etc/schema/xinclude.rnc @@ -0,0 +1,35 @@ +default namespace = "http://www.w3.org/2001/XInclude" +namespace xi = "http://www.w3.org/2001/XInclude" + +xi.include.attlist = + attribute href { xsd:anyURI }?, + attribute parse { "xml" | "text" }?, + attribute xpointer { xsd:string }?, + attribute encoding { xsd:string }?, + attribute accept { xsd:string }?, + attribute accept-language { xsd:string }? + +xi.include.attlist.extra = + attribute * - xi.include.attlist { text }* + +xi.include = + element xi:include { + xi.include.attlist, + xi.include.attlist.extra, + (xi.fallback? | xi.include.extra)* + } + +xi.include.extra = notAllowed + +xi.fallback.attlist = + attribute * { text }* + +xi.fallback = + element xi:fallback { + xi.fallback.attlist, + (xi.include | xi.fallback.extra)* + } + +xi.fallback.extra = notAllowed + +xi.class = xi.include | xi.fallback \ No newline at end of file diff --git a/emacs/nxhtml/etc/templates/rollover-2v.css b/emacs/nxhtml/etc/templates/rollover-2v.css new file mode 100644 index 0000000..ed10a41 --- /dev/null +++ b/emacs/nxhtml/etc/templates/rollover-2v.css @@ -0,0 +1,25 @@ +ROLLOVER_SPEC a { + /* Image */ + display: block; + background: transparent url("IMG_URL") 0 0 no-repeat; + overflow: hidden; + width: IMG_WIDTHpx; + /* Text placement and size, etc */ + CENTER_OR_PAD; + padding-top: PADDING_TOPpx; + font-size: FONT_SIZEpx; + padding-bottom: PADDING_BOTTOMpx; + text-decoration: none; + white-space: nowrap; + border: none; + margin: 0; +} +ROLLOVER_SPEC a:hover { + background-position: 0 -IMG_HEIGHT_2px; +} +ROLLOVER_SPEC li { + display: inline; + padding: 0; + margin: 0; + HOR_OR_VER; +} diff --git a/emacs/nxhtml/etc/uts39/idnchars.txt b/emacs/nxhtml/etc/uts39/idnchars.txt new file mode 100644 index 0000000..369f8f8 --- /dev/null +++ b/emacs/nxhtml/etc/uts39/idnchars.txt @@ -0,0 +1,894 @@ +# Recommended Identifier Profiles for IDN +# File: idnchars.txt +# Version: 2.0 +# Generated: 2006-08-15, 04:35:10 GMT +# Checkin: $Revision: 1.11 $ +# +# For documentation and usage, see http://www.unicode.org/reports/tr39/ +# +# Allowed as output characters + +002D ; output # (-) HYPHEN-MINUS +0030..0039 ; output # [10] (0..9) DIGIT ZERO..DIGIT NINE +0041..005A ; output # [26] (A..Z) LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z +0061..007A ; output # [26] (a..z) LATIN SMALL LETTER A..LATIN SMALL LETTER Z +00B7 ; output # (·) MIDDLE DOT +00E0..00F6 ; output # [23] (à..ö) LATIN SMALL LETTER A WITH GRAVE..LATIN SMALL LETTER O WITH DIAERESIS +00F8..00FF ; output # [8] (ø..ÿ) LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER Y WITH DIAERESIS +0101 ; output # (ā) LATIN SMALL LETTER A WITH MACRON +0103 ; output # (ă) LATIN SMALL LETTER A WITH BREVE +0105 ; output # (ą) LATIN SMALL LETTER A WITH OGONEK +0107 ; output # (ć) LATIN SMALL LETTER C WITH ACUTE +0109 ; output # (ĉ) LATIN SMALL LETTER C WITH CIRCUMFLEX +010B ; output # (ċ) LATIN SMALL LETTER C WITH DOT ABOVE +010D ; output # (č) LATIN SMALL LETTER C WITH CARON +010F ; output # (ď) LATIN SMALL LETTER D WITH CARON +0111 ; output # (đ) LATIN SMALL LETTER D WITH STROKE +0113 ; output # (ē) LATIN SMALL LETTER E WITH MACRON +0115 ; output # (ĕ) LATIN SMALL LETTER E WITH BREVE +0117 ; output # (ė) LATIN SMALL LETTER E WITH DOT ABOVE +0119 ; output # (ę) LATIN SMALL LETTER E WITH OGONEK +011B ; output # (ě) LATIN SMALL LETTER E WITH CARON +011D ; output # (ĝ) LATIN SMALL LETTER G WITH CIRCUMFLEX +011F ; output # (ğ) LATIN SMALL LETTER G WITH BREVE +0121 ; output # (ġ) LATIN SMALL LETTER G WITH DOT ABOVE +0123 ; output # (ģ) LATIN SMALL LETTER G WITH CEDILLA +0125 ; output # (ĥ) LATIN SMALL LETTER H WITH CIRCUMFLEX +0127 ; output # (ħ) LATIN SMALL LETTER H WITH STROKE +0129 ; output # (ĩ) LATIN SMALL LETTER I WITH TILDE +012B ; output # (ī) LATIN SMALL LETTER I WITH MACRON +012D ; output # (ĭ) LATIN SMALL LETTER I WITH BREVE +012F ; output # (į) LATIN SMALL LETTER I WITH OGONEK +0131 ; output # (ı) LATIN SMALL LETTER DOTLESS I +0135 ; output # (ĵ) LATIN SMALL LETTER J WITH CIRCUMFLEX +0137..0138 ; output # [2] (ķ..ĸ) LATIN SMALL LETTER K WITH CEDILLA..LATIN SMALL LETTER KRA +013A ; output # (ĺ) LATIN SMALL LETTER L WITH ACUTE +013C ; output # (ļ) LATIN SMALL LETTER L WITH CEDILLA +013E ; output # (ľ) LATIN SMALL LETTER L WITH CARON +0142 ; output # (ł) LATIN SMALL LETTER L WITH STROKE +0144 ; output # (ń) LATIN SMALL LETTER N WITH ACUTE +0146 ; output # (ņ) LATIN SMALL LETTER N WITH CEDILLA +0148 ; output # (ň) LATIN SMALL LETTER N WITH CARON +014B ; output # (ŋ) LATIN SMALL LETTER ENG +014D ; output # (ō) LATIN SMALL LETTER O WITH MACRON +014F ; output # (ŏ) LATIN SMALL LETTER O WITH BREVE +0151 ; output # (ő) LATIN SMALL LETTER O WITH DOUBLE ACUTE +0153 ; output # (œ) LATIN SMALL LIGATURE OE +0155 ; output # (ŕ) LATIN SMALL LETTER R WITH ACUTE +0157 ; output # (ŗ) LATIN SMALL LETTER R WITH CEDILLA +0159 ; output # (ř) LATIN SMALL LETTER R WITH CARON +015B ; output # (ś) LATIN SMALL LETTER S WITH ACUTE +015D ; output # (ŝ) LATIN SMALL LETTER S WITH CIRCUMFLEX +015F ; output # (ş) LATIN SMALL LETTER S WITH CEDILLA +0161 ; output # (š) LATIN SMALL LETTER S WITH CARON +0163 ; output # (ţ) LATIN SMALL LETTER T WITH CEDILLA +0165 ; output # (ť) LATIN SMALL LETTER T WITH CARON +0167 ; output # (ŧ) LATIN SMALL LETTER T WITH STROKE +0169 ; output # (ũ) LATIN SMALL LETTER U WITH TILDE +016B ; output # (ū) LATIN SMALL LETTER U WITH MACRON +016D ; output # (ŭ) LATIN SMALL LETTER U WITH BREVE +016F ; output # (ů) LATIN SMALL LETTER U WITH RING ABOVE +0171 ; output # (ű) LATIN SMALL LETTER U WITH DOUBLE ACUTE +0173 ; output # (ų) LATIN SMALL LETTER U WITH OGONEK +0175 ; output # (ŵ) LATIN SMALL LETTER W WITH CIRCUMFLEX +0177 ; output # (ŷ) LATIN SMALL LETTER Y WITH CIRCUMFLEX +017A ; output # (ź) LATIN SMALL LETTER Z WITH ACUTE +017C ; output # (ż) LATIN SMALL LETTER Z WITH DOT ABOVE +017E ; output # (ž) LATIN SMALL LETTER Z WITH CARON +0183 ; output # (ƃ) LATIN SMALL LETTER B WITH TOPBAR +0185 ; output # (ƅ) LATIN SMALL LETTER TONE SIX +0188 ; output # (ƈ) LATIN SMALL LETTER C WITH HOOK +018C ; output # (ƌ) LATIN SMALL LETTER D WITH TOPBAR +0192 ; output # (ƒ) LATIN SMALL LETTER F WITH HOOK +0195 ; output # (ƕ) LATIN SMALL LETTER HV +0199..019B ; output # [3] (ƙ..ƛ) LATIN SMALL LETTER K WITH HOOK..LATIN SMALL LETTER LAMBDA WITH STROKE +019E ; output # (ƞ) LATIN SMALL LETTER N WITH LONG RIGHT LEG +01A1 ; output # (ơ) LATIN SMALL LETTER O WITH HORN +01A3 ; output # (ƣ) LATIN SMALL LETTER OI +01A5 ; output # (ƥ) LATIN SMALL LETTER P WITH HOOK +01A8 ; output # (ƨ) LATIN SMALL LETTER TONE TWO +01AD ; output # (ƭ) LATIN SMALL LETTER T WITH HOOK +01B0 ; output # (ư) LATIN SMALL LETTER U WITH HORN +01B4 ; output # (ƴ) LATIN SMALL LETTER Y WITH HOOK +01B6 ; output # (ƶ) LATIN SMALL LETTER Z WITH STROKE +01BD ; output # (ƽ) LATIN SMALL LETTER TONE FIVE +01CE ; output # (ǎ) LATIN SMALL LETTER A WITH CARON +01D0 ; output # (ǐ) LATIN SMALL LETTER I WITH CARON +01D2 ; output # (ǒ) LATIN SMALL LETTER O WITH CARON +01D4 ; output # (ǔ) LATIN SMALL LETTER U WITH CARON +01D6 ; output # (ǖ) LATIN SMALL LETTER U WITH DIAERESIS AND MACRON +01D8 ; output # (ǘ) LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE +01DA ; output # (ǚ) LATIN SMALL LETTER U WITH DIAERESIS AND CARON +01DC..01DD ; output # [2] (ǜ..ǝ) LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE..LATIN SMALL LETTER TURNED E +01DF ; output # (ǟ) LATIN SMALL LETTER A WITH DIAERESIS AND MACRON +01E1 ; output # (ǡ) LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON +01E3 ; output # (ǣ) LATIN SMALL LETTER AE WITH MACRON +01E5 ; output # (ǥ) LATIN SMALL LETTER G WITH STROKE +01E7 ; output # (ǧ) LATIN SMALL LETTER G WITH CARON +01E9 ; output # (ǩ) LATIN SMALL LETTER K WITH CARON +01EB ; output # (ǫ) LATIN SMALL LETTER O WITH OGONEK +01ED ; output # (ǭ) LATIN SMALL LETTER O WITH OGONEK AND MACRON +01EF..01F0 ; output # [2] (ǯ..ǰ) LATIN SMALL LETTER EZH WITH CARON..LATIN SMALL LETTER J WITH CARON +01F5 ; output # (ǵ) LATIN SMALL LETTER G WITH ACUTE +01F9 ; output # (ǹ) LATIN SMALL LETTER N WITH GRAVE +01FB ; output # (ǻ) LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE +01FD ; output # (ǽ) LATIN SMALL LETTER AE WITH ACUTE +01FF ; output # (ǿ) LATIN SMALL LETTER O WITH STROKE AND ACUTE +0201 ; output # (ȁ) LATIN SMALL LETTER A WITH DOUBLE GRAVE +0203 ; output # (ȃ) LATIN SMALL LETTER A WITH INVERTED BREVE +0205 ; output # (ȅ) LATIN SMALL LETTER E WITH DOUBLE GRAVE +0207 ; output # (ȇ) LATIN SMALL LETTER E WITH INVERTED BREVE +0209 ; output # (ȉ) LATIN SMALL LETTER I WITH DOUBLE GRAVE +020B ; output # (ȋ) LATIN SMALL LETTER I WITH INVERTED BREVE +020D ; output # (ȍ) LATIN SMALL LETTER O WITH DOUBLE GRAVE +020F ; output # (ȏ) LATIN SMALL LETTER O WITH INVERTED BREVE +0211 ; output # (ȑ) LATIN SMALL LETTER R WITH DOUBLE GRAVE +0213 ; output # (ȓ) LATIN SMALL LETTER R WITH INVERTED BREVE +0215 ; output # (ȕ) LATIN SMALL LETTER U WITH DOUBLE GRAVE +0217 ; output # (ȗ) LATIN SMALL LETTER U WITH INVERTED BREVE +0219 ; output # (ș) LATIN SMALL LETTER S WITH COMMA BELOW +021B ; output # (ț) LATIN SMALL LETTER T WITH COMMA BELOW +021F ; output # (ȟ) LATIN SMALL LETTER H WITH CARON +0223 ; output # (ȣ) LATIN SMALL LETTER OU +0225 ; output # (ȥ) LATIN SMALL LETTER Z WITH HOOK +0227 ; output # (ȧ) LATIN SMALL LETTER A WITH DOT ABOVE +0229 ; output # (ȩ) LATIN SMALL LETTER E WITH CEDILLA +022B ; output # (ȫ) LATIN SMALL LETTER O WITH DIAERESIS AND MACRON +022D ; output # (ȭ) LATIN SMALL LETTER O WITH TILDE AND MACRON +022F ; output # (ȯ) LATIN SMALL LETTER O WITH DOT ABOVE +0231 ; output # (ȱ) LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON +0233 ; output # (ȳ) LATIN SMALL LETTER Y WITH MACRON +0253..0254 ; output # [2] (ɓ..ɔ) LATIN SMALL LETTER B WITH HOOK..LATIN SMALL LETTER OPEN O +0256..0257 ; output # [2] (ɖ..ɗ) LATIN SMALL LETTER D WITH TAIL..LATIN SMALL LETTER D WITH HOOK +0259 ; output # (ə) LATIN SMALL LETTER SCHWA +025B ; output # (ɛ) LATIN SMALL LETTER OPEN E +0260 ; output # (ɠ) LATIN SMALL LETTER G WITH HOOK +0263 ; output # (ɣ) LATIN SMALL LETTER GAMMA +0268..0269 ; output # [2] (ɨ..ɩ) LATIN SMALL LETTER I WITH STROKE..LATIN SMALL LETTER IOTA +026F ; output # (ɯ) LATIN SMALL LETTER TURNED M +0272 ; output # (ɲ) LATIN SMALL LETTER N WITH LEFT HOOK +0275 ; output # (ɵ) LATIN SMALL LETTER BARRED O +0280 ; output # (ʀ) LATIN LETTER SMALL CAPITAL R +0283 ; output # (ʃ) LATIN SMALL LETTER ESH +0288 ; output # (ʈ) LATIN SMALL LETTER T WITH RETROFLEX HOOK +028A..028B ; output # [2] (ʊ..ʋ) LATIN SMALL LETTER UPSILON..LATIN SMALL LETTER V WITH HOOK +0292 ; output # (ʒ) LATIN SMALL LETTER EZH +0294 ; output # (ʔ) LATIN LETTER GLOTTAL STOP +0300..033F ; output # [64] (̀..̿) COMBINING GRAVE ACCENT..COMBINING DOUBLE OVERLINE +0342 ; output # (͂) COMBINING GREEK PERISPOMENI +0346..034E ; output # [9] (͆..͎) COMBINING BRIDGE ABOVE..COMBINING UPWARDS ARROW BELOW +0360..036F ; output # [16] (͠..ͯ) COMBINING DOUBLE TILDE..COMBINING LATIN SMALL LETTER X +0390 ; output # (ΐ) GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +03AC..03C1 ; output # [22] (ά..ρ) GREEK SMALL LETTER ALPHA WITH TONOS..GREEK SMALL LETTER RHO +03C3..03CE ; output # [12] (σ..ώ) GREEK SMALL LETTER SIGMA..GREEK SMALL LETTER OMEGA WITH TONOS +0430..045F ; output # [48] (а..џ) CYRILLIC SMALL LETTER A..CYRILLIC SMALL LETTER DZHE +0461 ; output # (ѡ) CYRILLIC SMALL LETTER OMEGA +0463 ; output # (ѣ) CYRILLIC SMALL LETTER YAT +0465 ; output # (ѥ) CYRILLIC SMALL LETTER IOTIFIED E +0467 ; output # (ѧ) CYRILLIC SMALL LETTER LITTLE YUS +0469 ; output # (ѩ) CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS +046B ; output # (ѫ) CYRILLIC SMALL LETTER BIG YUS +046D ; output # (ѭ) CYRILLIC SMALL LETTER IOTIFIED BIG YUS +046F ; output # (ѯ) CYRILLIC SMALL LETTER KSI +0471 ; output # (ѱ) CYRILLIC SMALL LETTER PSI +0473 ; output # (ѳ) CYRILLIC SMALL LETTER FITA +0475 ; output # (ѵ) CYRILLIC SMALL LETTER IZHITSA +0477 ; output # (ѷ) CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT +0479 ; output # (ѹ) CYRILLIC SMALL LETTER UK +047B ; output # (ѻ) CYRILLIC SMALL LETTER ROUND OMEGA +047D ; output # (ѽ) CYRILLIC SMALL LETTER OMEGA WITH TITLO +047F ; output # (ѿ) CYRILLIC SMALL LETTER OT +0481 ; output # (ҁ) CYRILLIC SMALL LETTER KOPPA +048B ; output # (ҋ) CYRILLIC SMALL LETTER SHORT I WITH TAIL +048D ; output # (ҍ) CYRILLIC SMALL LETTER SEMISOFT SIGN +048F ; output # (ҏ) CYRILLIC SMALL LETTER ER WITH TICK +0491 ; output # (ґ) CYRILLIC SMALL LETTER GHE WITH UPTURN +0493 ; output # (ғ) CYRILLIC SMALL LETTER GHE WITH STROKE +0495 ; output # (ҕ) CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK +0497 ; output # (җ) CYRILLIC SMALL LETTER ZHE WITH DESCENDER +0499 ; output # (ҙ) CYRILLIC SMALL LETTER ZE WITH DESCENDER +049B ; output # (қ) CYRILLIC SMALL LETTER KA WITH DESCENDER +049D ; output # (ҝ) CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE +049F ; output # (ҟ) CYRILLIC SMALL LETTER KA WITH STROKE +04A1 ; output # (ҡ) CYRILLIC SMALL LETTER BASHKIR KA +04A3 ; output # (ң) CYRILLIC SMALL LETTER EN WITH DESCENDER +04A5 ; output # (ҥ) CYRILLIC SMALL LIGATURE EN GHE +04A7 ; output # (ҧ) CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK +04A9 ; output # (ҩ) CYRILLIC SMALL LETTER ABKHASIAN HA +04AB ; output # (ҫ) CYRILLIC SMALL LETTER ES WITH DESCENDER +04AD ; output # (ҭ) CYRILLIC SMALL LETTER TE WITH DESCENDER +04AF ; output # (ү) CYRILLIC SMALL LETTER STRAIGHT U +04B1 ; output # (ұ) CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE +04B3 ; output # (ҳ) CYRILLIC SMALL LETTER HA WITH DESCENDER +04B5 ; output # (ҵ) CYRILLIC SMALL LIGATURE TE TSE +04B7 ; output # (ҷ) CYRILLIC SMALL LETTER CHE WITH DESCENDER +04B9 ; output # (ҹ) CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE +04BB ; output # (һ) CYRILLIC SMALL LETTER SHHA +04BD ; output # (ҽ) CYRILLIC SMALL LETTER ABKHASIAN CHE +04BF..04C0 ; output # [2] (ҿ..Ӏ) CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER..CYRILLIC LETTER PALOCHKA +04C2 ; output # (ӂ) CYRILLIC SMALL LETTER ZHE WITH BREVE +04C4 ; output # (ӄ) CYRILLIC SMALL LETTER KA WITH HOOK +04C6 ; output # (ӆ) CYRILLIC SMALL LETTER EL WITH TAIL +04C8 ; output # (ӈ) CYRILLIC SMALL LETTER EN WITH HOOK +04CA ; output # (ӊ) CYRILLIC SMALL LETTER EN WITH TAIL +04CC ; output # (ӌ) CYRILLIC SMALL LETTER KHAKASSIAN CHE +04CE ; output # (ӎ) CYRILLIC SMALL LETTER EM WITH TAIL +04D1 ; output # (ӑ) CYRILLIC SMALL LETTER A WITH BREVE +04D3 ; output # (ӓ) CYRILLIC SMALL LETTER A WITH DIAERESIS +04D5 ; output # (ӕ) CYRILLIC SMALL LIGATURE A IE +04D7 ; output # (ӗ) CYRILLIC SMALL LETTER IE WITH BREVE +04D9 ; output # (ә) CYRILLIC SMALL LETTER SCHWA +04DB ; output # (ӛ) CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS +04DD ; output # (ӝ) CYRILLIC SMALL LETTER ZHE WITH DIAERESIS +04DF ; output # (ӟ) CYRILLIC SMALL LETTER ZE WITH DIAERESIS +04E1 ; output # (ӡ) CYRILLIC SMALL LETTER ABKHASIAN DZE +04E3 ; output # (ӣ) CYRILLIC SMALL LETTER I WITH MACRON +04E5 ; output # (ӥ) CYRILLIC SMALL LETTER I WITH DIAERESIS +04E7 ; output # (ӧ) CYRILLIC SMALL LETTER O WITH DIAERESIS +04E9 ; output # (ө) CYRILLIC SMALL LETTER BARRED O +04EB ; output # (ӫ) CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS +04ED ; output # (ӭ) CYRILLIC SMALL LETTER E WITH DIAERESIS +04EF ; output # (ӯ) CYRILLIC SMALL LETTER U WITH MACRON +04F1 ; output # (ӱ) CYRILLIC SMALL LETTER U WITH DIAERESIS +04F3 ; output # (ӳ) CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE +04F5 ; output # (ӵ) CYRILLIC SMALL LETTER CHE WITH DIAERESIS +04F9 ; output # (ӹ) CYRILLIC SMALL LETTER YERU WITH DIAERESIS +0501 ; output # (ԁ) CYRILLIC SMALL LETTER KOMI DE +0503 ; output # (ԃ) CYRILLIC SMALL LETTER KOMI DJE +0505 ; output # (ԅ) CYRILLIC SMALL LETTER KOMI ZJE +0507 ; output # (ԇ) CYRILLIC SMALL LETTER KOMI DZJE +0509 ; output # (ԉ) CYRILLIC SMALL LETTER KOMI LJE +050B ; output # (ԋ) CYRILLIC SMALL LETTER KOMI NJE +050D ; output # (ԍ) CYRILLIC SMALL LETTER KOMI SJE +050F ; output # (ԏ) CYRILLIC SMALL LETTER KOMI TJE +0561..0586 ; output # [38] (ա..ֆ) ARMENIAN SMALL LETTER AYB..ARMENIAN SMALL LETTER FEH +0591..05A1 ; output # [17] (֑..֡) HEBREW ACCENT ETNAHTA..HEBREW ACCENT PAZER +05A3..05B9 ; output # [23] (֣..ֹ) HEBREW ACCENT MUNAH..HEBREW POINT HOLAM +05BB..05BD ; output # [3] (ֻ..ֽ) HEBREW POINT QUBUTS..HEBREW POINT METEG +05BF ; output # (ֿ) HEBREW POINT RAFE +05C1..05C2 ; output # [2] (ׁ..ׂ) HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT +05C4 ; output # (ׄ) HEBREW MARK UPPER DOT +05D0..05EA ; output # [27] (א..ת) HEBREW LETTER ALEF..HEBREW LETTER TAV +05F0..05F2 ; output # [3] (װ..ײ) HEBREW LIGATURE YIDDISH DOUBLE VAV..HEBREW LIGATURE YIDDISH DOUBLE YOD +0621..063A ; output # [26] (ء..غ) ARABIC LETTER HAMZA..ARABIC LETTER GHAIN +0641..0655 ; output # [21] (ف..ٕ) ARABIC LETTER FEH..ARABIC HAMZA BELOW +0660..0669 ; output # [10] (٠..٩) ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE +0670..0674 ; output # [5] (ٰ..ٴ) ARABIC LETTER SUPERSCRIPT ALEF..ARABIC LETTER HIGH HAMZA +0679..068D ; output # [21] (ٹ..ڍ) ARABIC LETTER TTEH..ARABIC LETTER DDAHAL +068F..06D3 ; output # [69] (ڏ..ۓ) ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE +06D5..06DC ; output # [8] (ە..ۜ) ARABIC LETTER AE..ARABIC SMALL HIGH SEEN +06DF..06E8 ; output # [10] (۟..ۨ) ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH NOON +06EA..06ED ; output # [4] (۪..ۭ) ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM +06F0..06FC ; output # [13] (۰..ۼ) EXTENDED ARABIC-INDIC DIGIT ZERO..ARABIC LETTER GHAIN WITH DOT BELOW +0710..072C ; output # [29] (ܐ..ܬ) SYRIAC LETTER ALAPH..SYRIAC LETTER TAW +0730..073F ; output # [16] (ܰ..ܿ) SYRIAC PTHAHA ABOVE..SYRIAC RWAHA +0780..07B1 ; output # [50] (ހ..ޱ) THAANA LETTER HAA..THAANA LETTER NAA +0901..0903 ; output # [3] (ँ..ः) DEVANAGARI SIGN CANDRABINDU..DEVANAGARI SIGN VISARGA +0905..0939 ; output # [53] (अ..ह) DEVANAGARI LETTER A..DEVANAGARI LETTER HA +093C..094D ; output # [18] (़..्) DEVANAGARI SIGN NUKTA..DEVANAGARI SIGN VIRAMA +0950..0954 ; output # [5] (ॐ..॔) DEVANAGARI OM..DEVANAGARI ACUTE ACCENT +0960..0963 ; output # [4] (ॠ..ॣ) DEVANAGARI LETTER VOCALIC RR..DEVANAGARI VOWEL SIGN VOCALIC LL +0966..096F ; output # [10] (०..९) DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE +0981..0983 ; output # [3] (ঁ..ঃ) BENGALI SIGN CANDRABINDU..BENGALI SIGN VISARGA +0985..098C ; output # [8] (অ..ঌ) BENGALI LETTER A..BENGALI LETTER VOCALIC L +098F..0990 ; output # [2] (এ..ঐ) BENGALI LETTER E..BENGALI LETTER AI +0993..09A8 ; output # [22] (ও..ন) BENGALI LETTER O..BENGALI LETTER NA +09AA..09B0 ; output # [7] (প..র) BENGALI LETTER PA..BENGALI LETTER RA +09B2 ; output # (ল) BENGALI LETTER LA +09B6..09B9 ; output # [4] (শ..হ) BENGALI LETTER SHA..BENGALI LETTER HA +09BC ; output # (়) BENGALI SIGN NUKTA +09BE..09C4 ; output # [7] (া..ৄ) BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN VOCALIC RR +09C7..09C8 ; output # [2] (ে..ৈ) BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI +09CB..09CD ; output # [3] (ো..্) BENGALI VOWEL SIGN O..BENGALI SIGN VIRAMA +09D7 ; output # (ৗ) BENGALI AU LENGTH MARK +09E0..09E3 ; output # [4] (ৠ..ৣ) BENGALI LETTER VOCALIC RR..BENGALI VOWEL SIGN VOCALIC LL +09E6..09F1 ; output # [12] (০..ৱ) BENGALI DIGIT ZERO..BENGALI LETTER RA WITH LOWER DIAGONAL +0A02 ; output # (ਂ) GURMUKHI SIGN BINDI +0A05..0A0A ; output # [6] (ਅ..ਊ) GURMUKHI LETTER A..GURMUKHI LETTER UU +0A0F..0A10 ; output # [2] (ਏ..ਐ) GURMUKHI LETTER EE..GURMUKHI LETTER AI +0A13..0A28 ; output # [22] (ਓ..ਨ) GURMUKHI LETTER OO..GURMUKHI LETTER NA +0A2A..0A30 ; output # [7] (ਪ..ਰ) GURMUKHI LETTER PA..GURMUKHI LETTER RA +0A32 ; output # (ਲ) GURMUKHI LETTER LA +0A35 ; output # (ਵ) GURMUKHI LETTER VA +0A38..0A39 ; output # [2] (ਸ..ਹ) GURMUKHI LETTER SA..GURMUKHI LETTER HA +0A3C ; output # (਼) GURMUKHI SIGN NUKTA +0A3E..0A42 ; output # [5] (ਾ..ੂ) GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN UU +0A47..0A48 ; output # [2] (ੇ..ੈ) GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI +0A4B..0A4D ; output # [3] (ੋ..੍) GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA +0A5C ; output # (ੜ) GURMUKHI LETTER RRA +0A66..0A74 ; output # [15] (੦..ੴ) GURMUKHI DIGIT ZERO..GURMUKHI EK ONKAR +0A81..0A83 ; output # [3] (ઁ..ઃ) GUJARATI SIGN CANDRABINDU..GUJARATI SIGN VISARGA +0A85..0A8B ; output # [7] (અ..ઋ) GUJARATI LETTER A..GUJARATI LETTER VOCALIC R +0A8D ; output # (ઍ) GUJARATI VOWEL CANDRA E +0A8F..0A91 ; output # [3] (એ..ઑ) GUJARATI LETTER E..GUJARATI VOWEL CANDRA O +0A93..0AA8 ; output # [22] (ઓ..ન) GUJARATI LETTER O..GUJARATI LETTER NA +0AAA..0AB0 ; output # [7] (પ..ર) GUJARATI LETTER PA..GUJARATI LETTER RA +0AB2..0AB3 ; output # [2] (લ..ળ) GUJARATI LETTER LA..GUJARATI LETTER LLA +0AB5..0AB9 ; output # [5] (વ..હ) GUJARATI LETTER VA..GUJARATI LETTER HA +0ABC..0AC5 ; output # [10] (઼..ૅ) GUJARATI SIGN NUKTA..GUJARATI VOWEL SIGN CANDRA E +0AC7..0AC9 ; output # [3] (ે..ૉ) GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN CANDRA O +0ACB..0ACD ; output # [3] (ો..્) GUJARATI VOWEL SIGN O..GUJARATI SIGN VIRAMA +0AD0 ; output # (ૐ) GUJARATI OM +0AE0 ; output # (ૠ) GUJARATI LETTER VOCALIC RR +0AE6..0AEF ; output # [10] (૦..૯) GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE +0B01..0B03 ; output # [3] (ଁ..ଃ) ORIYA SIGN CANDRABINDU..ORIYA SIGN VISARGA +0B05..0B0C ; output # [8] (ଅ..ଌ) ORIYA LETTER A..ORIYA LETTER VOCALIC L +0B0F..0B10 ; output # [2] (ଏ..ଐ) ORIYA LETTER E..ORIYA LETTER AI +0B13..0B28 ; output # [22] (ଓ..ନ) ORIYA LETTER O..ORIYA LETTER NA +0B2A..0B30 ; output # [7] (ପ..ର) ORIYA LETTER PA..ORIYA LETTER RA +0B32..0B33 ; output # [2] (ଲ..ଳ) ORIYA LETTER LA..ORIYA LETTER LLA +0B36..0B39 ; output # [4] (ଶ..ହ) ORIYA LETTER SHA..ORIYA LETTER HA +0B3C..0B43 ; output # [8] (଼..ୃ) ORIYA SIGN NUKTA..ORIYA VOWEL SIGN VOCALIC R +0B47..0B48 ; output # [2] (େ..ୈ) ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI +0B4B..0B4D ; output # [3] (ୋ..୍) ORIYA VOWEL SIGN O..ORIYA SIGN VIRAMA +0B56..0B57 ; output # [2] (ୖ..ୗ) ORIYA AI LENGTH MARK..ORIYA AU LENGTH MARK +0B5F..0B61 ; output # [3] (ୟ..ୡ) ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL +0B66..0B6F ; output # [10] (୦..୯) ORIYA DIGIT ZERO..ORIYA DIGIT NINE +0B82..0B83 ; output # [2] (ஂ..ஃ) TAMIL SIGN ANUSVARA..TAMIL SIGN VISARGA +0B85..0B8A ; output # [6] (அ..ஊ) TAMIL LETTER A..TAMIL LETTER UU +0B8E..0B90 ; output # [3] (எ..ஐ) TAMIL LETTER E..TAMIL LETTER AI +0B92..0B95 ; output # [4] (ஒ..க) TAMIL LETTER O..TAMIL LETTER KA +0B99..0B9A ; output # [2] (ங..ச) TAMIL LETTER NGA..TAMIL LETTER CA +0B9C ; output # (ஜ) TAMIL LETTER JA +0B9E..0B9F ; output # [2] (ஞ..ட) TAMIL LETTER NYA..TAMIL LETTER TTA +0BA3..0BA4 ; output # [2] (ண..த) TAMIL LETTER NNA..TAMIL LETTER TA +0BA8..0BAA ; output # [3] (ந..ப) TAMIL LETTER NA..TAMIL LETTER PA +0BAE..0BB5 ; output # [8] (ம..வ) TAMIL LETTER MA..TAMIL LETTER VA +0BB7..0BB9 ; output # [3] (ஷ..ஹ) TAMIL LETTER SSA..TAMIL LETTER HA +0BBE..0BC2 ; output # [5] (ா..ூ) TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN UU +0BC6..0BC8 ; output # [3] (ெ..ை) TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI +0BCA..0BCD ; output # [4] (ொ..்) TAMIL VOWEL SIGN O..TAMIL SIGN VIRAMA +0BD7 ; output # (ௗ) TAMIL AU LENGTH MARK +0BE7..0BEF ; output # [9] (௧..௯) TAMIL DIGIT ONE..TAMIL DIGIT NINE +0C01..0C03 ; output # [3] (ఁ..ః) TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA +0C05..0C0C ; output # [8] (అ..ఌ) TELUGU LETTER A..TELUGU LETTER VOCALIC L +0C0E..0C10 ; output # [3] (ఎ..ఐ) TELUGU LETTER E..TELUGU LETTER AI +0C12..0C28 ; output # [23] (ఒ..న) TELUGU LETTER O..TELUGU LETTER NA +0C2A..0C33 ; output # [10] (ప..ళ) TELUGU LETTER PA..TELUGU LETTER LLA +0C35..0C39 ; output # [5] (వ..హ) TELUGU LETTER VA..TELUGU LETTER HA +0C3E..0C44 ; output # [7] (ా..ౄ) TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN VOCALIC RR +0C46..0C48 ; output # [3] (ె..ై) TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI +0C4A..0C4D ; output # [4] (ొ..్) TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA +0C55..0C56 ; output # [2] (ౕ..ౖ) TELUGU LENGTH MARK..TELUGU AI LENGTH MARK +0C60..0C61 ; output # [2] (ౠ..ౡ) TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL +0C66..0C6F ; output # [10] (౦..౯) TELUGU DIGIT ZERO..TELUGU DIGIT NINE +0C82..0C83 ; output # [2] (ಂ..ಃ) KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA +0C85..0C8C ; output # [8] (ಅ..ಌ) KANNADA LETTER A..KANNADA LETTER VOCALIC L +0C8E..0C90 ; output # [3] (ಎ..ಐ) KANNADA LETTER E..KANNADA LETTER AI +0C92..0CA8 ; output # [23] (ಒ..ನ) KANNADA LETTER O..KANNADA LETTER NA +0CAA..0CB3 ; output # [10] (ಪ..ಳ) KANNADA LETTER PA..KANNADA LETTER LLA +0CB5..0CB9 ; output # [5] (ವ..ಹ) KANNADA LETTER VA..KANNADA LETTER HA +0CBE..0CC4 ; output # [7] (ಾ..ೄ) KANNADA VOWEL SIGN AA..KANNADA VOWEL SIGN VOCALIC RR +0CC6..0CC8 ; output # [3] (ೆ..ೈ) KANNADA VOWEL SIGN E..KANNADA VOWEL SIGN AI +0CCA..0CCD ; output # [4] (ೊ..್) KANNADA VOWEL SIGN O..KANNADA SIGN VIRAMA +0CD5..0CD6 ; output # [2] (ೕ..ೖ) KANNADA LENGTH MARK..KANNADA AI LENGTH MARK +0CE0..0CE1 ; output # [2] (ೠ..ೡ) KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL +0CE6..0CEF ; output # [10] (೦..೯) KANNADA DIGIT ZERO..KANNADA DIGIT NINE +0D02..0D03 ; output # [2] (ം..ഃ) MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA +0D05..0D0C ; output # [8] (അ..ഌ) MALAYALAM LETTER A..MALAYALAM LETTER VOCALIC L +0D0E..0D10 ; output # [3] (എ..ഐ) MALAYALAM LETTER E..MALAYALAM LETTER AI +0D12..0D28 ; output # [23] (ഒ..ന) MALAYALAM LETTER O..MALAYALAM LETTER NA +0D2A..0D39 ; output # [16] (പ..ഹ) MALAYALAM LETTER PA..MALAYALAM LETTER HA +0D3E..0D43 ; output # [6] (ാ..ൃ) MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN VOCALIC R +0D46..0D48 ; output # [3] (െ..ൈ) MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI +0D4A..0D4D ; output # [4] (ൊ..്) MALAYALAM VOWEL SIGN O..MALAYALAM SIGN VIRAMA +0D57 ; output # (ൗ) MALAYALAM AU LENGTH MARK +0D60..0D61 ; output # [2] (ൠ..ൡ) MALAYALAM LETTER VOCALIC RR..MALAYALAM LETTER VOCALIC LL +0D66..0D6F ; output # [10] (൦..൯) MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE +0D82..0D83 ; output # [2] (ං..ඃ) SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA +0D85..0D96 ; output # [18] (අ..ඖ) SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA +0D9A..0DB1 ; output # [24] (ක..න) SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA +0DB3..0DBB ; output # [9] (ඳ..ර) SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA +0DBD ; output # (ල) SINHALA LETTER DANTAJA LAYANNA +0DC0..0DC6 ; output # [7] (ව..ෆ) SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA +0DCA ; output # (්) SINHALA SIGN AL-LAKUNA +0DCF..0DD4 ; output # [6] (ා..ු) SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA +0DD6 ; output # (ූ) SINHALA VOWEL SIGN DIGA PAA-PILLA +0DD8..0DDF ; output # [8] (ෘ..ෟ) SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA +0DF2..0DF3 ; output # [2] (ෲ..ෳ) SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA +0E01..0E32 ; output # [50] (ก..า) THAI CHARACTER KO KAI..THAI CHARACTER SARA AA +0E34..0E3A ; output # [7] (ิ..ฺ) THAI CHARACTER SARA I..THAI CHARACTER PHINTHU +0E40..0E4E ; output # [15] (เ..๎) THAI CHARACTER SARA E..THAI CHARACTER YAMAKKAN +0E50..0E59 ; output # [10] (๐..๙) THAI DIGIT ZERO..THAI DIGIT NINE +0E81..0E82 ; output # [2] (ກ..ຂ) LAO LETTER KO..LAO LETTER KHO SUNG +0E84 ; output # (ຄ) LAO LETTER KHO TAM +0E87..0E88 ; output # [2] (ງ..ຈ) LAO LETTER NGO..LAO LETTER CO +0E8A ; output # (ຊ) LAO LETTER SO TAM +0E8D ; output # (ຍ) LAO LETTER NYO +0E94..0E97 ; output # [4] (ດ..ທ) LAO LETTER DO..LAO LETTER THO TAM +0E99..0E9F ; output # [7] (ນ..ຟ) LAO LETTER NO..LAO LETTER FO SUNG +0EA1..0EA3 ; output # [3] (ມ..ຣ) LAO LETTER MO..LAO LETTER LO LING +0EA5 ; output # (ລ) LAO LETTER LO LOOT +0EA7 ; output # (ວ) LAO LETTER WO +0EAA..0EAB ; output # [2] (ສ..ຫ) LAO LETTER SO SUNG..LAO LETTER HO SUNG +0EAD..0EB2 ; output # [6] (ອ..າ) LAO LETTER O..LAO VOWEL SIGN AA +0EB4..0EB9 ; output # [6] (ິ..ູ) LAO VOWEL SIGN I..LAO VOWEL SIGN UU +0EBB..0EBD ; output # [3] (ົ..ຽ) LAO VOWEL SIGN MAI KON..LAO SEMIVOWEL SIGN NYO +0EC0..0EC4 ; output # [5] (ເ..ໄ) LAO VOWEL SIGN E..LAO VOWEL SIGN AI +0EC6 ; output # (ໆ) LAO KO LA +0EC8..0ECD ; output # [6] (່..ໍ) LAO TONE MAI EK..LAO NIGGAHITA +0ED0..0ED9 ; output # [10] (໐..໙) LAO DIGIT ZERO..LAO DIGIT NINE +0F00 ; output # (ༀ) TIBETAN SYLLABLE OM +0F18..0F19 ; output # [2] (༘..༙) TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS +0F20..0F29 ; output # [10] (༠..༩) TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE +0F35 ; output # (༵) TIBETAN MARK NGAS BZUNG NYI ZLA +0F37 ; output # (༷) TIBETAN MARK NGAS BZUNG SGOR RTAGS +0F39 ; output # (༹) TIBETAN MARK TSA -PHRU +0F3E..0F42 ; output # [5] (༾..ག) TIBETAN SIGN YAR TSHES..TIBETAN LETTER GA +0F44..0F47 ; output # [4] (ང..ཇ) TIBETAN LETTER NGA..TIBETAN LETTER JA +0F49..0F4C ; output # [4] (ཉ..ཌ) TIBETAN LETTER NYA..TIBETAN LETTER DDA +0F4E..0F51 ; output # [4] (ཎ..ད) TIBETAN LETTER NNA..TIBETAN LETTER DA +0F53..0F56 ; output # [4] (ན..བ) TIBETAN LETTER NA..TIBETAN LETTER BA +0F58..0F5B ; output # [4] (མ..ཛ) TIBETAN LETTER MA..TIBETAN LETTER DZA +0F5D..0F68 ; output # [12] (ཝ..ཨ) TIBETAN LETTER WA..TIBETAN LETTER A +0F6A ; output # (ཪ) TIBETAN LETTER FIXED-FORM RA +0F71..0F72 ; output # [2] (ཱ..ི) TIBETAN VOWEL SIGN AA..TIBETAN VOWEL SIGN I +0F74 ; output # (ུ) TIBETAN VOWEL SIGN U +0F7A..0F80 ; output # [7] (ེ..ྀ) TIBETAN VOWEL SIGN E..TIBETAN VOWEL SIGN REVERSED I +0F82..0F84 ; output # [3] (ྂ..྄) TIBETAN SIGN NYI ZLA NAA DA..TIBETAN MARK HALANTA +0F86..0F8B ; output # [6] (྆..ྋ) TIBETAN SIGN LCI RTAGS..TIBETAN SIGN GRU MED RGYINGS +0F90..0F92 ; output # [3] (ྐ..ྒ) TIBETAN SUBJOINED LETTER KA..TIBETAN SUBJOINED LETTER GA +0F94..0F97 ; output # [4] (ྔ..ྗ) TIBETAN SUBJOINED LETTER NGA..TIBETAN SUBJOINED LETTER JA +0F99..0F9C ; output # [4] (ྙ..ྜ) TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER DDA +0F9E..0FA1 ; output # [4] (ྞ..ྡ) TIBETAN SUBJOINED LETTER NNA..TIBETAN SUBJOINED LETTER DA +0FA3..0FA6 ; output # [4] (ྣ..ྦ) TIBETAN SUBJOINED LETTER NA..TIBETAN SUBJOINED LETTER BA +0FA8..0FAB ; output # [4] (ྨ..ྫ) TIBETAN SUBJOINED LETTER MA..TIBETAN SUBJOINED LETTER DZA +0FAD..0FB8 ; output # [12] (ྭ..ྸ) TIBETAN SUBJOINED LETTER WA..TIBETAN SUBJOINED LETTER A +0FBA..0FBC ; output # [3] (ྺ..ྼ) TIBETAN SUBJOINED LETTER FIXED-FORM WA..TIBETAN SUBJOINED LETTER FIXED-FORM RA +0FC6 ; output # (࿆) TIBETAN SYMBOL PADMA GDAN +1000..1021 ; output # [34] (က..အ) MYANMAR LETTER KA..MYANMAR LETTER A +1023..1027 ; output # [5] (ဣ..ဧ) MYANMAR LETTER I..MYANMAR LETTER E +1029..102A ; output # [2] (ဩ..ဪ) MYANMAR LETTER O..MYANMAR LETTER AU +102C..1032 ; output # [7] (ာ..ဲ) MYANMAR VOWEL SIGN AA..MYANMAR VOWEL SIGN AI +1036..1039 ; output # [4] (ံ..္) MYANMAR SIGN ANUSVARA..MYANMAR SIGN VIRAMA +1040..1049 ; output # [10] (၀..၉) MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE +1050..1059 ; output # [10] (ၐ..ၙ) MYANMAR LETTER SHA..MYANMAR VOWEL SIGN VOCALIC LL +10A0..10C5 ; output # [38] (Ⴀ..Ⴥ) GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE +10D0..10F0 ; output # [33] (ა..ჰ) GEORGIAN LETTER AN..GEORGIAN LETTER HAE +10F7..10F8 ; output # [2] (ჷ..ჸ) GEORGIAN LETTER YN..GEORGIAN LETTER ELIFI +1200..1206 ; output # [7] (ሀ..ሆ) ETHIOPIC SYLLABLE HA..ETHIOPIC SYLLABLE HO +1208..1246 ; output # [63] (ለ..ቆ) ETHIOPIC SYLLABLE LA..ETHIOPIC SYLLABLE QO +1248 ; output # (ቈ) ETHIOPIC SYLLABLE QWA +124A..124D ; output # [4] (ቊ..ቍ) ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE +1250..1256 ; output # [7] (ቐ..ቖ) ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO +1258 ; output # (ቘ) ETHIOPIC SYLLABLE QHWA +125A..125D ; output # [4] (ቚ..ቝ) ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE +1260..1286 ; output # [39] (በ..ኆ) ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XO +1288 ; output # (ኈ) ETHIOPIC SYLLABLE XWA +128A..128D ; output # [4] (ኊ..ኍ) ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE +1290..12AE ; output # [31] (ነ..ኮ) ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KO +12B0 ; output # (ኰ) ETHIOPIC SYLLABLE KWA +12B2..12B5 ; output # [4] (ኲ..ኵ) ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE +12B8..12BE ; output # [7] (ኸ..ኾ) ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO +12C0 ; output # (ዀ) ETHIOPIC SYLLABLE KXWA +12C2..12C5 ; output # [4] (ዂ..ዅ) ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE +12C8..12CE ; output # [7] (ወ..ዎ) ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE WO +12D0..12D6 ; output # [7] (ዐ..ዖ) ETHIOPIC SYLLABLE PHARYNGEAL A..ETHIOPIC SYLLABLE PHARYNGEAL O +12D8..12EE ; output # [23] (ዘ..ዮ) ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE YO +12F0..130E ; output # [31] (ደ..ጎ) ETHIOPIC SYLLABLE DA..ETHIOPIC SYLLABLE GO +1310 ; output # (ጐ) ETHIOPIC SYLLABLE GWA +1312..1315 ; output # [4] (ጒ..ጕ) ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE +1318..131E ; output # [7] (ጘ..ጞ) ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE GGO +1320..1346 ; output # [39] (ጠ..ፆ) ETHIOPIC SYLLABLE THA..ETHIOPIC SYLLABLE TZO +1348..135A ; output # [19] (ፈ..ፚ) ETHIOPIC SYLLABLE FA..ETHIOPIC SYLLABLE FYA +1369..1371 ; output # [9] (፩..፱) ETHIOPIC DIGIT ONE..ETHIOPIC DIGIT NINE +13A0..13F4 ; output # [85] (Ꭰ..Ᏼ) CHEROKEE LETTER A..CHEROKEE LETTER YV +1401..166C ; output # [620] (ᐁ..ᙬ) CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA +166F..1676 ; output # [8] (ᙯ..ᙶ) CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS NNGAA +1780..17A2 ; output # [35] (ក..អ) KHMER LETTER KA..KHMER LETTER QA +17A5..17A7 ; output # [3] (ឥ..ឧ) KHMER INDEPENDENT VOWEL QI..KHMER INDEPENDENT VOWEL QU +17A9..17B3 ; output # [11] (ឩ..ឳ) KHMER INDEPENDENT VOWEL QUU..KHMER INDEPENDENT VOWEL QAU +17B6..17D0 ; output # [27] (ា..័) KHMER VOWEL SIGN AA..KHMER SIGN SAMYOK SANNYA +17D2 ; output # (្) KHMER SIGN COENG +17D7 ; output # (ៗ) KHMER SIGN LEK TOO +17DC ; output # (ៜ) KHMER SIGN AVAKRAHASANYA +17E0..17E9 ; output # [10] (០..៩) KHMER DIGIT ZERO..KHMER DIGIT NINE +1810..1819 ; output # [10] (᠐..᠙) MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE +1820..1877 ; output # [88] (ᠠ..ᡷ) MONGOLIAN LETTER A..MONGOLIAN LETTER MANCHU ZHA +1880..18A9 ; output # [42] (ᢀ..ᢩ) MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER ALI GALI DAGALGA +1E01 ; output # (ḁ) LATIN SMALL LETTER A WITH RING BELOW +1E03 ; output # (ḃ) LATIN SMALL LETTER B WITH DOT ABOVE +1E05 ; output # (ḅ) LATIN SMALL LETTER B WITH DOT BELOW +1E07 ; output # (ḇ) LATIN SMALL LETTER B WITH LINE BELOW +1E09 ; output # (ḉ) LATIN SMALL LETTER C WITH CEDILLA AND ACUTE +1E0B ; output # (ḋ) LATIN SMALL LETTER D WITH DOT ABOVE +1E0D ; output # (ḍ) LATIN SMALL LETTER D WITH DOT BELOW +1E0F ; output # (ḏ) LATIN SMALL LETTER D WITH LINE BELOW +1E11 ; output # (ḑ) LATIN SMALL LETTER D WITH CEDILLA +1E13 ; output # (ḓ) LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW +1E15 ; output # (ḕ) LATIN SMALL LETTER E WITH MACRON AND GRAVE +1E17 ; output # (ḗ) LATIN SMALL LETTER E WITH MACRON AND ACUTE +1E19 ; output # (ḙ) LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW +1E1B ; output # (ḛ) LATIN SMALL LETTER E WITH TILDE BELOW +1E1D ; output # (ḝ) LATIN SMALL LETTER E WITH CEDILLA AND BREVE +1E1F ; output # (ḟ) LATIN SMALL LETTER F WITH DOT ABOVE +1E21 ; output # (ḡ) LATIN SMALL LETTER G WITH MACRON +1E23 ; output # (ḣ) LATIN SMALL LETTER H WITH DOT ABOVE +1E25 ; output # (ḥ) LATIN SMALL LETTER H WITH DOT BELOW +1E27 ; output # (ḧ) LATIN SMALL LETTER H WITH DIAERESIS +1E29 ; output # (ḩ) LATIN SMALL LETTER H WITH CEDILLA +1E2B ; output # (ḫ) LATIN SMALL LETTER H WITH BREVE BELOW +1E2D ; output # (ḭ) LATIN SMALL LETTER I WITH TILDE BELOW +1E2F ; output # (ḯ) LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE +1E31 ; output # (ḱ) LATIN SMALL LETTER K WITH ACUTE +1E33 ; output # (ḳ) LATIN SMALL LETTER K WITH DOT BELOW +1E35 ; output # (ḵ) LATIN SMALL LETTER K WITH LINE BELOW +1E37 ; output # (ḷ) LATIN SMALL LETTER L WITH DOT BELOW +1E39 ; output # (ḹ) LATIN SMALL LETTER L WITH DOT BELOW AND MACRON +1E3B ; output # (ḻ) LATIN SMALL LETTER L WITH LINE BELOW +1E3D ; output # (ḽ) LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW +1E3F ; output # (ḿ) LATIN SMALL LETTER M WITH ACUTE +1E41 ; output # (ṁ) LATIN SMALL LETTER M WITH DOT ABOVE +1E43 ; output # (ṃ) LATIN SMALL LETTER M WITH DOT BELOW +1E45 ; output # (ṅ) LATIN SMALL LETTER N WITH DOT ABOVE +1E47 ; output # (ṇ) LATIN SMALL LETTER N WITH DOT BELOW +1E49 ; output # (ṉ) LATIN SMALL LETTER N WITH LINE BELOW +1E4B ; output # (ṋ) LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW +1E4D ; output # (ṍ) LATIN SMALL LETTER O WITH TILDE AND ACUTE +1E4F ; output # (ṏ) LATIN SMALL LETTER O WITH TILDE AND DIAERESIS +1E51 ; output # (ṑ) LATIN SMALL LETTER O WITH MACRON AND GRAVE +1E53 ; output # (ṓ) LATIN SMALL LETTER O WITH MACRON AND ACUTE +1E55 ; output # (ṕ) LATIN SMALL LETTER P WITH ACUTE +1E57 ; output # (ṗ) LATIN SMALL LETTER P WITH DOT ABOVE +1E59 ; output # (ṙ) LATIN SMALL LETTER R WITH DOT ABOVE +1E5B ; output # (ṛ) LATIN SMALL LETTER R WITH DOT BELOW +1E5D ; output # (ṝ) LATIN SMALL LETTER R WITH DOT BELOW AND MACRON +1E5F ; output # (ṟ) LATIN SMALL LETTER R WITH LINE BELOW +1E61 ; output # (ṡ) LATIN SMALL LETTER S WITH DOT ABOVE +1E63 ; output # (ṣ) LATIN SMALL LETTER S WITH DOT BELOW +1E65 ; output # (ṥ) LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE +1E67 ; output # (ṧ) LATIN SMALL LETTER S WITH CARON AND DOT ABOVE +1E69 ; output # (ṩ) LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE +1E6B ; output # (ṫ) LATIN SMALL LETTER T WITH DOT ABOVE +1E6D ; output # (ṭ) LATIN SMALL LETTER T WITH DOT BELOW +1E6F ; output # (ṯ) LATIN SMALL LETTER T WITH LINE BELOW +1E71 ; output # (ṱ) LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW +1E73 ; output # (ṳ) LATIN SMALL LETTER U WITH DIAERESIS BELOW +1E75 ; output # (ṵ) LATIN SMALL LETTER U WITH TILDE BELOW +1E77 ; output # (ṷ) LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW +1E79 ; output # (ṹ) LATIN SMALL LETTER U WITH TILDE AND ACUTE +1E7B ; output # (ṻ) LATIN SMALL LETTER U WITH MACRON AND DIAERESIS +1E7D ; output # (ṽ) LATIN SMALL LETTER V WITH TILDE +1E7F ; output # (ṿ) LATIN SMALL LETTER V WITH DOT BELOW +1E81 ; output # (ẁ) LATIN SMALL LETTER W WITH GRAVE +1E83 ; output # (ẃ) LATIN SMALL LETTER W WITH ACUTE +1E85 ; output # (ẅ) LATIN SMALL LETTER W WITH DIAERESIS +1E87 ; output # (ẇ) LATIN SMALL LETTER W WITH DOT ABOVE +1E89 ; output # (ẉ) LATIN SMALL LETTER W WITH DOT BELOW +1E8B ; output # (ẋ) LATIN SMALL LETTER X WITH DOT ABOVE +1E8D ; output # (ẍ) LATIN SMALL LETTER X WITH DIAERESIS +1E8F ; output # (ẏ) LATIN SMALL LETTER Y WITH DOT ABOVE +1E91 ; output # (ẑ) LATIN SMALL LETTER Z WITH CIRCUMFLEX +1E93 ; output # (ẓ) LATIN SMALL LETTER Z WITH DOT BELOW +1E95..1E99 ; output # [5] (ẕ..ẙ) LATIN SMALL LETTER Z WITH LINE BELOW..LATIN SMALL LETTER Y WITH RING ABOVE +1EA1 ; output # (ạ) LATIN SMALL LETTER A WITH DOT BELOW +1EA3 ; output # (ả) LATIN SMALL LETTER A WITH HOOK ABOVE +1EA5 ; output # (ấ) LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE +1EA7 ; output # (ầ) LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE +1EA9 ; output # (ẩ) LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE +1EAB ; output # (ẫ) LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE +1EAD ; output # (ậ) LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW +1EAF ; output # (ắ) LATIN SMALL LETTER A WITH BREVE AND ACUTE +1EB1 ; output # (ằ) LATIN SMALL LETTER A WITH BREVE AND GRAVE +1EB3 ; output # (ẳ) LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE +1EB5 ; output # (ẵ) LATIN SMALL LETTER A WITH BREVE AND TILDE +1EB7 ; output # (ặ) LATIN SMALL LETTER A WITH BREVE AND DOT BELOW +1EB9 ; output # (ẹ) LATIN SMALL LETTER E WITH DOT BELOW +1EBB ; output # (ẻ) LATIN SMALL LETTER E WITH HOOK ABOVE +1EBD ; output # (ẽ) LATIN SMALL LETTER E WITH TILDE +1EBF ; output # (ế) LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE +1EC1 ; output # (ề) LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE +1EC3 ; output # (ể) LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE +1EC5 ; output # (ễ) LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE +1EC7 ; output # (ệ) LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW +1EC9 ; output # (ỉ) LATIN SMALL LETTER I WITH HOOK ABOVE +1ECB ; output # (ị) LATIN SMALL LETTER I WITH DOT BELOW +1ECD ; output # (ọ) LATIN SMALL LETTER O WITH DOT BELOW +1ECF ; output # (ỏ) LATIN SMALL LETTER O WITH HOOK ABOVE +1ED1 ; output # (ố) LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE +1ED3 ; output # (ồ) LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE +1ED5 ; output # (ổ) LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE +1ED7 ; output # (ỗ) LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE +1ED9 ; output # (ộ) LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW +1EDB ; output # (ớ) LATIN SMALL LETTER O WITH HORN AND ACUTE +1EDD ; output # (ờ) LATIN SMALL LETTER O WITH HORN AND GRAVE +1EDF ; output # (ở) LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE +1EE1 ; output # (ỡ) LATIN SMALL LETTER O WITH HORN AND TILDE +1EE3 ; output # (ợ) LATIN SMALL LETTER O WITH HORN AND DOT BELOW +1EE5 ; output # (ụ) LATIN SMALL LETTER U WITH DOT BELOW +1EE7 ; output # (ủ) LATIN SMALL LETTER U WITH HOOK ABOVE +1EE9 ; output # (ứ) LATIN SMALL LETTER U WITH HORN AND ACUTE +1EEB ; output # (ừ) LATIN SMALL LETTER U WITH HORN AND GRAVE +1EED ; output # (ử) LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE +1EEF ; output # (ữ) LATIN SMALL LETTER U WITH HORN AND TILDE +1EF1 ; output # (ự) LATIN SMALL LETTER U WITH HORN AND DOT BELOW +1EF3 ; output # (ỳ) LATIN SMALL LETTER Y WITH GRAVE +1EF5 ; output # (ỵ) LATIN SMALL LETTER Y WITH DOT BELOW +1EF7 ; output # (ỷ) LATIN SMALL LETTER Y WITH HOOK ABOVE +1EF9 ; output # (ỹ) LATIN SMALL LETTER Y WITH TILDE +1F00..1F07 ; output # [8] (ἀ..ἇ) GREEK SMALL LETTER ALPHA WITH PSILI..GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI +1F10..1F15 ; output # [6] (ἐ..ἕ) GREEK SMALL LETTER EPSILON WITH PSILI..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA +1F20..1F27 ; output # [8] (ἠ..ἧ) GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI +1F30..1F37 ; output # [8] (ἰ..ἷ) GREEK SMALL LETTER IOTA WITH PSILI..GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI +1F40..1F45 ; output # [6] (ὀ..ὅ) GREEK SMALL LETTER OMICRON WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA +1F50..1F57 ; output # [8] (ὐ..ὗ) GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI +1F60..1F67 ; output # [8] (ὠ..ὧ) GREEK SMALL LETTER OMEGA WITH PSILI..GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI +1F70 ; output # (ὰ) GREEK SMALL LETTER ALPHA WITH VARIA +1F72 ; output # (ὲ) GREEK SMALL LETTER EPSILON WITH VARIA +1F74 ; output # (ὴ) GREEK SMALL LETTER ETA WITH VARIA +1F76 ; output # (ὶ) GREEK SMALL LETTER IOTA WITH VARIA +1F78 ; output # (ὸ) GREEK SMALL LETTER OMICRON WITH VARIA +1F7A ; output # (ὺ) GREEK SMALL LETTER UPSILON WITH VARIA +1F7C ; output # (ὼ) GREEK SMALL LETTER OMEGA WITH VARIA +1FB0..1FB1 ; output # [2] (ᾰ..ᾱ) GREEK SMALL LETTER ALPHA WITH VRACHY..GREEK SMALL LETTER ALPHA WITH MACRON +1FB6 ; output # (ᾶ) GREEK SMALL LETTER ALPHA WITH PERISPOMENI +1FC6 ; output # (ῆ) GREEK SMALL LETTER ETA WITH PERISPOMENI +1FD0..1FD2 ; output # [3] (ῐ..ῒ) GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA +1FD6..1FD7 ; output # [2] (ῖ..ῗ) GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI +1FE0..1FE2 ; output # [3] (ῠ..ῢ) GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA +1FE4..1FE7 ; output # [4] (ῤ..ῧ) GREEK SMALL LETTER RHO WITH PSILI..GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI +1FF6 ; output # (ῶ) GREEK SMALL LETTER OMEGA WITH PERISPOMENI +2132 ; output # (Ⅎ) TURNED CAPITAL F +3005..3007 ; output # [3] (々..〇) IDEOGRAPHIC ITERATION MARK..IDEOGRAPHIC NUMBER ZERO +3041..3096 ; output # [86] (ぁ..ゖ) HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE +3099..309A ; output # [2] (゙..゚) COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK +309D..309E ; output # [2] (ゝ..ゞ) HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK +30A1..30FE ; output # [94] (ァ..ヾ) KATAKANA LETTER SMALL A..KATAKANA VOICED ITERATION MARK +3105..312C ; output # [40] (ㄅ..ㄬ) BOPOMOFO LETTER B..BOPOMOFO LETTER GN +31A0..31B7 ; output # [24] (ㆠ..ㆷ) BOPOMOFO LETTER BU..BOPOMOFO FINAL LETTER H +31F0..31FF ; output # [16] (ㇰ..ㇿ) KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO +3447 ; output # (㑇) CJK UNIFIED IDEOGRAPH-3447 +3473 ; output # (㑳) CJK UNIFIED IDEOGRAPH-3473 +34E4 ; output # (㓤) CJK UNIFIED IDEOGRAPH-34E4 +3577 ; output # (㕷) CJK UNIFIED IDEOGRAPH-3577 +359E ; output # (㖞) CJK UNIFIED IDEOGRAPH-359E +35A1 ; output # (㖡) CJK UNIFIED IDEOGRAPH-35A1 +35AD ; output # (㖭) CJK UNIFIED IDEOGRAPH-35AD +35BF ; output # (㖿) CJK UNIFIED IDEOGRAPH-35BF +35CE ; output # (㗎) CJK UNIFIED IDEOGRAPH-35CE +35F3 ; output # (㗳) CJK UNIFIED IDEOGRAPH-35F3 +35FE ; output # (㗾) CJK UNIFIED IDEOGRAPH-35FE +360E ; output # (㘎) CJK UNIFIED IDEOGRAPH-360E +361A ; output # (㘚) CJK UNIFIED IDEOGRAPH-361A +3918 ; output # (㤘) CJK UNIFIED IDEOGRAPH-3918 +3960 ; output # (㥠) CJK UNIFIED IDEOGRAPH-3960 +396E ; output # (㥮) CJK UNIFIED IDEOGRAPH-396E +39CF..39D0 ; output # [2] (㧏..㧐) CJK UNIFIED IDEOGRAPH-39CF..CJK UNIFIED IDEOGRAPH-39D0 +39DF ; output # (㧟) CJK UNIFIED IDEOGRAPH-39DF +39F8 ; output # (㧸) CJK UNIFIED IDEOGRAPH-39F8 +39FE ; output # (㧾) CJK UNIFIED IDEOGRAPH-39FE +3A18 ; output # (㨘) CJK UNIFIED IDEOGRAPH-3A18 +3A52 ; output # (㩒) CJK UNIFIED IDEOGRAPH-3A52 +3A67 ; output # (㩧) CJK UNIFIED IDEOGRAPH-3A67 +3A73 ; output # (㩳) CJK UNIFIED IDEOGRAPH-3A73 +3B39 ; output # (㬹) CJK UNIFIED IDEOGRAPH-3B39 +3B4E ; output # (㭎) CJK UNIFIED IDEOGRAPH-3B4E +3C6E ; output # (㱮) CJK UNIFIED IDEOGRAPH-3C6E +3CE0 ; output # (㳠) CJK UNIFIED IDEOGRAPH-3CE0 +3DE7 ; output # (㷧) CJK UNIFIED IDEOGRAPH-3DE7 +3DEB ; output # (㷫) CJK UNIFIED IDEOGRAPH-3DEB +3E74 ; output # (㹴) CJK UNIFIED IDEOGRAPH-3E74 +3ED0 ; output # (㻐) CJK UNIFIED IDEOGRAPH-3ED0 +4056 ; output # (䁖) CJK UNIFIED IDEOGRAPH-4056 +4065 ; output # (䁥) CJK UNIFIED IDEOGRAPH-4065 +406A ; output # (䁪) CJK UNIFIED IDEOGRAPH-406A +40BB ; output # (䂻) CJK UNIFIED IDEOGRAPH-40BB +40DF ; output # (䃟) CJK UNIFIED IDEOGRAPH-40DF +4137 ; output # (䄷) CJK UNIFIED IDEOGRAPH-4137 +415F ; output # (䅟) CJK UNIFIED IDEOGRAPH-415F +4337 ; output # (䌷) CJK UNIFIED IDEOGRAPH-4337 +43AC ; output # (䎬) CJK UNIFIED IDEOGRAPH-43AC +43B1 ; output # (䎱) CJK UNIFIED IDEOGRAPH-43B1 +43DD ; output # (䏝) CJK UNIFIED IDEOGRAPH-43DD +44D6 ; output # (䓖) CJK UNIFIED IDEOGRAPH-44D6 +44EA ; output # (䓪) CJK UNIFIED IDEOGRAPH-44EA +4606 ; output # (䘆) CJK UNIFIED IDEOGRAPH-4606 +464C ; output # (䙌) CJK UNIFIED IDEOGRAPH-464C +4661 ; output # (䙡) CJK UNIFIED IDEOGRAPH-4661 +4723 ; output # (䜣) CJK UNIFIED IDEOGRAPH-4723 +4729 ; output # (䜩) CJK UNIFIED IDEOGRAPH-4729 +477C ; output # (䝼) CJK UNIFIED IDEOGRAPH-477C +478D ; output # (䞍) CJK UNIFIED IDEOGRAPH-478D +47F4 ; output # (䟴) CJK UNIFIED IDEOGRAPH-47F4 +48B5 ; output # (䢵) CJK UNIFIED IDEOGRAPH-48B5 +48BC ; output # (䢼) CJK UNIFIED IDEOGRAPH-48BC +48C5 ; output # (䣅) CJK UNIFIED IDEOGRAPH-48C5 +48D3 ; output # (䣓) CJK UNIFIED IDEOGRAPH-48D3 +4947 ; output # (䥇) CJK UNIFIED IDEOGRAPH-4947 +497A ; output # (䥺) CJK UNIFIED IDEOGRAPH-497A +497D ; output # (䥽) CJK UNIFIED IDEOGRAPH-497D +4982..4983 ; output # [2] (䦂..䦃) CJK UNIFIED IDEOGRAPH-4982..CJK UNIFIED IDEOGRAPH-4983 +4985..4986 ; output # [2] (䦅..䦆) CJK UNIFIED IDEOGRAPH-4985..CJK UNIFIED IDEOGRAPH-4986 +499B ; output # (䦛) CJK UNIFIED IDEOGRAPH-499B +499F ; output # (䦟) CJK UNIFIED IDEOGRAPH-499F +49B6..49B7 ; output # [2] (䦶..䦷) CJK UNIFIED IDEOGRAPH-49B6..CJK UNIFIED IDEOGRAPH-49B7 +49D1 ; output # (䧑) CJK UNIFIED IDEOGRAPH-49D1 +4A12 ; output # (䨒) CJK UNIFIED IDEOGRAPH-4A12 +4AB8 ; output # (䪸) CJK UNIFIED IDEOGRAPH-4AB8 +4C77 ; output # (䱷) CJK UNIFIED IDEOGRAPH-4C77 +4C7D ; output # (䱽) CJK UNIFIED IDEOGRAPH-4C7D +4C81 ; output # (䲁) CJK UNIFIED IDEOGRAPH-4C81 +4C85 ; output # (䲅) CJK UNIFIED IDEOGRAPH-4C85 +4C9F..4CA3 ; output # [5] (䲟..䲣) CJK UNIFIED IDEOGRAPH-4C9F..CJK UNIFIED IDEOGRAPH-4CA3 +4CB3 ; output # (䲳) CJK UNIFIED IDEOGRAPH-4CB3 +4D08 ; output # (䴈) CJK UNIFIED IDEOGRAPH-4D08 +4D13..4D19 ; output # [7] (䴓..䴙) CJK UNIFIED IDEOGRAPH-4D13..CJK UNIFIED IDEOGRAPH-4D19 +4DAE ; output # (䶮) CJK UNIFIED IDEOGRAPH-4DAE +4E00..9FA5 ; output # [20902] (一..龥) CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FA5 +A000..A48C ; output # [1165] (ꀀ..ꒌ) YI SYLLABLE IT..YI SYLLABLE YYR +AC00..D7A3 ; output # [11172] (가..힣) HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH +FA0E..FA0F ; output # [2] (﨎..﨏) CJK COMPATIBILITY IDEOGRAPH-FA0E..CJK COMPATIBILITY IDEOGRAPH-FA0F +FA11 ; output # (﨑) CJK COMPATIBILITY IDEOGRAPH-FA11 +FA13..FA14 ; output # [2] (﨓..﨔) CJK COMPATIBILITY IDEOGRAPH-FA13..CJK COMPATIBILITY IDEOGRAPH-FA14 +FA1F ; output # (﨟) CJK COMPATIBILITY IDEOGRAPH-FA1F +FA21 ; output # (﨡) CJK COMPATIBILITY IDEOGRAPH-FA21 +FA23..FA24 ; output # [2] (﨣..﨤) CJK COMPATIBILITY IDEOGRAPH-FA23..CJK COMPATIBILITY IDEOGRAPH-FA24 +FA27..FA29 ; output # [3] (﨧..﨩) CJK COMPATIBILITY IDEOGRAPH-FA27..CJK COMPATIBILITY IDEOGRAPH-FA29 +2070E ; output # (𠜎) CJK UNIFIED IDEOGRAPH-2070E +20731 ; output # (𠜱) CJK UNIFIED IDEOGRAPH-20731 +20779 ; output # (𠝹) CJK UNIFIED IDEOGRAPH-20779 +20C53 ; output # (𠱓) CJK UNIFIED IDEOGRAPH-20C53 +20C78 ; output # (𠱸) CJK UNIFIED IDEOGRAPH-20C78 +20C96 ; output # (𠲖) CJK UNIFIED IDEOGRAPH-20C96 +20CCF ; output # (𠳏) CJK UNIFIED IDEOGRAPH-20CCF +20CD5 ; output # (𠳕) CJK UNIFIED IDEOGRAPH-20CD5 +20D15 ; output # (𠴕) CJK UNIFIED IDEOGRAPH-20D15 +20D7C ; output # (𠵼) CJK UNIFIED IDEOGRAPH-20D7C +20D7F ; output # (𠵿) CJK UNIFIED IDEOGRAPH-20D7F +20E0E..20E0F ; output # [2] (𠸎..𠸏) CJK UNIFIED IDEOGRAPH-20E0E..CJK UNIFIED IDEOGRAPH-20E0F +20E77 ; output # (𠹷) CJK UNIFIED IDEOGRAPH-20E77 +20E9D ; output # (𠺝) CJK UNIFIED IDEOGRAPH-20E9D +20EA2 ; output # (𠺢) CJK UNIFIED IDEOGRAPH-20EA2 +20ED7 ; output # (𠻗) CJK UNIFIED IDEOGRAPH-20ED7 +20EF9..20EFA ; output # [2] (𠻹..𠻺) CJK UNIFIED IDEOGRAPH-20EF9..CJK UNIFIED IDEOGRAPH-20EFA +20F2D..20F2E ; output # [2] (𠼭..𠼮) CJK UNIFIED IDEOGRAPH-20F2D..CJK UNIFIED IDEOGRAPH-20F2E +20F4C ; output # (𠽌) CJK UNIFIED IDEOGRAPH-20F4C +20FB4 ; output # (𠾴) CJK UNIFIED IDEOGRAPH-20FB4 +20FBC ; output # (𠾼) CJK UNIFIED IDEOGRAPH-20FBC +20FEA ; output # (𠿪) CJK UNIFIED IDEOGRAPH-20FEA +2105C ; output # (𡁜) CJK UNIFIED IDEOGRAPH-2105C +2106F ; output # (𡁯) CJK UNIFIED IDEOGRAPH-2106F +21075..21076 ; output # [2] (𡁵..𡁶) CJK UNIFIED IDEOGRAPH-21075..CJK UNIFIED IDEOGRAPH-21076 +2107B ; output # (𡁻) CJK UNIFIED IDEOGRAPH-2107B +210C1 ; output # (𡃁) CJK UNIFIED IDEOGRAPH-210C1 +210C9 ; output # (𡃉) CJK UNIFIED IDEOGRAPH-210C9 +211D9 ; output # (𡇙) CJK UNIFIED IDEOGRAPH-211D9 +220C7 ; output # (𢃇) CJK UNIFIED IDEOGRAPH-220C7 +227B5 ; output # (𢞵) CJK UNIFIED IDEOGRAPH-227B5 +22AD5 ; output # (𢫕) CJK UNIFIED IDEOGRAPH-22AD5 +22B43 ; output # (𢭃) CJK UNIFIED IDEOGRAPH-22B43 +22BCA ; output # (𢯊) CJK UNIFIED IDEOGRAPH-22BCA +22C51 ; output # (𢱑) CJK UNIFIED IDEOGRAPH-22C51 +22C55 ; output # (𢱕) CJK UNIFIED IDEOGRAPH-22C55 +22CC2 ; output # (𢳂) CJK UNIFIED IDEOGRAPH-22CC2 +22D08 ; output # (𢴈) CJK UNIFIED IDEOGRAPH-22D08 +22D4C ; output # (𢵌) CJK UNIFIED IDEOGRAPH-22D4C +22D67 ; output # (𢵧) CJK UNIFIED IDEOGRAPH-22D67 +22EB3 ; output # (𢺳) CJK UNIFIED IDEOGRAPH-22EB3 +23CB7 ; output # (𣲷) CJK UNIFIED IDEOGRAPH-23CB7 +244D3 ; output # (𤓓) CJK UNIFIED IDEOGRAPH-244D3 +24DB8 ; output # (𤶸) CJK UNIFIED IDEOGRAPH-24DB8 +24DEA ; output # (𤷪) CJK UNIFIED IDEOGRAPH-24DEA +2512B ; output # (𥄫) CJK UNIFIED IDEOGRAPH-2512B +26258 ; output # (𦉘) CJK UNIFIED IDEOGRAPH-26258 +267CC ; output # (𦟌) CJK UNIFIED IDEOGRAPH-267CC +269F2 ; output # (𦧲) CJK UNIFIED IDEOGRAPH-269F2 +269FA ; output # (𦧺) CJK UNIFIED IDEOGRAPH-269FA +27A3E ; output # (𧨾) CJK UNIFIED IDEOGRAPH-27A3E +2815D ; output # (𨅝) CJK UNIFIED IDEOGRAPH-2815D +28207 ; output # (𨈇) CJK UNIFIED IDEOGRAPH-28207 +282E2 ; output # (𨋢) CJK UNIFIED IDEOGRAPH-282E2 +28CCA ; output # (𨳊) CJK UNIFIED IDEOGRAPH-28CCA +28CCD ; output # (𨳍) CJK UNIFIED IDEOGRAPH-28CCD +28CD2 ; output # (𨳒) CJK UNIFIED IDEOGRAPH-28CD2 +29D98 ; output # (𩶘) CJK UNIFIED IDEOGRAPH-29D98 + +# Total code points: 37201 + +# Not allowed at start of identifier + +0300..033F ; nonstarting # [64] (̀..̿) COMBINING GRAVE ACCENT..COMBINING DOUBLE OVERLINE +0342 ; nonstarting # (͂) COMBINING GREEK PERISPOMENI +0345..034E ; nonstarting # [10] (ͅ..͎) COMBINING GREEK YPOGEGRAMMENI..COMBINING UPWARDS ARROW BELOW +0360..036F ; nonstarting # [16] (͠..ͯ) COMBINING DOUBLE TILDE..COMBINING LATIN SMALL LETTER X +0591..05A1 ; nonstarting # [17] (֑..֡) HEBREW ACCENT ETNAHTA..HEBREW ACCENT PAZER +05A3..05B9 ; nonstarting # [23] (֣..ֹ) HEBREW ACCENT MUNAH..HEBREW POINT HOLAM +05BB..05BD ; nonstarting # [3] (ֻ..ֽ) HEBREW POINT QUBUTS..HEBREW POINT METEG +05BF ; nonstarting # (ֿ) HEBREW POINT RAFE +05C1..05C2 ; nonstarting # [2] (ׁ..ׂ) HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT +05C4 ; nonstarting # (ׄ) HEBREW MARK UPPER DOT +064B..0655 ; nonstarting # [11] (ً..ٕ) ARABIC FATHATAN..ARABIC HAMZA BELOW +0670 ; nonstarting # (ٰ) ARABIC LETTER SUPERSCRIPT ALEF +06D6..06DC ; nonstarting # [7] (ۖ..ۜ) ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN +06DF..06E4 ; nonstarting # [6] (۟..ۤ) ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA +06E7..06E8 ; nonstarting # [2] (ۧ..ۨ) ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON +06EA..06ED ; nonstarting # [4] (۪..ۭ) ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM +0711 ; nonstarting # (ܑ) SYRIAC LETTER SUPERSCRIPT ALAPH +0730..073F ; nonstarting # [16] (ܰ..ܿ) SYRIAC PTHAHA ABOVE..SYRIAC RWAHA +07A6..07B0 ; nonstarting # [11] (ަ..ް) THAANA ABAFILI..THAANA SUKUN +0901..0903 ; nonstarting # [3] (ँ..ः) DEVANAGARI SIGN CANDRABINDU..DEVANAGARI SIGN VISARGA +093C ; nonstarting # (़) DEVANAGARI SIGN NUKTA +093E..094D ; nonstarting # [16] (ा..्) DEVANAGARI VOWEL SIGN AA..DEVANAGARI SIGN VIRAMA +0951..0954 ; nonstarting # [4] (॑..॔) DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI ACUTE ACCENT +0962..0963 ; nonstarting # [2] (ॢ..ॣ) DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL +0981..0983 ; nonstarting # [3] (ঁ..ঃ) BENGALI SIGN CANDRABINDU..BENGALI SIGN VISARGA +09BC ; nonstarting # (়) BENGALI SIGN NUKTA +09BE..09C4 ; nonstarting # [7] (া..ৄ) BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN VOCALIC RR +09C7..09C8 ; nonstarting # [2] (ে..ৈ) BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI +09CB..09CD ; nonstarting # [3] (ো..্) BENGALI VOWEL SIGN O..BENGALI SIGN VIRAMA +09D7 ; nonstarting # (ৗ) BENGALI AU LENGTH MARK +09E2..09E3 ; nonstarting # [2] (ৢ..ৣ) BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL +0A02 ; nonstarting # (ਂ) GURMUKHI SIGN BINDI +0A3C ; nonstarting # (਼) GURMUKHI SIGN NUKTA +0A3E..0A42 ; nonstarting # [5] (ਾ..ੂ) GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN UU +0A47..0A48 ; nonstarting # [2] (ੇ..ੈ) GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI +0A4B..0A4D ; nonstarting # [3] (ੋ..੍) GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA +0A70..0A71 ; nonstarting # [2] (ੰ..ੱ) GURMUKHI TIPPI..GURMUKHI ADDAK +0A81..0A83 ; nonstarting # [3] (ઁ..ઃ) GUJARATI SIGN CANDRABINDU..GUJARATI SIGN VISARGA +0ABC ; nonstarting # (઼) GUJARATI SIGN NUKTA +0ABE..0AC5 ; nonstarting # [8] (ા..ૅ) GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN CANDRA E +0AC7..0AC9 ; nonstarting # [3] (ે..ૉ) GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN CANDRA O +0ACB..0ACD ; nonstarting # [3] (ો..્) GUJARATI VOWEL SIGN O..GUJARATI SIGN VIRAMA +0B01..0B03 ; nonstarting # [3] (ଁ..ଃ) ORIYA SIGN CANDRABINDU..ORIYA SIGN VISARGA +0B3C ; nonstarting # (଼) ORIYA SIGN NUKTA +0B3E..0B43 ; nonstarting # [6] (ା..ୃ) ORIYA VOWEL SIGN AA..ORIYA VOWEL SIGN VOCALIC R +0B47..0B48 ; nonstarting # [2] (େ..ୈ) ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI +0B4B..0B4D ; nonstarting # [3] (ୋ..୍) ORIYA VOWEL SIGN O..ORIYA SIGN VIRAMA +0B56..0B57 ; nonstarting # [2] (ୖ..ୗ) ORIYA AI LENGTH MARK..ORIYA AU LENGTH MARK +0B82 ; nonstarting # (ஂ) TAMIL SIGN ANUSVARA +0BBE..0BC2 ; nonstarting # [5] (ா..ூ) TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN UU +0BC6..0BC8 ; nonstarting # [3] (ெ..ை) TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI +0BCA..0BCD ; nonstarting # [4] (ொ..்) TAMIL VOWEL SIGN O..TAMIL SIGN VIRAMA +0BD7 ; nonstarting # (ௗ) TAMIL AU LENGTH MARK +0C01..0C03 ; nonstarting # [3] (ఁ..ః) TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA +0C3E..0C44 ; nonstarting # [7] (ా..ౄ) TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN VOCALIC RR +0C46..0C48 ; nonstarting # [3] (ె..ై) TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI +0C4A..0C4D ; nonstarting # [4] (ొ..్) TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA +0C55..0C56 ; nonstarting # [2] (ౕ..ౖ) TELUGU LENGTH MARK..TELUGU AI LENGTH MARK +0C82..0C83 ; nonstarting # [2] (ಂ..ಃ) KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA +0CBE..0CC4 ; nonstarting # [7] (ಾ..ೄ) KANNADA VOWEL SIGN AA..KANNADA VOWEL SIGN VOCALIC RR +0CC6..0CC8 ; nonstarting # [3] (ೆ..ೈ) KANNADA VOWEL SIGN E..KANNADA VOWEL SIGN AI +0CCA..0CCD ; nonstarting # [4] (ೊ..್) KANNADA VOWEL SIGN O..KANNADA SIGN VIRAMA +0CD5..0CD6 ; nonstarting # [2] (ೕ..ೖ) KANNADA LENGTH MARK..KANNADA AI LENGTH MARK +0D02..0D03 ; nonstarting # [2] (ം..ഃ) MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA +0D3E..0D43 ; nonstarting # [6] (ാ..ൃ) MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN VOCALIC R +0D46..0D48 ; nonstarting # [3] (െ..ൈ) MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI +0D4A..0D4D ; nonstarting # [4] (ൊ..്) MALAYALAM VOWEL SIGN O..MALAYALAM SIGN VIRAMA +0D57 ; nonstarting # (ൗ) MALAYALAM AU LENGTH MARK +0D82..0D83 ; nonstarting # [2] (ං..ඃ) SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA +0DCA ; nonstarting # (්) SINHALA SIGN AL-LAKUNA +0DCF..0DD4 ; nonstarting # [6] (ා..ු) SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA +0DD6 ; nonstarting # (ූ) SINHALA VOWEL SIGN DIGA PAA-PILLA +0DD8..0DDF ; nonstarting # [8] (ෘ..ෟ) SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA +0DF2..0DF3 ; nonstarting # [2] (ෲ..ෳ) SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA +0E31 ; nonstarting # (ั) THAI CHARACTER MAI HAN-AKAT +0E34..0E3A ; nonstarting # [7] (ิ..ฺ) THAI CHARACTER SARA I..THAI CHARACTER PHINTHU +0E47..0E4E ; nonstarting # [8] (็..๎) THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN +0EB1 ; nonstarting # (ັ) LAO VOWEL SIGN MAI KAN +0EB4..0EB9 ; nonstarting # [6] (ິ..ູ) LAO VOWEL SIGN I..LAO VOWEL SIGN UU +0EBB..0EBC ; nonstarting # [2] (ົ..ຼ) LAO VOWEL SIGN MAI KON..LAO SEMIVOWEL SIGN LO +0EC8..0ECD ; nonstarting # [6] (່..ໍ) LAO TONE MAI EK..LAO NIGGAHITA +0F18..0F19 ; nonstarting # [2] (༘..༙) TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS +0F35 ; nonstarting # (༵) TIBETAN MARK NGAS BZUNG NYI ZLA +0F37 ; nonstarting # (༷) TIBETAN MARK NGAS BZUNG SGOR RTAGS +0F39 ; nonstarting # (༹) TIBETAN MARK TSA -PHRU +0F3E..0F3F ; nonstarting # [2] (༾..༿) TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES +0F71..0F72 ; nonstarting # [2] (ཱ..ི) TIBETAN VOWEL SIGN AA..TIBETAN VOWEL SIGN I +0F74 ; nonstarting # (ུ) TIBETAN VOWEL SIGN U +0F76 ; nonstarting # (ྲྀ) TIBETAN VOWEL SIGN VOCALIC R +0F78 ; nonstarting # (ླྀ) TIBETAN VOWEL SIGN VOCALIC L +0F7A..0F80 ; nonstarting # [7] (ེ..ྀ) TIBETAN VOWEL SIGN E..TIBETAN VOWEL SIGN REVERSED I +0F82..0F84 ; nonstarting # [3] (ྂ..྄) TIBETAN SIGN NYI ZLA NAA DA..TIBETAN MARK HALANTA +0F86..0F87 ; nonstarting # [2] (྆..྇) TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS +0F90..0F97 ; nonstarting # [8] (ྐ..ྗ) TIBETAN SUBJOINED LETTER KA..TIBETAN SUBJOINED LETTER JA +0F99..0FBC ; nonstarting # [36] (ྙ..ྼ) TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA +0FC6 ; nonstarting # (࿆) TIBETAN SYMBOL PADMA GDAN +102C..1032 ; nonstarting # [7] (ာ..ဲ) MYANMAR VOWEL SIGN AA..MYANMAR VOWEL SIGN AI +1036..1039 ; nonstarting # [4] (ံ..္) MYANMAR SIGN ANUSVARA..MYANMAR SIGN VIRAMA +1056..1059 ; nonstarting # [4] (ၖ..ၙ) MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC LL +17B6..17D0 ; nonstarting # [27] (ា..័) KHMER VOWEL SIGN AA..KHMER SIGN SAMYOK SANNYA +17D2 ; nonstarting # (្) KHMER SIGN COENG +18A9 ; nonstarting # (ᢩ) MONGOLIAN LETTER ALI GALI DAGALGA +3099..309A ; nonstarting # [2] (゙..゚) COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + +# Total code points: 524 diff --git a/emacs/nxhtml/etc/viper-tut/0intro b/emacs/nxhtml/etc/viper-tut/0intro new file mode 100644 index 0000000..3a37e33 --- /dev/null +++ b/emacs/nxhtml/etc/viper-tut/0intro @@ -0,0 +1,59 @@ +Viper tutorial #0: Introduction + +This Viper tutorial is based on the vi tutorial VILEARN. Some things +works differently in Emacs and corresponding parts of the tutorial has +been changed for this. There has also been added some basic +information about Emacs that are useful to get started if you already +are a vi user. + +This tutorial is a hands-on-tutorial for Viper. If you want more +information about Viper, please read the VIPER-MANUAL. + +Note that if you are using Viper you probably still want to know quite +a bit about Emacs to use Emacs efficiently. Therefore you can also +run the Emacs tutorial from here - with special support for +Viper. This is part 6 below. You should run this part also to get to +know which Emacs standard key bindings are shadowed by Viper. + +The tutorial consists of these parts: + + 0 Introduction + (this file) + + 1 Basic Editing + Covers the handful of commands required to both navigate all + five tutorials and do basic editing. + + 2 Moving Efficiently + Covers all of the cursor positioning commands. These are the + commands used later as arguments to editing commands. + + 3 Cutting and Pasting + Introduces the first compound commands, numbering, and copy + buffers. + + 4 Inserting Techniques + Continues the discussion of compound commands, while completing + the list of insertion commands first discussed in tutorial one. + + 5 Tricks and Timesavers + This is less a tutorial than a description of common vi commands + which don't fit correctly into normal logic. + + 6 Emacs Tutorial for Viper Users + Even Viper users use a lot of keys from Emacs. Therefore you can + run the Emacs tutorial here too. It will show you which keys in + the tutorial that are changed because you are using Viper. This + depends of which Viper state you are in, vi state or some insert + state. If you switch Viper state the tutorial will immediately + show which keys are affected. + + +BUGS +Vilearn has the remark that it "Still doesn't cover variables, ex +commands, or tags. At least one more tutorial is necessary for a +complete introduction to vi." - I do not think you have to learn those +parts to use Viper. There are other ways to do these things in Emacs! + +For more information about vilearn see the the README-FILE. + diff --git a/emacs/nxhtml/etc/viper-tut/1basics b/emacs/nxhtml/etc/viper-tut/1basics new file mode 100644 index 0000000..aea1fc5 --- /dev/null +++ b/emacs/nxhtml/etc/viper-tut/1basics @@ -0,0 +1,187 @@ +Viper tutorial #1: The Basics + +This lesson lasts 10-15 minutes and teaches simple editing. Lines +which begin with >>> mark exercises you should try. When you +want to exit this tutorial type 'Z''Z' (type capital Z, twice). + +When you type commands in vi they do not appear on the screen. If the +letters you type unexpectedly appear on the screen, press the ESC key. + + +BASIC CURSOR MOVEMENT +--------------------- +To move through the tutorial use C-d (control d) and C-u (control u). + + C-d Move DOWN one half-screen + (depress the control key and type d) + + C-u Move UP one half-screen + (depress the control key and type u) + +* EMACS-NOTICE: C-u is normally used in Emacs for UNIVERSAL-ARGUMENT. + You can in most cases use DIGIT-ARGUMENT instead. + +>>> Now type C-d (control d) and C-u (control u) to move down and back up. + +When you are done reading a screen, you are expected to type C-d to move +down to the next screen. You must remember to type C-d throughout the +tutorial. + +To move the cursor line by line, or character by character, use the +four keys 'h', 'j', 'k', and 'l'. + + 'h' Move left one character + 'j' Move down one line + 'k' Move up one line + 'l' Move right one character + +You will notice that these keys are in a straight line on the +keyboard. Study the diagram below showing the function of h, j, k, l. + + UP + ....... ....... ....... ....... + : : : : : : : : + LEFT : h : : j : : k : : l : RIGHT + :.....: :.....: :.....: :.....: + + DOWN + +>>> Now type 'j' or 'k' a few times to bring the cursor to this line. + +>>> Try moving off the right end of a line using 'l' . Notice that +>>> vi will not allow you to move off the end of the line using 'l' . +>>> Likewise, you cannot use 'h' and 'l' on a blank line. + +>>> Try moving past the bottom of the screen using 'j' . Notice how +>>> how the screen scrolls downward. + +>>> Now practice using 'k' to move up, and 'h' to move left. + + +DELETION +-------- +To delete characters and lines, use 'x' and 'd''d'. + + 'x' X-OUT one character + 'd''d' DELETE one line + +To undo your changes, use 'u'. + + 'u' UNDO last change only + +>>> Delete this SCRAP line. Move to this line with 'j' or 'k' , now type 'd''d' . +>>> Try undoing the deletion with 'u' . + +>>> Move to this line and x-out the Y's with 'x' : "whY ask whY?" + +>>> Try undoing the deletion with 'u' . Try typing 'u' several times. +>>> Notice that 'u' only undoes the last change. + +* EMACS-NOTICE: In Viper you can use the repeat command '.' (just a dot) + to undo more changes. This goes in both direction, ie undoing and + redoing. Typing just 'u' changes direction. + +Here are more lines on which to practice deleting and undoing (use: 'd''d' 'x' 'u' ) + + Emacs is a nice creation. Emacs is a nice creation. + Emacs is a nice creation. Emacs is a nice creation. + Emacs is a nice creation. Emacs is a nice creation. + + +QUIT COMMANDS +------------- +(DO NOT QUIT the tutorial at this time.) + +To quit a file without saving any changes you have made (for instance, +with the 'd''d' or 'x' commands) use :q! . To quit and save your +changes, use 'Z''Z' . When you are editing your own files, you normally +use 'Z''Z' to quit. + + :q! QUIT without saving changes + (type a colon, then the letter q, then an + exclamation point, and press RETURN) + + 'Z''Z' Exit and save any changes + (type capital Z, twice) + + + +INSERTION +--------- +You enter insert mode with 'i' or 'o' . Anything you type during insert +mode appears on the screen. When you are done inserting, press ESC +to exit insert mode. Type C-[ (control [ ), if you do not have an ESC key. + + 'o' OPEN a line for inserting text + 'i' INSERT starting at the cursor + + ESC ESCAPE from insert mode + +During insert mode, use your erase character (usually backspace or +delete) to delete mistakes. The characters you delete will remain on +the screen until you press ESC. + +>>> Insert your name and phone number below the next blank line. To do this: +>>> Open a line below using 'o' . +>>> Type your first and last name. Press RETURN. +>>> Then type your phone number and press ESC. +>>> Use 'x' to erase part of your phone number. + +>>> Type the date below your phone number. To do this: +>>> Open another line using 'o' . +>>> Type the date and press ESC. + +>>> Type 'u' to undo the insertion. + +>>> Insert a nickname between your first and last names, using 'i'. To do this: +>>> Move the cursor to the spot between your names using 'h', 'j', 'k', 'l'. +>>> Press 'i' . +>>> Type the nickname, use DELETE or BACKSPACE to erase any typos. +>>> Then press ESC. + +On some computers, a line may be longer than the width of the screen. +This means that a very long line may appear to be two lines on the +screen. This happens when you keep typing without pressing RETURN at +the edge of the screen. To avoid any confusion when you're inserting +text, be sure to press RETURN before reaching the right edge of the +screen. + + +SUMMARY +------- +These are the vi commands you should know after tutorial #1: + + C-d Move DOWN one half-screen + (depress the control key and type d) + + C-u Move UP one half-screen + (depress the control key and type u) + + 'h' Move left one character + 'j' Move down one line + 'k' Move up one line + 'l' Move right one character + + 'd''d' DELETE one line + 'x' X-OUT one character + + 'u' UNDO last change + + :q! QUIT without saving changes + (type a colon, then the letter q, then an + exclamation point, and press RETURN) + + 'Z''Z' Exit and save any changes + (type capital Z, twice) + + 'o' OPEN a line for inserting text + 'i' INSERT starting at the cursor + + ESC ESCAPE from insert mode + + +You are now prepared to do simple editing on your own files. Practice +using vi for a few days. Then take the second vi tutorial to learn +more powerful and useful vi commands. + +Copyright (c) 1992 Jill Kliger and Wesley Craig. All Rights Reserved. diff --git a/emacs/nxhtml/etc/viper-tut/2moving b/emacs/nxhtml/etc/viper-tut/2moving new file mode 100644 index 0000000..8e4148e --- /dev/null +++ b/emacs/nxhtml/etc/viper-tut/2moving @@ -0,0 +1,269 @@ +Viper tutorial #2: Moving Through Files Efficiently + +This lesson lasts 15-20 minutes. The material taught here is used in +tutorial #3: Cutting and Pasting. Lines which begin with >>> mark +exercises you should try. When you want to exit this tutorial type 'Z''Z'. + + +WORDS +----- +There are many ways to move from one word to another. Consider these: + + 'w' Move to the beginning of the next WORD + 'e' Move to the END of the next word + 'b' Move BACK to the beginning to the previous word + +For 'w', 'e', and 'b', a word is delimited by any non-alphanumeric +character. The capitalized versions, 'W', 'E', and 'B', also move from word +to word. The difference is that for 'W', 'E', and 'B', a word is delimited +by any blank space. + +>>> Try out 'w', 'b', 'e', on the lines provided below. +>>> Next practice using 'B', 'W', 'b', 'E' on the lines provided below. + + EX-PER-IMENT on these lines;test moving back &forth. + EX-PER-IMENT on these lines;test moving back &forth. + + +ON THE LINE +----------- +You can move immediately to any point on the current line. + + '$' Move to the end of the line + '^' Move to the first non-white character on the line + + '0' Move to the first column on the line (column zero) + #'|' Move to an exact column on the line (column #) e.g. 5| 12| + +>>> Experiment with '$' and '^' on the line provided below. Notice +>>> that '^' moves to the first non-white character, not the beginning. + + This is a PRACTICE LINE. There is white space at the front. END + +'0' (zero) will always take you to the far left edge of the screen. + +#'|' (number vertical-bar) is for moving to an explicit column on a line. +Just type any number 1-80 and press | . For example: 5| 20| 30| +Note that you can't move beyond the last column on a line. + + +FINDING CHARACTERS +------------------ +Often you want to move to a specific letter or character on a line. + + 'f' char FIND the next occurrence of char on the line + 't' char Move 'TIL the next occurrence of char on the line + + 'F' char FIND the previous occurrence of char on the line + 'T' char Move 'TIL the previous occurrence of char on the line + + ';' Repeat the last f, t, F, or T + ',' Reverse the last f, t, F, or T + +'f' and 'F' land on the character. 't' and 'T' land next to the character. +'f' and 't' move forward, while 'F' and 'T' move backward. + +If the specified character is not on the line, vi will beep. + +>>> Move to the beginning of the line below, and try out these commands: +>>> 'f'e 'f'E ';' ';' ',' ',' 't'@ 'T'P 't'e 't'E ',' ';' ',' ';' + + "PRACTICE line?" "Each and Every?" "Find thE char@cter and move to it.END + + +MATCHING +-------- +vi has a handy way to determine if (), {}, and [] pairs match up. + + '%' Move to matching () or {} or [] + +>>> On the practice lines below, move your cursor over a (,),{,},[, or ]. +>>> Then type '%' . + + [TRY THIS. ((Whether) the pairs match up is the question.) [One] + pair is incomplete]. Can you tell {which one? ]} END + + +WINDOW POSITIONS +---------------- +You can move the cursor to the top, middle, or bottom of the vi window. + + 'H' Move to the HIGHEST position in the window + 'M' Move to the MIDDLE position in the window + 'L' Move to the LOWEST position in the window + +>>> Try out these commands: type H then M and L and then M again. + + +MARKING LOCATIONS +----------------- +You can mark positions in the file and return to them. + + 'm' char MARK this location and name it char + ''' char (quote character) return to line named char + '''''' (quote quote) return from last movement + +char can be any lower case letter, a-z. A mark persists until you: + 1) use the same char to mark another location + or 2) delete the marked line + +>>> Move to this line and type ma to mark it a +>>> Move to this line and type mb to mark it b +>>> Move to this line and type mz to mark it z +>>> Type 'a to return to line a +>>> Type 'b to return to line b +>>> Type 'z to return to line z + +Certain commands can move you large distances. These commands cause +your last position to be remembered in the special mark named ' (quote). +To move to this special mark, just type '' (quote quote). + +>>> Try this: 'b to return to line b, and then '' to return here. + + +GO TO A LINE +------------ + + 'G' GO to the last line in the file + #'G' GO to line #. (e.g., 3G , 5G , 124G ) + +Read these directions carefully: +>>> Type '1''G' to go to the top of the file, and then '''''' (quote quote) +>>> to return here. +>>> Now try 'G' to go to the end of the file, and then '''''' to return here. + + +BLOCKS OF TEXT +-------------- +It is often convenient to move through files jumping from one block of +text to the next. To do this use braces and parentheses: + + '{' (left brace) Move to the beginning of a paragraph + '}' (right brace) Move to the end of a paragraph + + '(' (left paren) Move to the beginning of a sentence + ')' (right paren) Move to the beginning of the next sentence + +>>> Experiment with '}' and '{' on the two paragraphs provided below. +>>> Note that paragraphs are separated by a blank line. + + EXPERIMENT on this first paragraph. The quick brown fox jumped + over the seven lazy dogs. The fox must have been very large to + jump over seven dogs! + + EXPERIMENT on this second paragraph. The quick brown dog + jumped over the seven lazy foxes. The dog didn't have to be nearly + as large, since foxes aren't too big. + +>>> Try out ')' and '(' on the two paragraphs provided above. +>>> Notice that sentences are separated by two blank spaces. + +C programmers find it useful to move by sections, since sections may be +delimited by a left brace in the first column. By placing the opening +brace of a C subroutine in the first column, you can move to the top of +the next subroutine, using '[''[' and ']'']' . + + '[''[' Move to the beginning of a section + ']'']' Move to the end of a section + +Note that if vi does not find a left brace at the far left, it will +move to the top or bottom of the file. + +>>> Now try ']'']' then ']'']' and '[''[' on the subroutines provided below: + +main() +{ + helloworld(); +} + +helloworld() +{ + printf( "Hello world\n" ); +} + + +SEARCHING +--------- +This enables you to jump to the next occurrence of a string in a file. +To initially find the string use: + + '/'string Find string looking forward + '?'string Find string looking backward + +To find additional occurrences of the string type: + + 'n' Repeat last / or ? command + 'N' Reverse last / or ? command + +vi may search past the bottom of the file and then start again at the top. +(Or, vi may search past the top and then start again at the bottom.) + +>>> You are going to search for a string, find the next three +>>> occurrences. Then flip directions and find the string until you +>>> return to this location. To do this: +>>> Type '/''t''h''e' then press RETURN. +>>> Type 'n' three times. +>>> Type 'N' until you return to this location. + +* EMACS-NOTICE: Emacs has very powerful SEARCH-COMMANDS which you may + want to use in parallell to those above. One of the first you want + to try is probably C-s (ISEARCH-FORWARD). + + +SUMMARY +------- + + 'w' Move to the beginning of the next WORD + 'e' Move to the END of the next word + 'b' Move BACK to the beginning to the previous word + + '$' Move to the end of the line + '^' Move to the first non-white character on the line + + '0' Move to the first column on the line (column zero) + #'|' Move to an exact column on the line (column #) e.g. 5| 12| + + 'f' char FIND the next occurrence of char on the line + 't' char Move 'TIL the next occurrence of char on the line + + 'F' char FIND the previous occurrence of char on the line + 'T' char Move 'TIL the previous occurrence of char on the line + + ';' Repeat the last f, t, F, or T + ',' Reverse the last f, t, F, or T + + '%' Show matching () or {} or [] + + 'H' Move to the HIGHEST position in the window + 'M' Move to the MIDDLE position in the window + 'L' Move to the LOWEST position in the window + + 'm' char MARK this location and name it char + ''' char (quote character) return to line named char + '''''' (quote quote) return from last movement + + 'G' GO to the last line in the file + #'G' GO to line #. (e.g., 3G , 5G , 175G ) + + '{' (left brace) Move to the beginning of a paragraph + '}' (right brace) Move to the end of a paragraph + + '(' (left paren) Move to the beginning of a sentence + ')' (right paren) Move to the beginning of the next sentence + + '[''[' Move to the beginning of a section + ']'']' Move to the end of a section + + '/'string Find string looking forward + '?'string Find string looking backward + + 'n' Repeat last / or ? command + 'N' Reverse last / or ? command + +You should now be able to move around files very efficiently. These +commands are especially useful if you are using vi over a slow modem. +Practice the material in this lesson for a few days and then take +either the third vi tutorial to learn how to copy, cut, and paste, or +the forth vi tutorial to learn additional insertion techniques. + +Copyright (c) 1992 Jill Kliger and Wesley Craig. All Rights Reserved. diff --git a/emacs/nxhtml/etc/viper-tut/3cutpaste b/emacs/nxhtml/etc/viper-tut/3cutpaste new file mode 100644 index 0000000..6d531d9 --- /dev/null +++ b/emacs/nxhtml/etc/viper-tut/3cutpaste @@ -0,0 +1,318 @@ +Viper tutorial #3: Copying, Cutting, and Pasting + +This lesson lasts 15-20 minutes. This tutorial assumes full knowledge +of tutorial #1, and familiarity with tutorial #2. Lines which begin +with >>> mark exercises you should try. + +When you want to exit this tutorial type 'Z''Z' to exit and save your +changes. Or type :q! to exit without saving changes. +Remember that typing u will UNDO your last change. + + +CUTTING TEXT +------------ +The delete command can be combined with any of the movement commands +taught throughout tutorial #2. The resulting command is of the form: + + 'd'movement DELETE to where the movement command specifies + +Consider the following examples: + + 'd''w' DELETE to the beginning of the next WORD + 'd''$' DELETE to the end of the line + 'd'')' DELETE to the beginning of the next sentence + 'd''t'e DELETE 'TIL the next e + 'd''d' DELETE a line (dd is a special case of the d command) + +>>> Experiment with 'd''w' 'd''$' 'd'')' 'd''t'e 'd''d' on the paragraph provided below: + + PRACTICE here. Now is the time for all good users to learn the + editor. The quick brown fox jumped over the seven lazy fish. Now + is the time for all good users to learn the editor. The quick + brown computer jumped over the seven lazy users. END PRACTICE + +* EMACS-NOTICE: In Viper you can also use 'r' and 'R' for Emacs region and + Viper line extended region. This is very convenient together with + CUA-MODE where the region is visible (it is usually called the + selected text or something similar in other applications). + + +PASTING TEXT +------------ +When text is deleted it is put into a buffer which contains the most +recently deleted text. To paste the contents of this buffer elsewhere +in the file use the p or P command. + + 'P' (upper p) PUT the contents of the buffer before the cursor + 'p' (lower p) PUT the contents of the buffer after the cursor + +>>> Try this sequence of commands on the practice lines below: +>>> 'd''d' to delete one line +>>> 'j' to move down a line +>>> 'p' (lower p) to PUT the deleted text after the cursor +>>> '}' to move to the end of the paragraph +>>> 'P' (upper p) to PUT the deleted text before the cursor + + PRACTICE line. Cut and Paste this line to the bottom of the + paragraph. Here is some filler, feel free to cut and paste the + text in this practice region. Remember that u undoes the last + action. END OF PRACTICE + +>>> Try this sequence of commands at the beginning of a word: +>>> 'd''w' 'w' 'P' + +The fastest way to swap two letters is to type: 'x''p' + +>>> Use xp to correct the misspelled words below: + + PRACTICE. Thier weird quiet recieved an inconvenient shriek. + Thier belief is that to recieve grief from nieghbors outwieghs + all else. Biege skies lead to wierd science. END. + + +NUMBERING +--------- +Consider cutting and pasting 3 words. Based on previous exercises you +would type 'd''w' , move to the new location, and type 'p' , and repeat +this procedure twice more. There is an easier way to do this: + +>>> Using the practice lines below, try the following sequence of commands: +>>> Move to the beginning of the first sentence. +>>> Type 'd''3''w' to DELETE 3 WORDS. +>>> Type 'w' to move ahead one WORD. +>>> Type 'P' (upper p) to PUT the three words before the cursor. + + PRACTICE Numbering vi commands is easy to do. Now is the time for + all good users to learn the editor. The quick brown fox jumped + over the seven lazy dogs. Numbering vi commands is easy to do. + Now is the time for all good users to learn the editor. END PRACTICE + +>>> Type 'd''2''d' to DELETE 2 lines, using the practice paragraph above. +>>> Move to the top of the paragraph. +>>> Type 'p' (lower p) to PUT the two lines after of the cursor. + +Numbering also works for movement commands. + +>>> Now try '4''w' to move ahead 4 WORDs, on the lines provided above. +>>> Then use '3''b' to move BACK 3 words. + +When you type '4''w' THINK "4 words", when you type d4w think "delete 4 +words". In general, we can write + + #movement repeat movement # times + d#movement DELETE to where the #movement command specifies + + +COPYING TEXT +------------ +The YANK command works just like the DELETE command, except 'y' is used +instead of 'd' . + + 'y'movement YANK to where the movement command specifies + +YANK and DELETE are identical except that YANK only copies the specified +text into the buffer. + +>>> Try this sequence of commands on the practice lines below: +>>> 'y''y' to YANK a line (yy is a special case of the y command) +>>> '3''j' to move down 3 lines +>>> 'p' (lower p) to PUT the yanked text after the cursor + + PRACTICE line. Copy and Paste this line to the bottom of the + paragraph. Here is some filler, feel free to copy and paste the + text in this practice region. Remember that u undoes the last + action. END OF PRACTICE + +Please note that copy, cutting, and pasting large blocks of text may +significantly alter the tutorial file. Remember that you can always get +a new copy of the tutorial file and that u UNDOes your last change. + +Here are some examples which show the similarity between y and d . + + 'y''w' YANK to the beginning of the next WORD + 'y''$' YANK to the end of the line + 'y'')' YANK to the beginning of the next sentence + 'y''t'e YANK 'TIL the next e + 'y''y' YANK a line + +Here are some more examples using commands from tutorial #2. + + 'y''L' YANK from here to the lowest point of the window + 'y''/'and YANK from here to the word "and" + 'y''2''}' YANK 2 paragraphs + 'y''''a YANK from here to the marked line "a" (mark line first) + +>>> Experiment with 'y''w' 'y''t'e 'y''4''w' 'y''2''}' 'y''3''y' and 'y''$' on the paragraph +>>> provided below. Copy text AND use 'p' or 'P' to paste it. + + PRACTICE line. Copy and Paste this line to the bottom of the + paragraph. Here is some filler, feel free to copy and paste + the text in this practice region. Remember that u undoes the + last action. END OF PRACTICE + + +NUMBERED BUFFERS +---------------- +In all of the previous pasting exercises you've used the "un-named" +buffer. The un-named buffer contains the text you most recently cut or +copied. When you make a new cut or copy, the old contents of the +un-named buffer are moved to one of the "numbered" buffers. The +buffers are numbered 1-9. Each time you cut or copy text, + + vi saves your current cut or copy in a buffer #1 + vi saves your 2nd to last cut or copy in a buffer #2 + The cut or copy before that is saved in a buffer #3 ... + vi saves your 8th oldest cut or copy in a buffer #8 + vi saves your 9th oldest cut or copy in a buffer #9 + +Note that buffer #1 is the same as the un-named buffer. Here's how to +paste from the numbered buffers: + + "#P (upper p) PUT contents of buffer # before the cursor + "#p (lower p) PUT contents of buffer # after the cursor + +For example: + + "1p PUT buffer 1 after the cursor + "7p PUT buffer 7 after the cursor + +>>> Delete this 1st line with dd +>>> Delete this 2nd line with dd +>>> Delete this 3rd block with d2d +>>> (2nd half of block 3) +>>> Delete this 4th block with dd +>>> Now type "1p "2p "3p "4p + +If you are using vi and have made accidental deletions, just PUT the +contents of each numbered buffer to recover the deleted text. + + +NAMED BUFFERS +------------- +vi maintains the un-named and numbered buffers automatically. You can +maintain your own buffers named a-z. That is, you can cut or copy text +into buffer x and later paste the text from buffer x. + + '"'aDELETE DELETE text into buffer a + "aYANK YANK text into buffer a + "aPUT PUT text from buffer a + +Note, don't actually type 'DELETE', 'YANK', or 'PUT'; type one of the +DELETE commands, YANK commands, or PUT commands. See the examples below: + + "ad} DELETE paragraph into buffer a + "by3y YANK 3 lines into buffer b + "cy200G YANK to line 200 into buffer c + "dp PUT buffer d after the cursor + "zP PUT buffer z before the cursor + +The contents of a named buffer are lost if: + 1) you store new text in a buffer with the same name + or 2) you quit vi (using 'Z''Z' or :q! ) + +>>> Delete this START line into buffer a by typing "add +>>> Paste buffer a by typing "ap + +>>> Delete this INTERMEDIATE line into buffer b by typing "bdd +>>> Paste buffer b by typing "bp + +To put new material into buffer a +>>> Delete this FINAL line into buffer a by typing "add +>>> Paste buffer a by typing "ap + + +SAVING WITHOUT QUITTING +----------------------- +With ZZ you save changes and kill the current buffer. (In vi you also +exit with 'Z''Z'.) With :w you can save and not quit vi. It is a safe +practice to save changes to a file regularly. This reduces re-typing +in the event your computer crashes. + + :w WRITE contents of the file (without quitting) + (type a colon, type w , then press the RETURN key) + +>>> Try :w now. Note the message at the bottom of the screen. + + +PASTING BETWEEN FILES +--------------------- + +* EMACS-NOTICE: In Emacs there are no problems editing several + files. You can however do it in the more complicated vi way below if + you really want to ;-) + +This is an extremely useful procedure in vi. Only one new command is +required for pasting between files, the EDIT command + + :e filename Begin EDITing the file called "filename" + +The EDIT command allows you to edit another file without quitting vi. +This is useful since named buffers are lost when you quit vi. + +Let's say you want to copy 6 lines from the file called "3temp" into +this file which is named "3cutpaste": +(Note that "3temp" has already been created for you) + + 1) WRITE "3cutpaste". vi will not allow :w (press RETURN) + you to edit another file without first + saving any changes you've made. + + 2) EDIT "3temp" without quitting vi. :e 3temp (press RETURN) + + 3) YANK 6 lines from "3temp". "ay6y + + 4) Return to "3cutpaste". :e 3cutpaste (press RETURN) + + 5) PUT from buffer a "ap + +Note that the un-named and numbered buffers are lost when the EDIT +command is used. Only named buffers are preserved with EDIT. + +>>> Follow the 5-step procedure outlined above. Don't be concerned +>>> with remembering all 5 steps, the instructions are repeated in +>>> "3temp". Paste the text from "3temp" near this line of this file, +>>> "3cutpaste". + +You can use this 5-step procedure on any two files, with any cutting or +copying action (here, y6y is the example). + + +SUMMARY +------- + + #movement repeat movement # times + * EMACS-NOTICE: You may also use 'r' or 'R' in Viper. + + 'd'movement DELETE to where "movement" command specifies + 'd'#movement DELETE to where the #movement command specifies + (e.g. 'd''w' 'd''3''w' ) + + 'y'movement YANK to where "movement" command specifies + 'y'#movement YANK to where the #movement command specifies + (e.g. 'y''w' 'y''3''w' ) + + 'P' (upper p) PUT the contents of the buffer before the cursor + 'p' (lower p) PUT the contents of the buffer after the cursor + + '"'#P (upper p) PUT contents of buffer # before the cursor + '"'#p (lower p) PUT contents of buffer # after the cursor + (e.g. '"''2''p' '"''7''P' ) + + '"'aDELETE DELETE text into buffer a + '"'aYANK YANK text into buffer a + '"'aPUT PUT text from named buffer a + (Note, don't actually type 'DELETE', 'YANK', or 'PUT'; + type one of the DELETE commands, YANK commands, or PUT + commands, e.g. '"''a''d''}' '"''b''y''3''y' '"''c''y''2''0''0''G' '"''d''p' '"''z''P' ) + + :w WRITE contents of the file (without quitting) + (type a colon, type w , then press the RETURN key) + + :e filename Begin EDITing the file called "filename" + + +You are now prepared to handle all cutting, copying and pasting tasks +which may arise. If you practice what you've learned you'll find editing +in vi to be fast and convenient. + +Copyright (c) 1992 Jill Kliger and Wesley Craig. All Rights Reserved. diff --git a/emacs/nxhtml/etc/viper-tut/4inserting b/emacs/nxhtml/etc/viper-tut/4inserting new file mode 100644 index 0000000..ab2c6a5 --- /dev/null +++ b/emacs/nxhtml/etc/viper-tut/4inserting @@ -0,0 +1,180 @@ +Viper tutorial #4: Insertion Techniques + +This lesson lasts 5-10 minutes. This tutorial assumes full knowledge +of tutorial #1, and familiarity with tutorial #2. Lines which begin +with >>> mark exercises you should try. When you want to exit this +tutorial type 'Z''Z' . + + +SIMPLE INSERTION +---------------- +You spend most of your time in vi inserting text. As you might expect, +there are several commands to begin insertion. + + 'o' OPEN a line below the cursor + 'O' OPEN a line above the cursor + + 'i' INSERT starting before the cursor + 'I' INSERT at the beginning of the line + + 'a' APPEND starting after the cursor + 'A' APPEND at the end of the line + +Remember to type ESC to leave insert mode. If you don't have an ESC key +type C-[ (control [ ). + + ESC ESCAPE from insert mode + +>>> Move the cursor to this line. Type 'O' , enter your name. Press ESC. +>>> Next type 'o' , enter the date. Press ESC. + +Note that 'O' opens the line above and puts you in insert mode, +while 'o' opens the line below and also puts you in insert mode. + +>>> Type 'a' on any line above, enter your name. Press ESC. Do the +>>> same for 'A'. + +>>> Read the following. Your goal is to take the sentence fragment below: + + BROWN FOX OVER THE SEVEN LAZY + +>>> and convert it to + + THE QUICK BROWN FOX JUMPED OVER THE SEVEN LAZY DOGS. + +>>> To do this type: +>>> 'I' to insert THE QUICK (then press ESC) +>>> move the cursor to after the X in FOX +>>> 'a' to insert JUMPED (then press ESC) +>>> 'A' to insert DOGS. (then press ESC) +>>> Now move to the sentence fragment and make the changes outlined above. + + +JOINING LINES +------------- +Often it is convenient to join two short lines into one line. There +are several ways to do this. The easiest is the J command. Other +methods will be explored in tutorial #5. + + 'J' JOIN two lines + +>>> Go to the first line in the block below. Type J. Type J again. + + Example: NOW IS THE TIME + the walrus said + TO THINK OF MANY THINGS + +In the event that joining lines creates a line which exceeds the width +of the screen, you can break the line by typing i and pressing RETURN. + + +SUBSTITUTING TEXT +----------------- +Substituting combines the delete command and the insert command into a +single step. + + #'s' SUBSTITUTE for # characters + #'S' SUBSTITUTE for # whole lines + + +In order to substitute text you have to know how much text you want to +delete. Consider the following examples: + + '3''s' SUBSTITUTE the next 3 characters for what will be typed + '7''s' SUBSTITUTE the next 7 characters for what will be typed + +>>> Change the SAMPLE DEFINITION below. To do this: +>>> move the cursor to the T in TWO +>>> type '3's +>>> type FOUR then press ESC + + SAMPLE DEFINITION: A string quartet is defined to be + a group of TWO musicians. + + +REPLACING TEXT +-------------- +The 'r' and 'R' commands allow you to directly type over existing text. + + 'r' REPLACE character (NO need to press ESC) + 'R' enter over-type mode + +>>> Correct each of the TYPOs on the sample line below. To do this: +>>> move the cursor to the misspelled character +>>> type 'r' +>>> type the correct character + + SAMPLE: maintanence conveniance complience applience dilagent + +>>> Use the over-type command, 'R' , on the sample line above. +>>> Type 'R' then type the name of a local restaurant. Press ESC. + + +CHANGING TEXT +------------- +The change command combines insertion, deletion, and the movement +commands. (Recall that the movement commands were taught in tutorial +#2.) Change is probably more useful than replace or substitute. The +general form of the change command is: + + 'c'movement CHANGE to where the movement command specifies + +Consider the following examples: + + 'c''w' CHANGE to the beginning of the next WORD + 'c''$' CHANGE to the end of the line + 'c'')' CHANGE to the beginning of the next sentence + 'c''t'e CHANGE 'TIL the next e + 'c''3''w' CHANGE the next 3 WORDS + 'c''c' CHANGE a line (cc is a special case of the c command) + 'c''}' CHANGE to the end of the paragraph + +>>> Follow these steps: +>>> 1. move to the desired location in the practice paragraph below +>>> 2. type 'c''w' (change to the beginning of the next WORD) +>>> 3. type your name +>>> 4. press ESC + + PRACTICE here. Now is the time for all good users to learn the + editor. The quick red fox jumped over the seven lazy fish. Now + is the time for all good users to learn the editor. The quick + brown computer jumped over the seven lazy users. END PRACTICE + +>>> Experiment by using a variety of options for step #2. Try +>>> out 'c''$' 'c'')' 'c''t'e 'c''3''w' 'c''c' 'c''}' on the practice paragraph above. + +Note that the change command follows the same pattern as the delete +and yank commands which were explored in tutorial #3. + + +SUMMARY +------- + + 'o' OPEN a line below the cursor + 'O' OPEN a line above the cursor + + 'i' INSERT starting before the cursor + 'I' INSERT at the beginning of the line + + 'a' APPEND starting after the cursor + 'A' APPEND at the end of the line + + ESC ESCAPE from insert mode + + 'J' JOIN two lines + + #'s' SUBSTITUTE for # characters + #'S' SUBSTITUTE for # whole lines + + 'r' REPLACE character (NO need to press ESC) + 'R' enter over-type mode + + 'c'movement CHANGE to where the movement commands specifies + (e.g. 'c''3''w' 'c''$' 'c''c' ) + + +These commands should improve your ability to insert text efficiently. +The next tutorials deal with advanced commands and tricks which can +further speed up your editing. + +Copyright (c) 1992 Jill Kliger and Wesley Craig. All Rights Reserved. diff --git a/emacs/nxhtml/etc/viper-tut/5tricks b/emacs/nxhtml/etc/viper-tut/5tricks new file mode 100644 index 0000000..c1e414e --- /dev/null +++ b/emacs/nxhtml/etc/viper-tut/5tricks @@ -0,0 +1,229 @@ +Viper tutorial #5: Tricks and Timesavers + +This lesson lasts 10-15 minutes. You should have a strong +understanding of tutorials #1-3 before working through these timesaving +techniques. Lines which begin with >>> mark exercises you should +try. When you want to exit this tutorial type 'Z''Z' . + + +CASE CONVERSION +--------------- +When you want to change an upper-case character to a lower-case +character (or lower-case to upper-case) there is a single command which +does both: + + '~' (tilde) Convert case of current character + +>>> Move the cursor to be OVER the first character in the example +>>> line below. Press '~' until you have changed the case of the +>>> entire line. ( '~' will advance to the right automatically). + + bOB WENT TO pARIS, fRANCE, TO SEE THE #1 CYCLING EVENT. end. + +Note that '~' only affects alphabetic characters. + + +UNDOING +------- +* EMACS-NOTICE: Uppercase U does the same thing as lowercase u in + Viper so this part of the tutorial which was about U has been + removed. + + +REPEAT LAST COMMAND +------------------- +Often you want to make the same change at multiple locations in the +file. To help accomplish this, vi remembers your previous action. + + '.' (dot) repeat last change + +>>> Go through the example below changing "FISH" to "TOAD": +>>> Go to the "F" in the first instance of "FISH" +>>> To change the word: type 'c''w' then type TOAD then press ESC +>>> Move the cursor to "F" in the second occurence of "FISH" +>>> Type '.' (dot) +>>> Move the cursor to "F" in the final occurence of "FISH" +>>> Type '.' (dot) +>>> Now move the cursor to each occurence of "CROW"; Type '.' (dot) + + EXAMPLE: The FISH fed the cat. The CROW fed the cat. Example + text is FISH to make interesting. The man fed the CROW. The + worm fed the FISH. Example text is hard to make CROW. END. + +>>> Go through the example above deleting all occurences of "TOAD": +>>> Move to the beginning of the EXAMPLE paragraph above. +>>> Type '/''T''O''A''D' and press RETURN (recall tutorial #2) +>>> Delete the word by typing 'd''w' +>>> Type 'n' to move to the next occurence of "TOAD" +>>> Type '.' (dot) to repeat the dw command +>>> Use 'n''.' to delete the remaining "TOAD"s + +Note that '.' only repeats changes, not cursor movements. + +* EMACS-NOTICE: In Emacs '.' also repeat undo and redo. + +* EMACS-NOTICE: Emacs KEYBOARD-MACROS are very powerful for repeating + whole sequences of keyboard commands. + + +WINDOW ACTIONS +-------------- +You are already familiar with the C-u (depress the control key and +type u) and C-d commands from tutorial #1. + + C-d Move DOWN one half-screen + C-u Move UP one half-screen + +There are several related commands: + + C-f Move FORWARD one full-screen + C-b Move BACKWARD one full-screen + + C-e Move the window down one line without moving cursor + C-y Move the window up one line without moving cursor + +The C-e and C-y commands may seem obscure; however, notice that on +the keyboard, e and y are close to d and u respectively. This +should help you remember that C-e moves DOWN, and C-y moves UP. + +Recall the 'H' 'M' 'L' (HIGH MIDDLE LOW) window commands from Tutorial 2. +Consider a scenario where you want to yank from the current line to a +line near the top of the window. You could use C-e and C-y to +position the text in the window before you use the yH command. + +The 'z' command also moves the window without moving your cursor: + + 'z' Position the current line to top of window + 'z''.' Position the current line to middle of window + 'z''-' Position the current line to bottom of window + +>>> Move to this line. Type 'z' and press RETURN. Notice that +>>> this text and the cursor have moved to the top of the window. +>>> Try 'z''-' and 'z''.' also. + + +FILE AND DISPLAY CONTROL +------------------------ + +* EMACS-NOTICE: In vi C-g shows the status of the current file, but + C-g in Emacs in most situation stops what Emacs is doing. To get + information about the current file you can use C-c C-g instead when + Viper is in vi state. + +* EMACS-NOTICE: In vi C-l refreshes the screen, but C-l in Emacs calls + the command recenter. + + +SUSPENDING VI +------------- +* EMACS-NOTICE: In vi C-z suspends vi. However in Viper C-z is by + default the VIPER-TOGGLE-KEY. To suspend or iconify Emacs use C-x + C-z. + + +BANG COMMAND +------------ +* EMACS-NOTICE: Emacs has builtin commands to sort etc. + +The exclamation point, '!' (aka BANG), command allows you to feed text +to any Unix command. The output of the Unix command replaces the +original text. Here is a useful Unix command to use from within vi: + + !}fmt Format the paragraph, joining and filling lines to + produce output lines of up to 72 characters + +>>> Move to the example paragraph below. Type !}fmt and press +>>> RETURN. Notice the paragraph will be reformatted such that +>>> the lines are of approximately equal length. + + EXAMPLE: + So we grow together, + Like to a double cherry, seeming parted, + But yet an union in partition; + Two lovely berries moulded on one stem; + So, with two seeming bodies, but one heart; + END. + +Another useful command is: + + !}sort Sort lines of a paragraph alphabetically + +>>> Move to the example text below. Type !}sort and press RETURN. + + OBERON king of the fairies. + PUCK or Robin Goodfellow. + HERMIA daughter to Egeus, in love with Lysander. + HELENA in love with Demetrius. + LYSANDER in love with Hermia. + DEMETRIUS in love with Hermia. + +Remember, any Unix command may be used this way. + + +SHIFTING TEXT +------------- +It is possible to shift large blocks of text right and left with the '>' +and '<' commands. + + '>'movement Shift right to where the movement command specifies + '<'movement Shift left to where the movement command specifies + +These commands work like the 'd' command. For example: + + '>''}' Shift right to the end of the paragraph + '<''}' Shift left to the end of the paragraph + '>''>' Shift the current line right + '<''<' Shift the current line left + +>>> Move the cursor to the first line of the paragraph below. +>>> Type '>''>' and '<''<' to shift the line back and forth. Next +>>> try '>''}' to shift the paragraph to the right, then '<''}' to shift +>>> it left, then type '.' until all four lines start at the left edge. + + THIS IS THE FIRST LINE OF EXAMPLE TEXT + IS + EXAMPLE + TEXT END + + +SUMMARY +------- + + '~' (tilde) Convert case of current character + + 'U' * EMACS-NOTICE: Same as lowercase u undo in Viper. + + '.' (dot) repeat last change + + C-d Move DOWN one half-screen + (depress the control key and type d) + + C-u Move UP one half-screen + (depress the control key and type u) + + C-f Move FORWARD one full-screen + C-b Move BACKWARD one full-screen + + C-e Move the window down one line without moving cursor + C-y Move the window up one line without moving cursor + + 'z' Position the current line to top of window + 'z''.' Position the current line to middle of window + 'z''-' Position the current line to bottom of window + + C-c C-g Show status of current file + C-l Recenter + + '!'}fmt Format the paragraph, joining and filling lines to + produce output lines of up to 72 characters + + '!'}sort Sort lines of a paragraph alphabetically + + '>'movement Shift right to where the movement command specifies + '<'movement Shift left to where the movement command specifies + + +These commands should significantly speed up your editing. Have a nice +day. Tutorial 6 contains even more nifty commands. + +Copyright (c) 1992 Jill Kliger and Wesley Craig. All Rights Reserved. diff --git a/emacs/nxhtml/etc/viper-tut/README b/emacs/nxhtml/etc/viper-tut/README new file mode 100644 index 0000000..dd39176 --- /dev/null +++ b/emacs/nxhtml/etc/viper-tut/README @@ -0,0 +1,49 @@ +Viper Tutorial README +===================== + +To install the Viper tutorial you must do two things: + +1) Put viper-tutorial.el in your Emacs load-path. + +2) Put the tutorial files (0intro, 1basics etc) in subdirectory to + where you put viper-tutorial.el with the name viper-tut. + Optionally you may put those file any where and customize the + option viper-tut-directory. + +The tutorial is started by + + M-x viper-tutorial RET + + + + +Viper tutorial is based on vilearn version 1.0 which was downloaded +from http://vilearn.org. + +Below is the original readme from vilearn. Note that the only part +that applies here is the copyright notice. + +--------------------------------------------------- +This is version 1.0 of vilearn, an interactive vi tutorial. + +Copyright (c) 1992 Jill Kliger and Wesley Craig. All Rights Reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appears in all copies and that +the copyright notice, this permission notice, and an explicit record of +any local changes, appear in supporting documentation. This software +is supplied as is without expressed or implied warranties of any kind. + +To install, edit the Makefile and type + + make install + +We have a mailing list, vilearn-admins@terminator.rs.itd.umich.edu. To +be added to the list, send mail to vilearn-admins-request. The list is +intended to discuss the tutorials, coordinate projects relating to +them, and provide help to those who may need it. + +Wesley Craig & Jill Kliger +1317 Packard Street vilearn@terminator.rs.itd.umich.edu +Ann Arbor, MI 48104 diff --git a/emacs/nxhtml/etc/viper-tut/outline b/emacs/nxhtml/etc/viper-tut/outline new file mode 100644 index 0000000..9eaa3e4 --- /dev/null +++ b/emacs/nxhtml/etc/viper-tut/outline @@ -0,0 +1,131 @@ + +* +* tutorial 1 FILENAME: 1basics +* basics +* + +C-d down +C-u up + +h left +j down +k up +l right + +dd delete line +x x-out character + +u undo + +:q! force quit +ZZ good bye + +o open +i insert + +* +* tutorial 2 FILENAME: 2moving +* objects, finds & marks +* + +w W word +b B back +e E end + +{ } paragraph +( ) sentence +[ ] sections + +$ end of line +^ first non-white +| column +0 beginning of line + +f F find +t T to +; repeat fFtT +, reverse fFtT + +G goto + +H high +M middle +L low + +n N next +? / regex + +% match + +' move to marked line +m mark + + +* +* tutorial 3 FILENAME: 3cutpaste & 3temp +* +* cutting, pasting, buffers, and files +* + +d D deletes +y Y yank +p P put +" buffer +:e edit + +* +* tutorial 4 FILENAME: 4inserting +* insertion +* + +a A append +c C change +i I insert +o O open +r R replace +s S substitute + +J join + +* +* tutorial 5 FILENAME: 5tricks +* tricks +* + +~ case + +u U undo + +. do again + +C-b back +C-f forward +C-e down line +C-y up line +z zero + +C-g status +C-l refresh + +C-z suspend + +C-t pop tag proposed +C-] follow tag proposed + +! command + +< > shift + +* +* tutorial 6 PROPOSED +* commands from hell +* + +: colon commands +Q quit +C-r redraw +@ execute buffer as macro +& like :& + +C-t shift (insert) +C-d unshift (insert) diff --git a/emacs/nxhtml/nxhtml-base.el b/emacs/nxhtml/nxhtml-base.el new file mode 100644 index 0000000..d768a5e --- /dev/null +++ b/emacs/nxhtml/nxhtml-base.el @@ -0,0 +1,150 @@ +;;; nxhtml-base.el --- The very, very basic vars... +;; +;; Author: Lennart Borgman (lennart O borgman A gmail O com) +;; Created: 2010-01-13 Wed +;; Version: +;; Last-Updated: +;; URL: +;; Keywords: +;; Compatibility: +;; +;; Features that might be required by this library: +;; +;; None +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; Things that always must be loaded and that are often necessary when +;; byte compiling. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 3, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;;(eval-when-compile (require 'web-vcs nil t)) +(eval-when-compile (require 'flymake-js nil t)) +(eval-when-compile (require 'flymake-css nil t)) +(eval-when-compile (require 'flymake-java-1 nil t)) + +(defconst nxhtml-menu:version "2.08") +(setq message-log-max t) +(setq debug-on-error t) + +(defconst nxhtml-install-dir + (file-name-directory (or load-file-name + (when (boundp 'bytecomp-filename) bytecomp-filename) + buffer-file-name)) + "Installation directory for nXhtml.") + +(define-minor-mode nxhtml-autoload-web + "If on download elisp files from web when they are needed. +If t then during `require' nXhtml elisp files can be downloaded +from the nXhtml repository on the web. This will currently +download the development sources, latest version. + +Other files that are used by a command may also be downloaded. + +Note that files are not updated automatically. You have to use +`nxhtml-update-existing-files' for that." + :global t + ;;:lighter (propertize " nX" 'face 'font-lock-comment-face) + :lighter " nX" + :group 'nxhtml) + +(defun nxhtml-autoload (fun src &optional docstring interactive type) + "Generalized `autoload'. May setup autoload from the web. +If `nxhtml-autoload-web' is t then setup autoloading from the web. +Otherwise setup for normal local autoloading." + (if nxhtml-autoload-web + (progn + ;; Do not require this until we really need it. + (require 'web-autoload) + (web-autoload fun src docstring interactive type)) + (let ((file src)) + (when (listp file) + (setq file (file-name-nondirectory (nth 2 file)))) + (autoload fun file docstring interactive type)))) + +;; Fix-me: web autoload defcustoms. +;; +;; I have no good idea how to fix this. It looks like I have to +;; defadvice `custom-load-symbol'. I thought that should not be +;; necessary since it does (require load) on line 605 but the web +;; autoload does not start. Why? Hm, you never know since it is inside +;; a (condition-case nil ...). +;; +;; Ah, found it. The require is only done if custom loads contains a +;; symbol, not a string. So I changed this to a symbol instead in +;; nxhtml-loaddefs.el. Maybe `load' instead of `require' should be +;; advised? + +;; What a hell is this below? Have things been rewritten in custom or +;; did I mix somethintg? +(defun nxhtml-custom-autoload (symbol load &optional noset) + "Like `custom-autoload', but also run :set for defcustoms etc." + ;; Fix-me: is-boundp is currently always t because of the order in + ;; loaddefs. Hm, so this worked just by chance... + (let* ((is-boundp (prog1 (boundp symbol) + (custom-autoload symbol load noset))) + (standard (get symbol 'standard-value)) + (saved (get symbol 'saved-value)) + ;; Fix-me: property custom-set etc are not available + (custom-set (get symbol 'custom-set)) + (custom-initialize (get symbol 'custom-initialize)) + (set (or custom-set 'custom-set-default))) ;; Fix-me: initialize + (setq custom-set t) ;; Not available here + (when (or custom-initialize + (and saved + (not (equal (car saved) (symbol-value symbol))) + custom-set)) + (funcall set symbol (car saved)) + (custom-load-symbol symbol)))) + +(defun flymake-init-load-flymakemsg () + (require 'flymakemsg)) + +(define-minor-mode nxhtml-flymake-setup + "Let nXhtml add some addtions to flymake. +This adds support for CSS and JavaScript files. + +It also adds showing of errors in minibuffer when point is on +them. + +If you turn this off you must restart Emacs for it to take +effect." + :group 'nxhtml + :group 'flymake + (when nxhtml-flymake-setup + (flymake-js-load) + (flymake-css-load) + (flymake-java-1-load) + (add-hook 'flymake-mode-hook 'flymake-init-load-flymakemsg))) + + +(provide 'nxhtml-base) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; nxhtml-base.el ends here diff --git a/emacs/nxhtml/nxhtml-loaddefs.el b/emacs/nxhtml/nxhtml-loaddefs.el new file mode 100644 index 0000000..bfa98ee --- /dev/null +++ b/emacs/nxhtml/nxhtml-loaddefs.el @@ -0,0 +1,4490 @@ +;; Autoloads for nXthml +;; +;; This file should be updated by `nxhtmlmaint-get-file-autoloads', +;; `nxhtmlmaint-get-dir-autoloads' or `nxhtmlmaint-get-all-autoloads'. +(eval-when-compile (require 'nxhtml-base)) +(eval-when-compile (require 'web-vcs)) + +;;;### (autoloads (cancel-secondary-selection set-secondary-selection +;;;;;; anchored-transpose) "anchored-transpose" "util/anchored-transpose.el" +;;;;;; (19333 54924)) +;;; Generated autoloads from util/anchored-transpose.el +(web-autoload-require 'anchored-transpose 'lp '(nxhtml-download-root-url nil) "util/anchored-transpose" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'anchored-transpose `(lp '(nxhtml-download-root-url nil) "util/anchored-transpose" nxhtml-install-dir) "\ +Transpose portions of the region around an anchor phrase. + +`this phrase but not that word' can be transposed into +`that word but not this phrase' + +I want this phrase but not that word. + |----------------------------|. .This is the entire phrase. + |-------|. . . . . . .This is the anchor phrase. + +First select the entire phrase and type \\[anchored-transpose]. +This set the secondary selection. + +Then select the anchor phrase and type \\[anchored-transpose] +again. Alternatively you can do the selections like this: + +I want this phrase but not that word. + |----------| |---------| Separate phrase selection. + +By default the anchor phrase will automatically include +any surrounding whitespace even if you don't explicitly select +it. Also, it won't include certain trailing punctuation. See +`anchored-transpose-do-fuzzy' for details. A prefix arg prior to +either selection means `no fuzzy logic, use selections +literally'. + +You can select the regions to be swapped separately in any +order. + +After swapping both primary and secondary selection are still +active. They will be canceled after second next command if you +do not swap regions again. (Second because this allow you to +adjust the regions and try again.) + +You can also swap text between different buffers this way. + +Typing \\[anchored-transpose] with nothing selected clears any +prior selection, ie secondary selection. + +\(fn BEG1 END1 FLG1 &optional BEG2 END2 FLG2 WIN2)" t nil) + +(nxhtml-autoload 'set-secondary-selection `(lp '(nxhtml-download-root-url nil) "util/anchored-transpose" nxhtml-install-dir) "\ +Set the secondary selection to the current region. +This must be bound to a mouse drag event. + +\(fn BEG END)" t nil) + +(nxhtml-autoload 'cancel-secondary-selection `(lp '(nxhtml-download-root-url nil) "util/anchored-transpose" nxhtml-install-dir) "\ +Not documented + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (appmenu-mode appmenu-add appmenu) "appmenu" "util/appmenu.el" +;;;;;; (19275 63380)) +;;; Generated autoloads from util/appmenu.el +(web-autoload-require 'appmenu 'lp '(nxhtml-download-root-url nil) "util/appmenu" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'appmenu 'custom-loads))) (if (member '"appmenu" loads) nil (put 'appmenu 'custom-loads (cons '"appmenu" loads)))) + +(nxhtml-autoload 'appmenu-add `(lp '(nxhtml-download-root-url nil) "util/appmenu" nxhtml-install-dir) "\ +Add entry to `appmenu-alist'. +Add an entry to this list with ID, PRIORITY, TEST, TITLE and +DEFINITION as explained there. + +\(fn ID PRIORITY TEST TITLE DEFINITION)" nil nil) + +(defvar appmenu-mode nil "\ +Non-nil if Appmenu mode is enabled. +See the command `appmenu-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `appmenu-mode'.") + +(nxhtml-custom-autoload 'appmenu-mode 'appmenu nil) + +(nxhtml-autoload 'appmenu-mode `(lp '(nxhtml-download-root-url nil) "util/appmenu" nxhtml-install-dir) "\ +Use a context sensitive popup menu. +AppMenu (appmenu.el) is a framework for creating cooperative +context sensitive popup menus with commands from different major +and minor modes. Using this different modes may cooperate about +the use of popup menus. + +There is also the command `appmenu-as-help' that shows the key +bindings at current point in the help buffer. + +The popup menu and the help buffer version are on these keys: + +\\{appmenu-mode-map} + +The variable `appmenu-alist' is where the popup menu entries +comes from. + +If there is a `keymap' property at point then relevant bindings +from this is also shown in the popup menu. + +You can write functions that use whatever information you want in +Emacs to construct these entries. Since this information is only +collected when the popup menu is shown you do not have to care as +much about computation time as for entries in the menu bar. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (as-external-mode as-external-for-wiki as-external-for-mail-mode +;;;;;; as-external-for-xhtml as-external) "as-external" "util/as-external.el" +;;;;;; (19292 49706)) +;;; Generated autoloads from util/as-external.el +(web-autoload-require 'as-external 'lp '(nxhtml-download-root-url nil) "util/as-external" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'as-external 'custom-loads))) (if (member '"as-external" loads) nil (put 'as-external 'custom-loads (cons '"as-external" loads)))) + +(nxhtml-autoload 'as-external-for-xhtml `(lp '(nxhtml-download-root-url nil) "util/as-external" nxhtml-install-dir) "\ +Setup for Firefox addon It's All Text to edit XHTML. +It's All Text is a Firefox add-on for editing textareas with an +external editor. +See URL `https://addons.mozilla.org/en-US/firefox/addon/4125'. + +In this case Emacs is used to edit textarea fields on a web page. +The text will most often be part of a web page later, like on a +blog. Therefore turn on these: + +- `nxhtml-mode' since some XHTML tags may be allowed. +- `nxhtml-validation-header-mode' since it is not a full page. +- `wrap-to-fill-column-mode' to see what you are writing. +- `html-write-mode' to see it even better. + +Also bypass the question for line end conversion when using +emacsw32-eol. + +\(fn)" t nil) + +(nxhtml-autoload 'as-external-for-mail-mode `(lp '(nxhtml-download-root-url nil) "util/as-external" nxhtml-install-dir) "\ +Setup for Firefox addon It's All Text to edit mail. +Set normal mail comment markers in column 1 (ie >). + +Set `fill-column' to 90 and enable `wrap-to-fill-column-mode' so +that it will look similar to how it will look in the sent plain +text mail. + +See also `as-external-mode'. + +\(fn)" t nil) + +(nxhtml-autoload 'as-external-for-wiki `(lp '(nxhtml-download-root-url nil) "util/as-external" nxhtml-install-dir) "\ +Setup for Firefox addon It's All Text to edit MediaWikis. + +\(fn)" t nil) + +(defvar as-external-mode nil "\ +Non-nil if As-External mode is enabled. +See the command `as-external-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `as-external-mode'.") + +(nxhtml-custom-autoload 'as-external-mode 'as-external nil) + +(nxhtml-autoload 'as-external-mode `(lp '(nxhtml-download-root-url nil) "util/as-external" nxhtml-install-dir) "\ +If non-nil check if Emacs is called as external editor. +When Emacs is called as an external editor for example to edit +text areas on a web page viewed with Firefox this library tries +to help to setup the buffer in a useful way. It may for example +set major and minor modes for the buffer. + +This can for example be useful when blogging or writing comments +on blogs. + +See `as-external-alist' for more information. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (buffer-bg-set-color) "buffer-bg" "util/buffer-bg.el" +;;;;;; (19254 64104)) +;;; Generated autoloads from util/buffer-bg.el +(web-autoload-require 'buffer-bg 'lp '(nxhtml-download-root-url nil) "util/buffer-bg" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'buffer-bg-set-color `(lp '(nxhtml-download-root-url nil) "util/buffer-bg" nxhtml-install-dir) "\ +Add an overlay with background color COLOR to buffer BUFFER. +If COLOR is nil remove previously added overlay. + +\(fn COLOR BUFFER)" t nil) + +;;;*** + +;;;### (autoloads (chartg-make-chart chartg-complete) "chartg" "util/chartg.el" +;;;;;; (19278 15746)) +;;; Generated autoloads from util/chartg.el +(web-autoload-require 'chartg 'lp '(nxhtml-download-root-url nil) "util/chartg" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'chartg-complete `(lp '(nxhtml-download-root-url nil) "util/chartg" nxhtml-install-dir) "\ +Not documented + +\(fn)" t nil) + +(nxhtml-autoload 'chartg-make-chart `(lp '(nxhtml-download-root-url nil) "util/chartg" nxhtml-install-dir) "\ +Try to make a new chart. +If region is active then make a new chart from data in the +selected region. + +Else if current buffer is in `chartg-mode' then do it from the +chart specifications in this buffer. Otherwise create a new +buffer and initialize it with `chartg-mode'. + +If the chart specifications are complete enough to make a chart +then do it and show the resulting chart image. If not then tell +user what is missing. + +NOTE: This is beta, no alpha code. It is not ready. + +Below are some examples. To test them mark an example and do + + M-x chartg-make-chart + +* Example, simple x-y chart: + + Output-file: \"~/temp-chart.png\" + Size: 200 200 + Data: 3 8 5 | 10 20 30 + Type: line-chartg-xy + +* Example, pie: + + Output-file: \"~/temp-depression.png\" + Size: 400 200 + Data: + 2,160,000 + 3,110,000 + 1,510,000 + 73,600 + 775,000 + 726,000 + 8,180,000 + 419,000 + Type: pie-3-dimensional + Chartg-title: \"Depression hits on Google\" + Legends: + \"SSRI\" + | \"Psychotherapy\" + | \"CBT\" + | \"IPT\" + | \"Psychoanalysis\" + | \"Mindfulness\" + | \"Meditation\" + | \"Exercise\" + + +* Example, pie: + + Output-file: \"~/temp-panic.png\" + Size: 400 200 + Data: + 979,000 + 969,000 + 500,000 + 71,900 + 193,000 + 154,000 + 2,500,000 + 9,310,000 + Type: pie-3-dimensional + Chartg-title: \"Depression hits on Google\" + Legends: + \"SSRI\" + | \"Psychotherapy\" + | \"CBT\" + | \"IPT\" + | \"Psychoanalysis\" + | \"Mindfulness\" + | \"Meditation\" + | \"Exercise\" + + +* Example using raw: + + Output-file: \"~/temp-chartg-slipsen-kostar.png\" + Size: 400 130 + Data: 300 1000 30000 + Type: bar-chartg-horizontal + Chartg-title: \"Vad killen i slips tjänar jämfört med dig och mig\" + Google-chartg-raw: \"&chds=0,30000&chco=00cd00|ff4500|483d8b&chxt=y,x&chxl=0:|Killen+i+slips|Partiledarna|Du+och+jag&chf=bg,s,ffd700\" + + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (css-color-test css-color-global-mode css-color-mode +;;;;;; css-color) "css-color" "util/css-color.el" (19386 34254)) +;;; Generated autoloads from util/css-color.el +(web-autoload-require 'css-color 'lp '(nxhtml-download-root-url nil) "util/css-color" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'css-color 'custom-loads))) (if (member '"css-color" loads) nil (put 'css-color 'custom-loads (cons '"css-color" loads)))) + +(nxhtml-autoload 'css-color-mode `(lp '(nxhtml-download-root-url nil) "util/css-color" nxhtml-install-dir) "\ +Show hex color literals with the given color as background. +In this mode hexadecimal colour specifications like #6600ff are +displayed with the specified colour as background. + +Certain keys are bound to special colour editing commands when +point is at a hexadecimal colour: + +\\{css-color-map} + +\(fn &optional ARG)" t nil) + +(defvar css-color-global-mode nil "\ +Non-nil if Css-Color-Global mode is enabled. +See the command `css-color-global-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `css-color-global-mode'.") + +(nxhtml-custom-autoload 'css-color-global-mode 'css-color nil) + +(nxhtml-autoload 'css-color-global-mode `(lp '(nxhtml-download-root-url nil) "util/css-color" nxhtml-install-dir) "\ +Toggle Css-Color mode in every possible buffer. +With prefix ARG, turn Css-Color-Global mode on if and only if +ARG is positive. +Css-Color mode is enabled in all buffers where +`css-color-turn-on-in-buffer' would do it. +See `css-color-mode' for more information on Css-Color mode. + +\(fn &optional ARG)" t nil) + +(nxhtml-autoload 'css-color-test `(lp '(nxhtml-download-root-url nil) "util/css-color" nxhtml-install-dir) "\ +Test colors interactively. +The colors are displayed in the echo area. You can specify the +colors as any viable css color. Example: + + red + #f00 + #0C0 + #b0ff00 + hsla(100, 50%, 25%) + rgb(255,100,120) + +\(fn FG-COLOR BG-COLOR)" t nil) + +;;;*** + +;;;### (autoloads (css-palette-global-mode css-palette css-palette-mode) +;;;;;; "css-palette" "util/css-palette.el" (19235 1650)) +;;; Generated autoloads from util/css-palette.el +(web-autoload-require 'css-palette 'lp '(nxhtml-download-root-url nil) "util/css-palette" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'css-palette-mode `(lp '(nxhtml-download-root-url nil) "util/css-palette" nxhtml-install-dir) "\ +Minor mode for palettes in CSS. + +The mode `css-palette-mode' acts on the first COLORS declaration in your + file of the form: + +COLORS: +\( +c0 \"#6f5d25\" ;tainted sand +c1 \"#000000\" ;Black +c2 \"#cca42b\" ;goldenslumber +c3 \"#6889cb\" ;far off sky +c4 \"#fff\" ;strange aeons +) + +Such declarations should appear inside a block comment, in order + to be parsed properly by the LISP reader. + +Type \\[css-palette-update-all], and any occurence of + + color: #f55; /*[c3]*/ + +will be updated with + + color: #6899cb; /*[c3]*/ + +The following commands are available to insert key-value pairs + and palette declarations: + \\{css-palette-mode-map} + +You can extend or redefine the types of palettes by defining a + new palette specification of the form (PATTERN REGEXP + REF-FOLLOWS-VALUE), named according to the naming scheme + css-palette:my-type, where + +PATTERN is a pattern containing two (%s) format directives which + will be filled in with the variable and its value, + +REGEXP is a regular expression to match a value - variable + pattern, + +and REF-FOLLOWS-VALUE defined whether or not the reference comes + after the value. This allows for more flexibility. + +Note that, although the w3c spec at URL + `http://www.w3.org/TR/CSS2/syndata.html#comments' says that + comments \" may occur anywhere between tokens, and their + contents have no influence on the rendering\", Internet + Explorer does not think so. Better keep all your comments after + a \"statement\", as per the default. This means `css-palette' + is ill-suited for use within shorthands. + +See variable `css-palette:colors' for an example of a palette + type. + +The extension mechanism means that palette types can be used to + contain arbitrary key-value mappings. + +Besides the colors palette, css-palette defines the palette + definition variables `css-palette:colors-outside' and + `css-palette:files', for colors with the reference outside and + for file url()'s respectively. + +You can fine-control which palette types css-palette should look + at via the variable `css-palette-types'. + +\(fn &optional ARG)" t nil) + +(let ((loads (get 'css-palette 'custom-loads))) (if (member '"css-palette" loads) nil (put 'css-palette 'custom-loads (cons '"css-palette" loads)))) + +(defvar css-palette-global-mode nil "\ +Non-nil if Css-Palette-Global mode is enabled. +See the command `css-palette-global-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `css-palette-global-mode'.") + +(nxhtml-custom-autoload 'css-palette-global-mode 'css-palette nil) + +(nxhtml-autoload 'css-palette-global-mode `(lp '(nxhtml-download-root-url nil) "util/css-palette" nxhtml-install-dir) "\ +Toggle Css-Palette mode in every possible buffer. +With prefix ARG, turn Css-Palette-Global mode on if and only if +ARG is positive. +Css-Palette mode is enabled in all buffers where +`css-palette-turn-on-in-buffer' would do it. +See `css-palette-mode' for more information on Css-Palette mode. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (cusnu-export-my-skin-options customize-for-new-user) +;;;;;; "cus-new-user" "util/cus-new-user.el" (19173 56140)) +;;; Generated autoloads from util/cus-new-user.el +(web-autoload-require 'cus-new-user 'lp '(nxhtml-download-root-url nil) "util/cus-new-user" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'customize-for-new-user `(lp '(nxhtml-download-root-url nil) "util/cus-new-user" nxhtml-install-dir) "\ +Show special customization page for new user. + +\(fn &optional NAME)" t nil) + +(nxhtml-autoload 'cusnu-export-my-skin-options `(lp '(nxhtml-download-root-url nil) "util/cus-new-user" nxhtml-install-dir) "\ +Export to file FILE custom options in `cusnu-my-skin-options'. +The options is exported to elisp code that other users can run to +set the options that you have added to `cusnu-my-skin-options'. + +For more information about this see `cusnu-export-cust-group'. + +\(fn FILE)" t nil) + +;;;*** + +;;;### (autoloads (ediff-url) "ediff-url" "util/ediff-url.el" (19362 +;;;;;; 34258)) +;;; Generated autoloads from util/ediff-url.el +(web-autoload-require 'ediff-url 'lp '(nxhtml-download-root-url nil) "util/ediff-url" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'ediff-url `(lp '(nxhtml-download-root-url nil) "util/ediff-url" nxhtml-install-dir) "\ +Compare current buffer to a web URL using `ediff-buffers'. +Check URL using `ediff-url-redirects' before fetching the file. + +This is for checking downloaded file. A the file may have a comment +telling the download URL of thise form in the header: + + ;; URL: http://the-server.net/the-path/the-file.el + +If not the user is asked for the URL. + +\(fn URL)" t nil) + +;;;*** + +;;;### (autoloads (ffip-find-file-in-dirtree ffip-set-current-project) +;;;;;; "ffip" "util/ffip.el" (19257 25432)) +;;; Generated autoloads from util/ffip.el +(web-autoload-require 'ffip 'lp '(nxhtml-download-root-url nil) "util/ffip" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'ffip-set-current-project `(lp '(nxhtml-download-root-url nil) "util/ffip" nxhtml-install-dir) "\ +Setup ffip project NAME with top directory ROOT of type TYPE. +ROOT can either be just a directory or a list of directory where +the first used just for prompting purposes and the files in the +rest are read into the ffip project. + +Type is a type in `ffip-project-file-types'. + +\(fn NAME ROOT TYPE)" nil nil) + +(nxhtml-autoload 'ffip-find-file-in-dirtree `(lp '(nxhtml-download-root-url nil) "util/ffip" nxhtml-install-dir) "\ +Find files in directory tree ROOT. + +\(fn ROOT)" t nil) + +;;;*** + +;;;### (autoloads (fold-dwim-turn-on-outline-and-hide-all fold-dwim-turn-on-hs-and-hide +;;;;;; fold-dwim-unhide-hs-and-outline fold-dwim-mode fold-dwim-toggle +;;;;;; fold-dwim) "fold-dwim" "util/fold-dwim.el" (19218 42180)) +;;; Generated autoloads from util/fold-dwim.el +(web-autoload-require 'fold-dwim 'lp '(nxhtml-download-root-url nil) "util/fold-dwim" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'fold-dwim 'custom-loads))) (if (member '"fold-dwim" loads) nil (put 'fold-dwim 'custom-loads (cons '"fold-dwim" loads)))) + +(nxhtml-autoload 'fold-dwim-toggle `(lp '(nxhtml-download-root-url nil) "util/fold-dwim" nxhtml-install-dir) "\ +Toggle visibility or some other visual things. +Try toggling different visual things in this order: + +- Images shown at point with `inlimg-mode' +- Text at point prettified by `html-write-mode'. + +For the rest it unhides if possible, otherwise hides in this +order: + +- `org-mode' header or something else using that outlines. +- Maybe `fold-dwim-toggle-selective-display'. +- `Tex-fold-mode' things. +- In html if `outline-minor-mode' and after heading hide content. +- `hs-minor-mode' things. +- `outline-minor-mode' things. (Turns maybe on this.) + +It uses `fold-dwim-show' to show any hidden text at point; if no +hidden fold is found, try `fold-dwim-hide' to hide the +construction at the cursor. + +Note: Also first turn on `fold-dwim-mode' to get the keybinding +for this function from it. + +\(fn)" t nil) + +(defvar fold-dwim-mode nil "\ +Non-nil if Fold-Dwim mode is enabled. +See the command `fold-dwim-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `fold-dwim-mode'.") + +(nxhtml-custom-autoload 'fold-dwim-mode 'fold-dwim nil) + +(nxhtml-autoload 'fold-dwim-mode `(lp '(nxhtml-download-root-url nil) "util/fold-dwim" nxhtml-install-dir) "\ +Key binding for `fold-dwim-toggle'. + +\(fn &optional ARG)" t nil) + +(nxhtml-autoload 'fold-dwim-unhide-hs-and-outline `(lp '(nxhtml-download-root-url nil) "util/fold-dwim" nxhtml-install-dir) "\ +Unhide everything hidden by Hide/Show and Outline. +Ie everything hidden by `hs-minor-mode' and +`outline-minor-mode'. + +\(fn)" t nil) + +(nxhtml-autoload 'fold-dwim-turn-on-hs-and-hide `(lp '(nxhtml-download-root-url nil) "util/fold-dwim" nxhtml-install-dir) "\ +Turn on minor mode `hs-minor-mode' and hide. +If major mode is derived from `nxml-mode' call `hs-hide-block' +else call `hs-hide-all'. + +\(fn)" t nil) + +(nxhtml-autoload 'fold-dwim-turn-on-outline-and-hide-all `(lp '(nxhtml-download-root-url nil) "util/fold-dwim" nxhtml-install-dir) "\ +Turn on `outline-minor-mode' and call `hide-body'. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (foldit-global-mode foldit-mode foldit) "foldit" +;;;;;; "util/foldit.el" (19275 63380)) +;;; Generated autoloads from util/foldit.el +(web-autoload-require 'foldit 'lp '(nxhtml-download-root-url nil) "util/foldit" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'foldit 'custom-loads))) (if (member '"foldit" loads) nil (put 'foldit 'custom-loads (cons '"foldit" loads)))) + +(nxhtml-autoload 'foldit-mode `(lp '(nxhtml-download-root-url nil) "util/foldit" nxhtml-install-dir) "\ +Minor mode providing visual aids for folding. +Shows some hints about what you have hidden and how to reveal it. + +Supports `hs-minor-mode', `outline-minor-mode' and major modes +derived from `outline-mode'. + +\(fn &optional ARG)" t nil) + +(defvar foldit-global-mode nil "\ +Non-nil if Foldit-Global mode is enabled. +See the command `foldit-global-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `foldit-global-mode'.") + +(nxhtml-custom-autoload 'foldit-global-mode 'foldit nil) + +(nxhtml-autoload 'foldit-global-mode `(lp '(nxhtml-download-root-url nil) "util/foldit" nxhtml-install-dir) "\ +Toggle Foldit mode in every possible buffer. +With prefix ARG, turn Foldit-Global mode on if and only if +ARG is positive. +Foldit mode is enabled in all buffers where +`(lambda nil (foldit-mode 1))' would do it. +See `foldit-mode' for more information on Foldit mode. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (gimpedit-can-edit gimpedit-edit-buffer gimpedit-edit-file +;;;;;; gimpedit) "gimpedit" "util/gimpedit.el" (19275 63380)) +;;; Generated autoloads from util/gimpedit.el +(web-autoload-require 'gimpedit 'lp '(nxhtml-download-root-url nil) "util/gimpedit" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'gimpedit 'custom-loads))) (if (member '"gimpedit" loads) nil (put 'gimpedit 'custom-loads (cons '"gimpedit" loads)))) + +(nxhtml-autoload 'gimpedit-edit-file `(lp '(nxhtml-download-root-url nil) "util/gimpedit" nxhtml-install-dir) "\ +Edit IMAGE-FILE with GIMP. +See also `gimpedit-edit-file'. + +\(fn IMAGE-FILE &optional EXTRA-ARGS)" t nil) + +(nxhtml-autoload 'gimpedit-edit-buffer `(lp '(nxhtml-download-root-url nil) "util/gimpedit" nxhtml-install-dir) "\ +Edit image file in current buffer with GIMP. +See also `gimpedit-edit-file'. + +You may also be interested in gimpedit-mode with which you can edit +gimp files from within Emacs using GIMP's scripting +possibilities. See + + URL `http://www.emacswiki.org/emacs/GimpMode' + +\(fn)" t nil) + +(nxhtml-autoload 'gimpedit-can-edit `(lp '(nxhtml-download-root-url nil) "util/gimpedit" nxhtml-install-dir) "\ +Not documented + +\(fn FILE-NAME)" nil nil) + +;;;*** + +;;;### (autoloads (gpl-mode) "gpl" "util/gpl.el" (18795 27308)) +;;; Generated autoloads from util/gpl.el +(web-autoload-require 'gpl 'lp '(nxhtml-download-root-url nil) "util/gpl" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'gpl-mode `(lp '(nxhtml-download-root-url nil) "util/gpl" nxhtml-install-dir) "\ +Mode for font-locking and editing color palettes of the GPL format. + +Such palettes are used and produced by free software applications +such as the GIMP, Inkscape, Scribus, Agave and on-line tools such +as http://colourlovers.com. + +You can also use +URL `http://niels.kicks-ass.org/public/elisp/css-palette.el' to import +such palette into a css-file as hexadecimal color palette. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (hfyview-frame hfyview-window hfyview-region hfyview-buffer +;;;;;; hfyview-quick-print-in-files-menu) "hfyview" "util/hfyview.el" +;;;;;; (19400 17335)) +;;; Generated autoloads from util/hfyview.el +(web-autoload-require 'hfyview 'lp '(nxhtml-download-root-url nil) "util/hfyview" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(defvar hfyview-quick-print-in-files-menu nil "\ +Add Quick print entries to File menu if non-nil. +If you set this to nil you have to restart Emacs to get rid of +the Quick Print entry.") + +(nxhtml-custom-autoload 'hfyview-quick-print-in-files-menu 'hfyview nil) + +(nxhtml-autoload 'hfyview-buffer `(lp '(nxhtml-download-root-url nil) "util/hfyview" nxhtml-install-dir) "\ +Convert buffer to html preserving faces and show in web browser. +With command prefix ARG also show html source in other window. + +\(fn ARG)" t nil) + +(nxhtml-autoload 'hfyview-region `(lp '(nxhtml-download-root-url nil) "util/hfyview" nxhtml-install-dir) "\ +Convert region to html preserving faces and show in web browser. +With command prefix ARG also show html source in other window. + +\(fn ARG)" t nil) + +(nxhtml-autoload 'hfyview-window `(lp '(nxhtml-download-root-url nil) "util/hfyview" nxhtml-install-dir) "\ +Convert window to html preserving faces and show in web browser. +With command prefix ARG also show html source in other window. + +\(fn ARG)" t nil) + +(nxhtml-autoload 'hfyview-frame `(lp '(nxhtml-download-root-url nil) "util/hfyview" nxhtml-install-dir) "\ +Convert frame to html preserving faces and show in web browser. +Make an XHTML view of the current Emacs frame. Put it in a buffer +named *hfyview-frame* and show that buffer in a web browser. + +If WHOLE-BUFFERS is non-nil then the whole content of the buffers +is shown in the XHTML page, otherwise just the part that is +visible currently on the frame. + +If you turn on the minor mode `hfyview-frame-mode' you can also +get the minibuffer/echo area in the output. See this mode for +details. + +With command prefix also show html source in other window. + +\(fn WHOLE-BUFFERS)" t nil) + +;;;*** + +;;;### (autoloads (hl-needed-mode hl-needed) "hl-needed" "util/hl-needed.el" +;;;;;; (19394 16942)) +;;; Generated autoloads from util/hl-needed.el +(web-autoload-require 'hl-needed 'lp '(nxhtml-download-root-url nil) "util/hl-needed" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'hl-needed 'custom-loads))) (if (member '"hl-needed" loads) nil (put 'hl-needed 'custom-loads (cons '"hl-needed" loads)))) + +(defvar hl-needed-mode nil "\ +Non-nil if Hl-Needed mode is enabled. +See the command `hl-needed-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `hl-needed-mode'.") + +(nxhtml-custom-autoload 'hl-needed-mode 'hl-needed nil) + +(nxhtml-autoload 'hl-needed-mode `(lp '(nxhtml-download-root-url nil) "util/hl-needed" nxhtml-install-dir) "\ +Try to highlight current line and column when needed. +This is a global minor mode. It can operate in some different +ways: + +- Highlighting can be on always, see `hl-needed-always'. + +Or, it can be turned on depending on some conditions. In this +case highlighting is turned off after each command and turned on +again in the current window when either: + +- A new window was selected, see `hl-needed-on-new-window'. +- A new buffer was selected, see `hl-needed-on-new-buffer'. +- Window configuration was changed, see `hl-needed-on-config-change'. +- Buffer was scrolled see `hl-needed-on-scrolling'. +- A window was clicked with the mouse, see `hl-needed-on-mouse'. + +After this highlighting may be turned off again, normally after a +short delay, see `hl-needed-flash'. + +If either highlighting was not turned on or was turned off again +it will be turned on when + +- Emacs has been idle for `hl-needed-idle-time' seconds. + +See also `hl-needed-not-in-modes' and `hl-needed-currently-fun'. + +Note 1: For columns to be highlighted vline.el must be available. + +Note 2: This mode depends on `hl-line-mode' and `vline-mode' and +tries to cooperate with them. If you turn on either of these that +overrides the variables for turning on the respective +highlighting here. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (html-write-mode html-write) "html-write" "util/html-write.el" +;;;;;; (19275 63380)) +;;; Generated autoloads from util/html-write.el +(web-autoload-require 'html-write 'lp '(nxhtml-download-root-url nil) "util/html-write" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'html-write 'custom-loads))) (if (member '"html-write" loads) nil (put 'html-write 'custom-loads (cons '"html-write" loads)))) + +(nxhtml-autoload 'html-write-mode `(lp '(nxhtml-download-root-url nil) "util/html-write" nxhtml-install-dir) "\ +Minor mode for convenient display of some HTML tags. +When this mode is on a tag in `html-write-tag-list' is displayed as +the inner text of the tag with a face corresponding to the tag. +By default for example ... is displayed as italic and +... is displayed as an underlined clickable link. + +Only non-nested tags are hidden. The idea is just that it should +be easier to read and write, not that it should look as html +rendered text. + +See the customization group `html-write' for more information about +faces. + +The following keys are defined when you are on a tag handled by +this minor mode: + +\\{html-write-keymap} + +IMPORTANT: Most commands you use works also on the text that is +hidden. The movement commands is an exception, but as soon as +you edit the buffer you may also change the hidden parts. + +Hint: Together with `wrap-to-fill-column-mode' this can make it +easier to see what text you are actually writing in html parts of +a web file. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (inlimg-toggle-slicing inlimg-toggle-display inlimg-global-mode +;;;;;; inlimg-mode inlimg) "inlimg" "util/inlimg.el" (19269 33008)) +;;; Generated autoloads from util/inlimg.el +(web-autoload-require 'inlimg 'lp '(nxhtml-download-root-url nil) "util/inlimg" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'inlimg 'custom-loads))) (if (member '"inlimg" loads) nil (put 'inlimg 'custom-loads (cons '"inlimg" loads)))) + +(nxhtml-autoload 'inlimg-mode `(lp '(nxhtml-download-root-url nil) "util/inlimg" nxhtml-install-dir) "\ +Display images inline. +Search buffer for image tags. Display found images. + +Image tags are setup per major mode in `inlimg-mode-specs'. + +Images are displayed on a line below the tag referencing them. +The whole image or a slice of it may be displayed, see +`inlimg-slice'. Margins relative text are specified in +`inlimg-margins'. + +See also the commands `inlimg-toggle-display' and +`inlimg-toggle-slicing'. + +Note: This minor mode uses `font-lock-mode'. + +\(fn &optional ARG)" t nil) + +(defvar inlimg-global-mode nil "\ +Non-nil if Inlimg-Global mode is enabled. +See the command `inlimg-global-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `inlimg-global-mode'.") + +(nxhtml-custom-autoload 'inlimg-global-mode 'inlimg nil) + +(nxhtml-autoload 'inlimg-global-mode `(lp '(nxhtml-download-root-url nil) "util/inlimg" nxhtml-install-dir) "\ +Toggle Inlimg mode in every possible buffer. +With prefix ARG, turn Inlimg-Global mode on if and only if +ARG is positive. +Inlimg mode is enabled in all buffers where +`inlimg--global-turn-on' would do it. +See `inlimg-mode' for more information on Inlimg mode. + +\(fn &optional ARG)" t nil) + +(nxhtml-autoload 'inlimg-toggle-display `(lp '(nxhtml-download-root-url nil) "util/inlimg" nxhtml-install-dir) "\ +Toggle display of image at point POINT. +See also the command `inlimg-mode'. + +\(fn POINT)" t nil) + +(nxhtml-autoload 'inlimg-toggle-slicing `(lp '(nxhtml-download-root-url nil) "util/inlimg" nxhtml-install-dir) "\ +Toggle slicing of image at point POINT. +See also the command `inlimg-mode'. + +\(fn POINT)" t nil) + +;;;*** + +;;;### (autoloads (majmodpri majmodpri-apply-priorities majmodpri-apply +;;;;;; majmodpri-sort-lists) "majmodpri" "util/majmodpri.el" (19407 +;;;;;; 18407)) +;;; Generated autoloads from util/majmodpri.el +(web-autoload-require 'majmodpri 'lp '(nxhtml-download-root-url nil) "util/majmodpri" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'majmodpri-sort-lists `(lp '(nxhtml-download-root-url nil) "util/majmodpri" nxhtml-install-dir) "\ +Sort the list used when selecting major mode. +Only sort those lists choosen in `majmodpri-lists-to-sort'. +Sort according to priorities in `majmodpri-mode-priorities'. +Keep the old order in the list otherwise. + +The lists can be sorted when loading elisp libraries, see +`majmodpri-sort-after-load'. + +See also `majmodpri-apply-priorities'. + +\(fn)" t nil) + +(nxhtml-autoload 'majmodpri-apply `(lp '(nxhtml-download-root-url nil) "util/majmodpri" nxhtml-install-dir) "\ +Sort major mode lists and apply to existing buffers. +Note: This function is suitable to add to +`desktop-after-read-hook'. It will restore the multi major modes +in buffers. + +\(fn)" nil nil) + +(nxhtml-autoload 'majmodpri-apply-priorities `(lp '(nxhtml-download-root-url nil) "util/majmodpri" nxhtml-install-dir) "\ +Apply major mode priorities. +First run `majmodpri-sort-lists' and then if CHANGE-MODES is +non-nil apply to existing file buffers. If interactive ask +before applying. + +\(fn CHANGE-MODES)" t nil) + +(let ((loads (get 'majmodpri 'custom-loads))) (if (member '"majmodpri" loads) nil (put 'majmodpri 'custom-loads (cons '"majmodpri" loads)))) + +;;;*** + +;;;### (autoloads (markchars-global-mode markchars-mode markchars) +;;;;;; "markchars" "util/markchars.el" (19372 5886)) +;;; Generated autoloads from util/markchars.el +(web-autoload-require 'markchars 'lp '(nxhtml-download-root-url nil) "util/markchars" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'markchars 'custom-loads))) (if (member '"markchars" loads) nil (put 'markchars 'custom-loads (cons '"markchars" loads)))) + +(nxhtml-autoload 'markchars-mode `(lp '(nxhtml-download-root-url nil) "util/markchars" nxhtml-install-dir) "\ +Mark special characters. +Which characters to mark are defined by `markchars-keywords'. + +The default is to mark non-IDN, non-ascii chars with a magenta +underline. + +For information about IDN chars see `idn-is-recommended'. + +If you change anything in the customization group `markchars' you +must restart this minor mode for the changes to take effect. + +\(fn &optional ARG)" t nil) + +(defvar markchars-global-mode nil "\ +Non-nil if Markchars-Global mode is enabled. +See the command `markchars-global-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `markchars-global-mode'.") + +(nxhtml-custom-autoload 'markchars-global-mode 'markchars nil) + +(nxhtml-autoload 'markchars-global-mode `(lp '(nxhtml-download-root-url nil) "util/markchars" nxhtml-install-dir) "\ +Toggle Markchars mode in every possible buffer. +With prefix ARG, turn Markchars-Global mode on if and only if +ARG is positive. +Markchars mode is enabled in all buffers where +`(lambda nil (markchars-mode 1))' would do it. +See `markchars-mode' for more information on Markchars mode. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (mlinks-global-mode mlinks-mode mlinks) "mlinks" +;;;;;; "util/mlinks.el" (19364 56214)) +;;; Generated autoloads from util/mlinks.el +(web-autoload-require 'mlinks 'lp '(nxhtml-download-root-url nil) "util/mlinks" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'mlinks 'custom-loads))) (if (member '"mlinks" loads) nil (put 'mlinks 'custom-loads (cons '"mlinks" loads)))) + +(nxhtml-autoload 'mlinks-mode `(lp '(nxhtml-download-root-url nil) "util/mlinks" nxhtml-install-dir) "\ +Recognizes certain parts of a buffer as hyperlinks. +The hyperlinks are created in different ways for different major +modes with the help of the functions in the list +`mlinks-mode-functions'. + +The hyperlinks can be hilighted when point is over them. Use +`mlinks-toggle-hilight' to toggle this feature for the current +buffer. + +All keybindings in this mode are by default done under the prefi§x +key + + C-c RET + +which is supposed to be a kind of mnemonic for link (alluding to +the RET key commonly used in web browser to follow a link). +\(Unfortunately this breaks the rules in info node `Key Binding +Conventions'.) Below are the key bindings defined by this mode: + +\\{mlinks-mode-map} + +For some major modes `mlinks-backward-link' and +`mlinks-forward-link' will take you to the previous/next link. +By default the link moved to will be active, see +`mlinks-active-links'. + +\(fn &optional ARG)" t nil) + +(defvar mlinks-global-mode nil "\ +Non-nil if Mlinks-Global mode is enabled. +See the command `mlinks-global-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `mlinks-global-mode'.") + +(nxhtml-custom-autoload 'mlinks-global-mode 'mlinks nil) + +(nxhtml-autoload 'mlinks-global-mode `(lp '(nxhtml-download-root-url nil) "util/mlinks" nxhtml-install-dir) "\ +Toggle Mlinks mode in every possible buffer. +With prefix ARG, turn Mlinks-Global mode on if and only if +ARG is positive. +Mlinks mode is enabled in all buffers where +`mlinks-turn-on-in-buffer' would do it. +See `mlinks-mode' for more information on Mlinks mode. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (mumamo-multi-major-modep mumamo-list-defined-multi-major-modes +;;;;;; mumamo-mark-for-refontification mumamo-hi-lock-faces mumamo +;;;;;; mumamo-add-to-defined-multi-major-modes define-mumamo-multi-major-mode) +;;;;;; "mumamo" "util/mumamo.el" (19412 26290)) +;;; Generated autoloads from util/mumamo.el +(web-autoload-require 'mumamo 'lp '(nxhtml-download-root-url nil) "util/mumamo" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'define-mumamo-multi-major-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo" nxhtml-install-dir) "\ +Define a function that turn on support for multiple major modes. +Define a function FUN-SYM that set up to divide the current +buffer into chunks with different major modes. + +The documentation string for FUN-SYM should contain the special +documentation in the string SPEC-DOC, general documentation for +functions of this type and information about chunks. + +The new function will use the definitions in CHUNKS (which is +called a \"chunk family\") to make the dividing of the buffer. + +The function FUN-SYM can be used to setup a buffer instead of a +major mode function: + +- The function FUN-SYM can be called instead of calling a major + mode function when you want to use multiple major modes in a + buffer. + +- The defined function can be used instead of a major mode + function in for example `auto-mode-alist'. + +- As the very last thing FUN-SYM will run the hook FUN-SYM-hook, + just as major modes do. + +- There is also a general hook, `mumamo-turn-on-hook', which is + run when turning on mumamo with any of these functions. This + is run right before the hook specific to any of the functions + above that turns on the multiple major mode support. + +- The multi major mode FUN-SYM has a keymap named FUN-SYM-map. + This overrides the major modes' keymaps since it is handled as + a minor mode keymap. + +- There is also a special mumamo keymap, `mumamo-map' that is + active in every buffer with a multi major mode. This is also + handled as a minor mode keymap and therefor overrides the major + modes' keymaps. + +- However when this support for multiple major mode is on the + buffer is divided into chunks, each with its own major mode. + +- The chunks are fontified according the major mode assigned to + them for that. + +- Indenting is also done according to the major mode assigned to + them for that. + +- The actual major mode used in the buffer is changed to the one + in the chunk when moving point between these chunks. + +- When major mode is changed the hooks for the new major mode, + `after-change-major-mode-hook' and `change-major-mode-hook' are + run. + +- There will be an alias for FUN-SYM called mumamo-alias-FUN-SYM. + This can be used to check whic multi major modes have been + defined. + +** A little bit more technical description: + +The dividing of a buffer into chunks is done during fontification +by `mumamo-get-chunk-at'. + +The name of the function is saved in in the buffer local variable +`mumamo-multi-major-mode' when the function is called. + +All functions defined by this macro is added to the list +`mumamo-defined-multi-major-modes'. + +Basically Mumamo handles only major modes that uses jit-lock. +However as a special effort also `nxml-mode' and derivatives +thereof are handled. Since it seems impossible to me to restrict +those major modes fontification to only a chunk without changing +`nxml-mode' the fontification is instead done by +`html-mode'/`sgml-mode' for chunks using `nxml-mode' and its +derivates. + +CHUNKS is a list where each entry have the format + + (CHUNK-DEF-NAME MAIN-MAJOR-MODE SUBMODE-CHUNK-FUNCTIONS) + +CHUNK-DEF-NAME is the key name by which the entry is recognized. +MAIN-MAJOR-MODE is the major mode used when there is no chunks. +If this is nil then `major-mode' before turning on this mode will +be used. + +SUBMODE-CHUNK-FUNCTIONS is a list of the functions that does the +chunk division of the buffer. They are tried in the order they +appear here during the chunk division process. + +If you want to write new functions for chunk divisions then +please see `mumamo-find-possible-chunk'. You can perhaps also +use `mumamo-quick-static-chunk' which is more easy-to-use +alternative. See also the file mumamo-fun.el where there are +many routines for chunk division. + +When you write those new functions you may want to use some of +the functions for testing chunks: + + `mumamo-test-create-chunk-at' `mumamo-test-create-chunks-at-all' + `mumamo-test-easy-make' `mumamo-test-fontify-region' + +These are in the file mumamo-test.el. + +\(fn FUN-SYM SPEC-DOC CHUNKS)" nil (quote macro)) + +(nxhtml-autoload 'mumamo-add-to-defined-multi-major-modes `(lp '(nxhtml-download-root-url nil) "util/mumamo" nxhtml-install-dir) "\ +Not documented + +\(fn ENTRY)" nil nil) + +(let ((loads (get 'mumamo 'custom-loads))) (if (member '"mumamo" loads) nil (put 'mumamo 'custom-loads (cons '"mumamo" loads)))) + +(let ((loads (get 'mumamo-hi-lock-faces 'custom-loads))) (if (member '"mumamo" loads) nil (put 'mumamo-hi-lock-faces 'custom-loads (cons '"mumamo" loads)))) + +(nxhtml-autoload 'mumamo-mark-for-refontification `(lp '(nxhtml-download-root-url nil) "util/mumamo" nxhtml-install-dir) "\ +Mark region between MIN and MAX for refontification. + +\(fn MIN MAX)" nil nil) + +(nxhtml-autoload 'mumamo-list-defined-multi-major-modes `(lp '(nxhtml-download-root-url nil) "util/mumamo" nxhtml-install-dir) "\ +List currently defined multi major modes. +If SHOW-DOC is non-nil show the doc strings added when defining +them. (This is not the full doc string. To show the full doc +string you can click on the multi major mode in the list.) + +If SHOW-CHUNKS is non-nil show the names of the chunk dividing +functions each multi major mode uses. + +If MATCH then show only multi major modes whos names matches. + +\(fn SHOW-DOC SHOW-CHUNKS MATCH)" t nil) + +(nxhtml-autoload 'mumamo-multi-major-modep `(lp '(nxhtml-download-root-url nil) "util/mumamo" nxhtml-install-dir) "\ +Return t if VALUE is a multi major mode function. + +\(fn VALUE)" nil nil) + +;;;*** + +;;;### (autoloads (python-rst-mumamo-mode latex-haskell-mumamo-mode +;;;;;; latex-clojure-mumamo-mode markdown-html-mumamo-mode xsl-sgml-mumamo-mode +;;;;;; xsl-nxml-mumamo-mode mako-html-mumamo-mode org-mumamo-mode +;;;;;; asp-html-mumamo-mode noweb2-mumamo-mode mumamo-noweb2 csound-sgml-mumamo-mode +;;;;;; laszlo-nxml-mumamo-mode metapost-mumamo-mode ruby-heredoc-mumamo-mode +;;;;;; python-heredoc-mumamo-mode cperl-heredoc-mumamo-mode perl-heredoc-mumamo-mode +;;;;;; php-heredoc-mumamo-mode sh-heredoc-mumamo-mode eruby-javascript-mumamo-mode +;;;;;; eruby-html-mumamo-mode eruby-mumamo-mode jsp-html-mumamo-mode +;;;;;; gsp-html-mumamo-mode ssjs-html-mumamo-mode smarty-html-mumamo-mode +;;;;;; mjt-html-mumamo-mode genshi-html-mumamo-mode django-html-mumamo-mode +;;;;;; embperl-html-mumamo-mode mason-html-mumamo-mode nxml-mumamo-mode +;;;;;; html-mumamo-mode mumamo-define-html-file-wide-keys) "mumamo-fun" +;;;;;; "util/mumamo-fun.el" (19410 22971)) +;;; Generated autoloads from util/mumamo-fun.el +(web-autoload-require 'mumamo-fun 'lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'mumamo-define-html-file-wide-keys `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Define keys in multi major mode keymap for html files. + +\(fn)" nil nil) + +(nxhtml-autoload 'html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for (X)HTML with main mode `html-mode'. +This covers inlined style and javascript and PHP." t) + +(nxhtml-autoload 'nxml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for (X)HTML with main mode `nxml-mode'. +This covers inlined style and javascript and PHP. + +See also `mumamo-alt-php-tags-mode'." t) + +(nxhtml-autoload 'mason-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for Mason using main mode `html-mode'. +This covers inlined style and javascript." t) + +(nxhtml-autoload 'embperl-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for Embperl files with main mode `html-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'django-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for Django with main mode `html-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'genshi-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for Genshi with main mode `html-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'mjt-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for MJT with main mode `html-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'smarty-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for Smarty with main mode `html-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'ssjs-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for SSJS with main mode `html-mode'. +This covers inlined style and javascript." t) + +(nxhtml-autoload 'gsp-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for GSP with main mode `html-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'jsp-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for JSP with main mode `html-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'eruby-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major mode for eRuby with unspecified main mode. +Current major-mode will be used as the main major mode." t) + +(nxhtml-autoload 'eruby-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for eRuby with main mode `html-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'eruby-javascript-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for eRuby with main mode `javascript-mode'." t) + +(nxhtml-autoload 'sh-heredoc-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for sh heredoc document. +See `mumamo-heredoc-modes' for how to specify heredoc major modes." t) + +(nxhtml-autoload 'php-heredoc-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for PHP heredoc document. +See `mumamo-heredoc-modes' for how to specify heredoc major modes." t) + +(nxhtml-autoload 'perl-heredoc-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for Perl heredoc document. +See `mumamo-heredoc-modes' for how to specify heredoc major modes." t) + +(nxhtml-autoload 'cperl-heredoc-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for Perl heredoc document. +See `mumamo-heredoc-modes' for how to specify heredoc major modes." t) + +(nxhtml-autoload 'python-heredoc-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for Perl heredoc document. +See `mumamo-heredoc-modes' for how to specify heredoc major modes." t) + +(nxhtml-autoload 'ruby-heredoc-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for Ruby heredoc document. +See `mumamo-heredoc-modes' for how to specify heredoc major modes." t) + +(nxhtml-autoload 'metapost-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for MetaPost." t) + +(nxhtml-autoload 'laszlo-nxml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for OpenLaszlo." t) + +(nxhtml-autoload 'csound-sgml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on mutiple major modes for CSound orc/sco Modes." t) + +(let ((loads (get 'mumamo-noweb2 'custom-loads))) (if (member '"mumamo-fun" loads) nil (put 'mumamo-noweb2 'custom-loads (cons '"mumamo-fun" loads)))) + +(nxhtml-autoload 'noweb2-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Multi major mode for noweb files." t) + +(nxhtml-autoload 'asp-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for ASP with main mode `html-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'org-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for `org-mode' files with main mode `org-mode'. +** Note about HTML subchunks: +Unfortunately this only allows `html-mode' (not `nxhtml-mode') in +sub chunks." t) + +(nxhtml-autoload 'mako-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for Mako with main mode `html-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'xsl-nxml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multi major mode for XSL with main mode `nxml-mode'. +This covers inlined style and javascript." t) + +(nxhtml-autoload 'xsl-sgml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multi major mode for XSL with main mode `sgml-mode'. +This covers inlined style and javascript." t) + +(nxhtml-autoload 'markdown-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multi major markdown mode in buffer. +Main major mode will be `markdown-mode'. +Inlined html will be in `html-mode'. + +You need `markdown-mode' which you can download from URL +`http://jblevins.org/projects/markdown-mode/'." t) + +(nxhtml-autoload 'latex-clojure-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multi major mode latex+clojure. +Main major mode will be `latex-mode'. +Subchunks will be in `clojure-mode'. + +You will need `clojure-mode' which you can download from URL +`http://github.com/jochu/clojure-mode/tree'." t) + +(nxhtml-autoload 'latex-haskell-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multi major mode latex+haskell. +Main major mode will be `latex-mode'. +Subchunks will be in `haskell-mode'. + +You will need `haskell-mode' which you can download from URL +`http://projects.haskell.org/haskellmode-emacs/'." t) + +(nxhtml-autoload 'python-rst-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\ +Turn on multiple major modes for Python with RestructuredText docstrings." t) + +;;;*** + +;;;### (autoloads (mumamo-add-region-from-string mumamo-add-region) +;;;;;; "mumamo-regions" "util/mumamo-regions.el" (19275 63380)) +;;; Generated autoloads from util/mumamo-regions.el +(web-autoload-require 'mumamo-regions 'lp '(nxhtml-download-root-url nil) "util/mumamo-regions" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'mumamo-add-region `(lp '(nxhtml-download-root-url nil) "util/mumamo-regions" nxhtml-install-dir) "\ +Add a mumamo region from selection. +Mumamo regions are like another layer of chunks above the normal chunks. +They does not affect the normal chunks, but they overrides them. + +To create a mumamo region first select a visible region and then +call this function. + +If the buffer is not in a multi major mode a temporary multi +major mode will be created applied to the buffer first. +To get out of this and get back to a single major mode just use + + M-x normal-mode + +\(fn)" t nil) + +(nxhtml-autoload 'mumamo-add-region-from-string `(lp '(nxhtml-download-root-url nil) "util/mumamo-regions" nxhtml-install-dir) "\ +Add a mumamo region from string at point. +Works as `mumamo-add-region' but for string or comment at point. + +Buffer must be fontified. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (n-back-game n-back) "n-back" "util/n-back.el" +;;;;;; (19278 15746)) +;;; Generated autoloads from util/n-back.el +(web-autoload-require 'n-back 'lp '(nxhtml-download-root-url nil) "util/n-back" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'n-back 'custom-loads))) (if (member '"n-back" loads) nil (put 'n-back 'custom-loads (cons '"n-back" loads)))) + +(nxhtml-autoload 'n-back-game `(lp '(nxhtml-download-root-url nil) "util/n-back" nxhtml-install-dir) "\ +Emacs n-Back game. +This game is supposed to increase your working memory and fluid +intelligence. + +In this game something is shown for half a second on the screen +and maybe a sound is played. You should then answer if parts of +it is the same as you have seen or heard before. This is +repeated for about 20 trials. + +You answer with the keys shown in the bottom window. + +In the easiest version of the game you should answer if you have +just seen or heard what is shown now. By default the game gets +harder as you play it with success. Then first the number of +items presented in a trial grows. After that it gets harder by +that you have to somehow remember not the last item, but the item +before that (or even earlier). That is what \"n-Back\" stands +for. + +Note that remember does not really mean remember clearly. The +game is for training your brain getting used to keep those things +in the working memory, maybe as a cross-modal unit. You are +supposed to just nearly be able to do what you do in the game. +And you are supposed to have fun, that is what your brain like. + +You should probably not overdue this. Half an hour a day playing +might be an optimal time according to some people. + +The game is shamelessly modeled after Brain Workshop, see URL +`http://brainworkshop.sourceforge.net/' just for the fun of +getting it into Emacs. The game resembles but it not the same as +that used in the report by Jaeggi mentioned at the above URL. + +Not all features in Brain Workshop are implemented here, but some +new are maybe ... - and you have it available here in Emacs. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (nxhtmltest-run nxhtmltest-run-indent) "nxhtmltest-suites" +;;;;;; "tests/nxhtmltest-suites.el" (19360 6294)) +;;; Generated autoloads from tests/nxhtmltest-suites.el +(web-autoload-require 'nxhtmltest-suites 'lp '(nxhtml-download-root-url nil) "tests/nxhtmltest-suites" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'nxhtmltest-run-indent `(lp '(nxhtml-download-root-url nil) "tests/nxhtmltest-suites" nxhtml-install-dir) "\ +Run indentation tests. + +\(fn)" t nil) + +(nxhtml-autoload 'nxhtmltest-run `(lp '(nxhtml-download-root-url nil) "tests/nxhtmltest-suites" nxhtml-install-dir) "\ +Run all tests defined for nXhtml. +Currently there are only tests using ert.el defined. + +Note that it is currently expected that the following tests will +fail (they corresponds to known errors in nXhtml/Emacs): + + `nxhtml-ert-nxhtml-changes-jump-back-10549' + `nxhtml-ert-nxhtml-changes-jump-back-7014' + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (nxhtmltest-run-Q) "nxhtmltest-Q" "tests/nxhtmltest-Q.el" +;;;;;; (19264 36684)) +;;; Generated autoloads from tests/nxhtmltest-Q.el +(web-autoload-require 'nxhtmltest-Q 'lp '(nxhtml-download-root-url nil) "tests/nxhtmltest-Q" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'nxhtmltest-run-Q `(lp '(nxhtml-download-root-url nil) "tests/nxhtmltest-Q" nxhtml-install-dir) "\ +Run all tests defined for nXhtml in fresh Emacs. +See `nxhtmltest-run' for more information about the tests. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (ert-run-tests-interactively ert-deftest) "ert" +;;;;;; "tests/ert.el" (19173 56140)) +;;; Generated autoloads from tests/ert.el +(web-autoload-require 'ert 'lp '(nxhtml-download-root-url nil) "tests/ert" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'ert-deftest `(lp '(nxhtml-download-root-url nil) "tests/ert" nxhtml-install-dir) "\ +Define NAME (a symbol) as a test. + +\(fn NAME () [:documentation DOCSTRING] [:expected-result TYPE] BODY...)" nil (quote macro)) + +(nxhtml-autoload 'ert-run-tests-interactively `(lp '(nxhtml-download-root-url nil) "tests/ert" nxhtml-install-dir) "\ +Run the tests specified by SELECTOR and display the results in a buffer. + +\(fn SELECTOR &optional OUTPUT-BUFFER-NAME MESSAGE-FN)" t nil) + +;;;*** + +;;;### (autoloads (ocr-user-mode) "ocr-user" "util/ocr-user.el" (19290 +;;;;;; 21626)) +;;; Generated autoloads from util/ocr-user.el +(web-autoload-require 'ocr-user 'lp '(nxhtml-download-root-url nil) "util/ocr-user" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'ocr-user-mode `(lp '(nxhtml-download-root-url nil) "util/ocr-user" nxhtml-install-dir) "\ +Color up digits three by three. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (ourcomments-warning ourcomments-M-x-menu-mode +;;;;;; ourcomments-paste-with-convert-mode use-custom-style info-open-file +;;;;;; replace-read-files rdir-query-replace ldir-query-replace +;;;;;; grep-query-replace emacs-Q-nxhtml emacs-Q emacs--no-desktop +;;;;;; emacs--debug-init emacs-buffer-file emacs emacs-restart ourcomments-ido-ctrl-tab +;;;;;; ourcomments-ido-buffer-raise-frame ourcomments-ido-buffer-other-frame +;;;;;; ourcomments-ido-buffer-other-window describe-symbol describe-defstruct +;;;;;; describe-custom-group narrow-to-comment buffer-narrowed-p +;;;;;; describe-command ourcomments-ediff-files find-emacs-other-file +;;;;;; ourcomments-insert-date-and-time describe-timers ourcomments-copy+paste-set-point +;;;;;; better-fringes-mode describe-key-and-map-briefly ourcomments-move-end-of-line +;;;;;; ourcomments-move-beginning-of-line ourcomments-mark-whole-buffer-or-field +;;;;;; fill-dwim unfill-individual-paragraphs unfill-region unfill-paragraph +;;;;;; define-toggle-old define-toggle popup-menu-at-point ourcomments-indirect-fun) +;;;;;; "ourcomments-util" "util/ourcomments-util.el" (19411 29548)) +;;; Generated autoloads from util/ourcomments-util.el +(web-autoload-require 'ourcomments-util 'lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'ourcomments-indirect-fun `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Get the alias symbol for function FUN if any. + +\(fn FUN)" nil nil) + +(nxhtml-autoload 'popup-menu-at-point `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Popup the given menu at point. +This is similar to `popup-menu' and MENU and PREFIX has the same +meaning as there. The position for the popup is however where +the window point is. + +\(fn MENU &optional PREFIX)" nil nil) + +(nxhtml-autoload 'define-toggle `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Declare SYMBOL as a customizable variable with a toggle function. +The purpose of this macro is to define a defcustom and a toggle +function suitable for use in a menu. + +The arguments have the same meaning as for `defcustom' with these +restrictions: + +- The :type keyword cannot be used. Type is always 'boolean. +- VALUE must be t or nil. + +DOC and ARGS are just passed to `defcustom'. + +A `defcustom' named SYMBOL with doc-string DOC and a function +named SYMBOL-toggle is defined. The function toggles the value +of SYMBOL. It takes no parameters. + +To create a menu item something similar to this can be used: + + (define-key map [SYMBOL] + (list 'menu-item \"Toggle nice SYMBOL\" + 'SYMBOL-toggle + :button '(:toggle . SYMBOL))) + +\(fn SYMBOL VALUE DOC &rest ARGS)" nil (quote macro)) + +(nxhtml-autoload 'define-toggle-old `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Not documented + +\(fn SYMBOL VALUE DOC &rest ARGS)" nil (quote macro)) + +(nxhtml-autoload 'unfill-paragraph `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Unfill the current paragraph. + +\(fn)" t nil) + +(nxhtml-autoload 'unfill-region `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Unfill the current region. + +\(fn)" t nil) + +(nxhtml-autoload 'unfill-individual-paragraphs `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Unfill individual paragraphs in the current region. + +\(fn)" t nil) + +(nxhtml-autoload 'fill-dwim `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Fill or unfill paragraph or region. +With prefix ARG fill only current line. + +\(fn ARG)" t nil) + +(nxhtml-autoload 'ourcomments-mark-whole-buffer-or-field `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Mark whole buffer or editable field at point. + +\(fn)" t nil) + +(nxhtml-autoload 'ourcomments-move-beginning-of-line `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Move point to beginning of line or indentation. +See `beginning-of-line' for ARG. + +If `line-move-visual' is non-nil then the visual line beginning +is first tried. + +If in a widget field stay in that. + +\(fn ARG)" t nil) + +(nxhtml-autoload 'ourcomments-move-end-of-line `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Move point to end of line or after last non blank char. +See `end-of-line' for ARG. + +Similar to `ourcomments-move-beginning-of-line' but for end of +line. + +\(fn ARG)" t nil) + +(nxhtml-autoload 'describe-key-and-map-briefly `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Try to print names of keymap from which KEY fetch its definition. +Look in current active keymaps and find keymap variables with the +same value as the keymap where KEY is bound. Print a message +with those keymap variable names. Return a list with the keymap +variable symbols. + +When called interactively prompt for KEY. + +INSERT and UNTRANSLATED should normall be nil (and I am not sure +what they will do ;-). + +\(fn &optional KEY INSERT UNTRANSLATED)" t nil) + +(defvar better-fringes-mode nil "\ +Non-nil if Better-Fringes mode is enabled. +See the command `better-fringes-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `better-fringes-mode'.") + +(nxhtml-custom-autoload 'better-fringes-mode 'ourcomments-util nil) + +(nxhtml-autoload 'better-fringes-mode `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Choose another fringe bitmap color and bottom angle. + +\(fn &optional ARG)" t nil) + +(nxhtml-autoload 'ourcomments-copy+paste-set-point `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Set point for copy+paste here. +Enable temporary minor mode `ourcomments-copy+paste-mode'. +However if point for copy+paste already is set then cancel it and +disable the minor mode. + +The purpose of this command is to make it easy to grab a piece of +text and paste it at current position. After this command you +should select a piece of text to copy and then call the command +`ourcomments-copy+paste'. + +\(fn)" t nil) + +(nxhtml-autoload 'describe-timers `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Show timers with readable time format. + +\(fn)" t nil) + +(nxhtml-autoload 'ourcomments-insert-date-and-time `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Insert date and time. +See option `ourcomments-insert-date-and-time' for how to +customize it. + +\(fn)" t nil) + +(nxhtml-autoload 'find-emacs-other-file `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Find corresponding file to source or installed elisp file. +If you have checked out and compiled Emacs yourself you may have +Emacs lisp files in two places, the checked out source tree and +the installed Emacs tree. If buffer contains an Emacs elisp file +in one of these places then find the corresponding elisp file in +the other place. Return the file name of this file. + +Rename current buffer using your `uniquify-buffer-name-style' if +it is set. + +When DISPLAY-FILE is non-nil display this file in other window +and go to the same line number as in the current buffer. + +\(fn DISPLAY-FILE)" t nil) + +(nxhtml-autoload 'ourcomments-ediff-files `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +In directory DEF-DIR run `ediff-files' on files FILE-A and FILE-B. +The purpose of this function is to make it eaiser to start +`ediff-files' from a shell through Emacs Client. + +This is used in EmacsW32 in the file ediff.cmd where Emacs Client +is called like this: + + @%emacs_client% -e \"(setq default-directory \\\"%emacs_cd%\\\")\" + @%emacs_client% -n -e \"(ediff-files \\\"%f1%\\\" \\\"%f2%\\\")\" + +It can of course be done in a similar way with other shells. + +\(fn DEF-DIR FILE-A FILE-B)" nil nil) + +(nxhtml-autoload 'describe-command `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Like `describe-function', but prompts only for interactive commands. + +\(fn COMMAND)" t nil) + +(nxhtml-autoload 'buffer-narrowed-p `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Return non-nil if the current buffer is narrowed. + +\(fn)" nil nil) + +(nxhtml-autoload 'narrow-to-comment `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Not documented + +\(fn)" t nil) + +(nxhtml-autoload 'describe-custom-group `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Describe customization group SYMBOL. + +\(fn SYMBOL)" t nil) + +(nxhtml-autoload 'describe-defstruct `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Not documented + +\(fn SYMBOL)" t nil) + +(nxhtml-autoload 'describe-symbol `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Show information about SYMBOL. +Show SYMBOL plist and whether is is a variable or/and a +function. + +\(fn SYMBOL)" t nil) + +(nxhtml-autoload 'ourcomments-ido-buffer-other-window `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Show buffer in other window. + +\(fn)" t nil) + +(nxhtml-autoload 'ourcomments-ido-buffer-other-frame `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Show buffer in other frame. + +\(fn)" t nil) + +(nxhtml-autoload 'ourcomments-ido-buffer-raise-frame `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Raise frame showing buffer. + +\(fn)" t nil) + +(defvar ourcomments-ido-ctrl-tab nil "\ +Non-nil if Ourcomments-Ido-Ctrl-Tab mode is enabled. +See the command `ourcomments-ido-ctrl-tab' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `ourcomments-ido-ctrl-tab'.") + +(nxhtml-custom-autoload 'ourcomments-ido-ctrl-tab 'ourcomments-util nil) + +(nxhtml-autoload 'ourcomments-ido-ctrl-tab `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Enable buffer switching using C-Tab with function `ido-mode'. +This changes buffer switching with function `ido-mode' the +following way: + +- You can use C-Tab. + +- You can show the selected buffer in three ways independent of + how you entered function `ido-mode' buffer switching: + + * S-return: other window + * C-return: other frame + * M-return: raise frame + +Those keys are selected to at least be a little bit reminiscent +of those in for example common web browsers. + +\(fn &optional ARG)" t nil) + +(nxhtml-autoload 'emacs-restart `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Restart Emacs and start `server-mode' if on before. + +\(fn)" t nil) + +(nxhtml-autoload 'emacs `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Start a new Emacs with default parameters. +Additional ARGS are passed to the new Emacs. + +See also `ourcomments-started-emacs-use-output-buffer'. + +\(fn &rest ARGS)" t nil) + +(nxhtml-autoload 'emacs-buffer-file `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Start a new Emacs showing current buffer file. +Go to the current line and column in that file. +If there is no buffer file then instead start with `dired'. + +This calls the function `emacs' with argument --no-desktop and +the file or a call to dired. + +\(fn)" t nil) + +(nxhtml-autoload 'emacs--debug-init `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Start a new Emacs with --debug-init parameter. +This calls the function `emacs' with added arguments ARGS. + +\(fn &rest ARGS)" t nil) + +(nxhtml-autoload 'emacs--no-desktop `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Start a new Emacs with --no-desktop parameter. +This calls the function `emacs' with added arguments ARGS. + +\(fn &rest ARGS)" t nil) + +(nxhtml-autoload 'emacs-Q `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Start a new Emacs with -Q parameter. +Start new Emacs without any customization whatsoever. +This calls the function `emacs' with added arguments ARGS. + +\(fn &rest ARGS)" t nil) + +(nxhtml-autoload 'emacs-Q-nxhtml `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Start new Emacs with -Q and load nXhtml. +This calls the function `emacs' with added arguments ARGS. + +\(fn &rest ARGS)" t nil) + +(nxhtml-autoload 'grep-query-replace `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Do `query-replace-regexp' of FROM with TO, on all files in *grep*. +Third arg DELIMITED (prefix arg) means replace only word-delimited matches. +If you exit (\\[keyboard-quit], RET or q), you can resume the query replace +with the command \\[tags-loop-continue]. + +\(fn FROM TO &optional DELIMITED)" t nil) + +(nxhtml-autoload 'ldir-query-replace `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Replace FROM with TO in FILES in directory DIR. +This runs `query-replace-regexp' in files matching FILES in +directory DIR. + +See `tags-query-replace' for DELIMETED and more information. + +\(fn FROM TO FILES DIR &optional DELIMITED)" t nil) + +(nxhtml-autoload 'rdir-query-replace `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Replace FROM with TO in FILES in directory tree ROOT. +This runs `query-replace-regexp' in files matching FILES in +directory tree ROOT. + +See `tags-query-replace' for DELIMETED and more information. + +\(fn FROM TO FILE-REGEXP ROOT &optional DELIMITED)" t nil) + +(nxhtml-autoload 'replace-read-files `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Read files arg for replace. + +\(fn REGEXP &optional REPLACE)" nil nil) + +(nxhtml-autoload 'info-open-file `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Open an info file in `Info-mode'. + +\(fn INFO-FILE)" t nil) + +(nxhtml-autoload 'use-custom-style `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Setup like in `Custom-mode', but without things specific to Custom. + +\(fn)" nil nil) + +(defvar ourcomments-paste-with-convert-mode nil "\ +Non-nil if Ourcomments-Paste-With-Convert mode is enabled. +See the command `ourcomments-paste-with-convert-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `ourcomments-paste-with-convert-mode'.") + +(nxhtml-custom-autoload 'ourcomments-paste-with-convert-mode 'ourcomments-util nil) + +(nxhtml-autoload 'ourcomments-paste-with-convert-mode `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Pasted text may be automatically converted in this mode. +The functions in `ourcomments-paste-with-convert-hook' are run +after commands in `ourcomments-paste-with-convert-commands' if any +of the functions returns non-nil that text is inserted instead of +the original text. + +For exampel when this mode is on and you paste an html link in an +`org-mode' buffer it will be directly converted to an org style +link. (This is the default behaviour.) + +Tip: The Firefox plugin Copy as HTML Link is handy, see URL + `https://addons.mozilla.org/en-US/firefox/addon/2617'. + +Note: This minor mode will defadvice the paste commands. + +\(fn &optional ARG)" t nil) + +(defvar ourcomments-M-x-menu-mode nil "\ +Non-nil if Ourcomments-M-X-Menu mode is enabled. +See the command `ourcomments-M-x-menu-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `ourcomments-M-x-menu-mode'.") + +(nxhtml-custom-autoload 'ourcomments-M-x-menu-mode 'ourcomments-util nil) + +(nxhtml-autoload 'ourcomments-M-x-menu-mode `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Add commands started from Emacs menus to M-x history. +The purpose of this is to make it easier to redo them and easier +to learn how to do them from the command line (which is often +faster if you know how to do it). + +Only commands that are not already in M-x history are added. + +\(fn &optional ARG)" t nil) + +(nxhtml-autoload 'ourcomments-warning `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\ +Not documented + +\(fn FORMAT-STRING &rest ARGS)" nil nil) + +;;;*** + +;;;### (autoloads (major-modep major-or-multi-majorp) "ourcomments-widgets" +;;;;;; "util/ourcomments-widgets.el" (19275 63380)) +;;; Generated autoloads from util/ourcomments-widgets.el +(web-autoload-require 'ourcomments-widgets 'lp '(nxhtml-download-root-url nil) "util/ourcomments-widgets" nxhtml-install-dir 'nxhtml-byte-compile-file) + + (nxhtml-autoload 'command "ourcomments-widgets") + +(nxhtml-autoload 'major-or-multi-majorp `(lp '(nxhtml-download-root-url nil) "util/ourcomments-widgets" nxhtml-install-dir) "\ +Return t if VALUE is a major or multi major mode function. + +\(fn VALUE)" nil nil) + +(nxhtml-autoload 'major-modep `(lp '(nxhtml-download-root-url nil) "util/ourcomments-widgets" nxhtml-install-dir) "\ +Return t if VALUE is a major mode function. + +\(fn VALUE)" nil nil) + (nxhtml-autoload 'major-mode-function "ourcomments-widgets") + +;;;*** + +;;;### (autoloads (pause-start-in-new-emacs pause-mode pause) "pause" +;;;;;; "util/pause.el" (19335 58922)) +;;; Generated autoloads from util/pause.el +(web-autoload-require 'pause 'lp '(nxhtml-download-root-url nil) "util/pause" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'pause 'custom-loads))) (if (member '"pause" loads) nil (put 'pause 'custom-loads (cons '"pause" loads)))) + +(defvar pause-mode nil "\ +Non-nil if Pause mode is enabled. +See the command `pause-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `pause-mode'.") + +(nxhtml-custom-autoload 'pause-mode 'pause nil) + +(nxhtml-autoload 'pause-mode `(lp '(nxhtml-download-root-url nil) "util/pause" nxhtml-install-dir) "\ +This minor mode tries to make you take a break. +It will jump up and temporary stop your work - even if you are +not in Emacs. If you are in Emacs it will however try to be +gentle and wait until you have been idle with the keyboard for a +short while. (If you are not in Emacs it can't be gentle. How +could it?) + +Then it will show you a special screen with a link to a yoga +exercise you can do when you pause. + +After the pause you continue your work where you were +interrupted. + +\(fn &optional ARG)" t nil) + +(nxhtml-autoload 'pause-start-in-new-emacs `(lp '(nxhtml-download-root-url nil) "util/pause" nxhtml-install-dir) "\ +Start pause with interval AFTER-MINUTES in a new Emacs instance. +The new Emacs instance will be started with -Q. However if +`custom-file' is non-nil it will be loaded so you can still +customize pause. + +One way of using this function may be to put in your .emacs +something like + + ;; for just one Emacs running pause + (when server-mode (pause-start-in-new-emacs 15)) + +See `pause-start' for more info. + +\(fn AFTER-MINUTES)" t nil) + +;;;*** + +;;;### (autoloads (global-pointback-mode pointback-mode) "pointback" +;;;;;; "util/pointback.el" (19023 47096)) +;;; Generated autoloads from util/pointback.el +(web-autoload-require 'pointback 'lp '(nxhtml-download-root-url nil) "util/pointback" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'pointback-mode `(lp '(nxhtml-download-root-url nil) "util/pointback" nxhtml-install-dir) "\ +Restore previous window point when switching back to a buffer. + +\(fn &optional ARG)" t nil) + +(defvar global-pointback-mode nil "\ +Non-nil if Global-Pointback mode is enabled. +See the command `global-pointback-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `global-pointback-mode'.") + +(nxhtml-custom-autoload 'global-pointback-mode 'pointback nil) + +(nxhtml-autoload 'global-pointback-mode `(lp '(nxhtml-download-root-url nil) "util/pointback" nxhtml-install-dir) "\ +Toggle Pointback mode in every possible buffer. +With prefix ARG, turn Global-Pointback mode on if and only if +ARG is positive. +Pointback mode is enabled in all buffers where +`pointback-on' would do it. +See `pointback-mode' for more information on Pointback mode. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (popcmp-completing-read popcmp-completion-style +;;;;;; popcmp) "popcmp" "util/popcmp.el" (19365 33760)) +;;; Generated autoloads from util/popcmp.el +(web-autoload-require 'popcmp 'lp '(nxhtml-download-root-url nil) "util/popcmp" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'popcmp 'custom-loads))) (if (member '"popcmp" loads) nil (put 'popcmp 'custom-loads (cons '"popcmp" loads)))) + +(defvar popcmp-completion-style (cond (t 'popcmp-popup)) "\ +Completion style. +The currently available completion styles are: + +- popcmp-popup: Use OS popup menus (default). +- emacs-default: Emacs default completion. +- Company Mode completion. +- anything: The Anything elisp lib completion style. + +The style of completion set here is not implemented for all +completions. The scope varies however with which completion +style you have choosen. + +For information about Company Mode and how to use it see URL +`http://www.emacswiki.org/emacs/CompanyMode'. + +For information about Anything and how to use it see URL +`http://www.emacswiki.org/emacs/Anything'. + +See also the options `popcmp-short-help-beside-alts' and +`popcmp-group-alternatives' which are also availabe when popup +completion is available.") + +(nxhtml-custom-autoload 'popcmp-completion-style 'popcmp nil) + +(nxhtml-autoload 'popcmp-completing-read `(lp '(nxhtml-download-root-url nil) "util/popcmp" nxhtml-install-dir) "\ +Read a string in the minubuffer with completion, or popup a menu. +This function can be used instead `completing-read'. The main +purpose is to provide a popup style menu for completion when +completion is tighed to text at point in a buffer. If a popup +menu is used it will be shown at window point. Whether a popup +menu or minibuffer completion is used is governed by +`popcmp-completion-style'. + +The variables PROMPT, TABLE, PREDICATE, REQUIRE-MATCH, +INITIAL-INPUT, POP-HIST, DEF and INHERIT-INPUT-METHOD all have the +same meaning is for `completing-read'. + +ALT-HELP should be nil or a hash variable or an association list +with the completion alternative as key and a short help text as +value. You do not need to supply help text for all alternatives. +The use of ALT-HELP is set by `popcmp-short-help-beside-alts'. + +ALT-SETS should be nil or an association list that has as keys +groups and as second element an alternative that should go into +this group. + +\(fn PROMPT TABLE &optional PREDICATE REQUIRE-MATCH INITIAL-INPUT POP-HIST DEF INHERIT-INPUT-METHOD ALT-HELP ALT-SETS)" nil nil) + +;;;*** + +;;;### (autoloads (rebind-keys-mode rebind) "rebind" "util/rebind.el" +;;;;;; (19292 11678)) +;;; Generated autoloads from util/rebind.el +(web-autoload-require 'rebind 'lp '(nxhtml-download-root-url nil) "util/rebind" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'rebind 'custom-loads))) (if (member '"rebind" loads) nil (put 'rebind 'custom-loads (cons '"rebind" loads)))) + +(defvar rebind-keys-mode nil "\ +Non-nil if Rebind-Keys mode is enabled. +See the command `rebind-keys-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `rebind-keys-mode'.") + +(nxhtml-custom-autoload 'rebind-keys-mode 'rebind nil) + +(nxhtml-autoload 'rebind-keys-mode `(lp '(nxhtml-download-root-url nil) "util/rebind" nxhtml-install-dir) "\ +Rebind keys as defined in `rebind-keys'. +The key bindings will override almost all other key bindings +since it is put on emulation level, like for example ``cua-mode' +and `viper-mode'. + +This is for using for example C-a to mark the whole buffer (or a +field). There are some predifined keybindings for this. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (rnc-mode) "rnc-mode" "util/rnc-mode.el" (18775 +;;;;;; 60004)) +;;; Generated autoloads from util/rnc-mode.el +(web-autoload-require 'rnc-mode 'lp '(nxhtml-download-root-url nil) "util/rnc-mode" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'rnc-mode `(lp '(nxhtml-download-root-url nil) "util/rnc-mode" nxhtml-install-dir) "\ +Major mode for editing RELAX NG Compact Syntax schemas. +\\{rnc-mode-map} + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (search-form) "search-form" "util/search-form.el" +;;;;;; (19275 63380)) +;;; Generated autoloads from util/search-form.el +(web-autoload-require 'search-form 'lp '(nxhtml-download-root-url nil) "util/search-form" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'search-form `(lp '(nxhtml-download-root-url nil) "util/search-form" nxhtml-install-dir) "\ +Display a form for search and replace. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (sex-mode sex) "sex-mode" "util/sex-mode.el" (19218 +;;;;;; 42182)) +;;; Generated autoloads from util/sex-mode.el +(web-autoload-require 'sex-mode 'lp '(nxhtml-download-root-url nil) "util/sex-mode" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'sex 'custom-loads))) (if (member '"sex-mode" loads) nil (put 'sex 'custom-loads (cons '"sex-mode" loads)))) + +(defvar sex-mode nil "\ +Non-nil if Sex mode is enabled. +See the command `sex-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `sex-mode'.") + +(nxhtml-custom-autoload 'sex-mode 'sex-mode nil) + +(nxhtml-autoload 'sex-mode `(lp '(nxhtml-download-root-url nil) "util/sex-mode" nxhtml-install-dir) "\ +Open certain files in external programs. +See `sex-get-file-open-cmd' for how to determine which files to +open by external applications. Note that this selection is +nearly the same as in `org-mode'. The main difference is that +the fallback always is to open a file in Emacs. (This is +necessary to avoid to disturb many of Emacs operations.) + +This affects all functions that opens files, like `find-file', +`find-file-noselect' etc. + +However it does not affect files opened through Emacs client. + +Urls can also be handled, see `sex-handle-urls'. + +When opening a file with the shell a (temporary) dummy buffer is +created in Emacs with major mode `sex-file-mode' and an external +program is called to handle the file. How this dummy buffer is +handled is governed by `sex-keep-dummy-buffer'. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (sml-modeline-mode sml-modeline) "sml-modeline" +;;;;;; "util/sml-modeline.el" (19362 49086)) +;;; Generated autoloads from util/sml-modeline.el +(web-autoload-require 'sml-modeline 'lp '(nxhtml-download-root-url nil) "util/sml-modeline" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'sml-modeline 'custom-loads))) (if (member '"sml-modeline" loads) nil (put 'sml-modeline 'custom-loads (cons '"sml-modeline" loads)))) + +(defvar sml-modeline-mode nil "\ +Non-nil if Sml-Modeline mode is enabled. +See the command `sml-modeline-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `sml-modeline-mode'.") + +(nxhtml-custom-autoload 'sml-modeline-mode 'sml-modeline nil) + +(nxhtml-autoload 'sml-modeline-mode `(lp '(nxhtml-download-root-url nil) "util/sml-modeline" nxhtml-install-dir) "\ +Show buffer size and position like scrollbar in mode line. +You can customize this minor mode, see option `sml-modeline-mode'. + +Note: If you turn this mode on then you probably want to turn off +option `scroll-bar-mode'. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (tabkey2-emma-without-tabkey2 tabkey2-mode tabkey2) +;;;;;; "tabkey2" "util/tabkey2.el" (19277 65356)) +;;; Generated autoloads from util/tabkey2.el +(web-autoload-require 'tabkey2 'lp '(nxhtml-download-root-url nil) "util/tabkey2" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'tabkey2 'custom-loads))) (if (member '"tabkey2" loads) nil (put 'tabkey2 'custom-loads (cons '"tabkey2" loads)))) + +(defvar tabkey2-mode nil "\ +Non-nil if Tabkey2 mode is enabled. +See the command `tabkey2-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `tabkey2-mode'.") + +(nxhtml-custom-autoload 'tabkey2-mode 'tabkey2 nil) + +(nxhtml-autoload 'tabkey2-mode `(lp '(nxhtml-download-root-url nil) "util/tabkey2" nxhtml-install-dir) "\ +More fun with Tab key number two (completion etc). +This global minor mode by default binds Tab in a way that let you +do completion with Tab in all buffers (where it is possible). + +The Tab key is easy to type on your keyboard. Then why not use +it for completion, something that is very useful? Shells usually +use Tab for completion so many are used to it. This was the idea +of Smart Tabs and this is a generalization of that idea. + +However in Emacs the Tab key is usually used for indentation. +The idea here is that if Tab has been pressed once for +indentation, then as long as point stays further Tab keys might +as well do completion. + +So you kind of do Tab-Tab for first completion (and then just +Tab for further completions as long as point is not moved). + +And there is even kind of Tab-Tab-Tab completion: If completion +fails the next completion function will be the one you try with +next Tab. (You get some notification of this, of course.) + +See `tabkey2-first' for more information about usage. + +Note: If you do not want the Tab-Tab behaviour above, but still +want an easy way to reach the available completion functions, +then you can instead of turning on tabkey2-mode enter this in +your .emacs: + + (global-set-key [f8] 'tabkey2-cycle-completion-functions) + +After hitting f8 you will then be in the same state as after the +first in tabkey2-mode. + +\(fn &optional ARG)" t nil) + +(nxhtml-autoload 'tabkey2-emma-without-tabkey2 `(lp '(nxhtml-download-root-url nil) "util/tabkey2" nxhtml-install-dir) "\ +Not documented + +\(fn)" nil nil) + +;;;*** + +;;;### (autoloads (tyda-mode) "tyda" "util/tyda.el" (19275 63380)) +;;; Generated autoloads from util/tyda.el +(web-autoload-require 'tyda 'lp '(nxhtml-download-root-url nil) "util/tyda" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(defvar tyda-mode nil "\ +Non-nil if Tyda mode is enabled. +See the command `tyda-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `tyda-mode'.") + +(nxhtml-custom-autoload 'tyda-mode 'tyda nil) + +(nxhtml-autoload 'tyda-mode `(lp '(nxhtml-download-root-url nil) "util/tyda" nxhtml-install-dir) "\ +Minor mode for key bindings for `tyda-lookup-word'. +It binds Alt-Mouse-1 just as the Tyda add-on does in Firefox. +Here are all key bindings + +\\{tyda-mode-map} + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (udev-call-first-step) "udev" "util/udev.el" (19412 +;;;;;; 25976)) +;;; Generated autoloads from util/udev.el +(web-autoload-require 'udev 'lp '(nxhtml-download-root-url nil) "util/udev" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'udev-call-first-step `(lp '(nxhtml-download-root-url nil) "util/udev" nxhtml-install-dir) "\ +Set up and call first step. +Set up buffer LOG-BUFFER to be used for log messages and +controling of the execution of the functions in list STEPS which +are executed one after another. + +Write HEADER at the end of LOG-BUFFER. + +Call first step. + +If FINISH-FUN non-nil it should be a function. This is called +after last step with LOG-BUFFER as parameter. + +\(fn LOG-BUFFER STEPS HEADER FINISH-FUN)" nil nil) + +;;;*** + +;;;### (autoloads (udev-ecb-customize-startup udev-ecb-update) "udev-ecb" +;;;;;; "util/udev-ecb.el" (19256 5410)) +;;; Generated autoloads from util/udev-ecb.el +(web-autoload-require 'udev-ecb 'lp '(nxhtml-download-root-url nil) "util/udev-ecb" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'udev-ecb-update `(lp '(nxhtml-download-root-url nil) "util/udev-ecb" nxhtml-install-dir) "\ +Fetch and install ECB from the devel sources. +To determine where to store the sources see `udev-ecb-dir'. +For how to start ECB see `udev-ecb-load-ecb'. + +\(fn)" t nil) + +(nxhtml-autoload 'udev-ecb-customize-startup `(lp '(nxhtml-download-root-url nil) "util/udev-ecb" nxhtml-install-dir) "\ +Customize ECB dev nXhtml startup group. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (udev-rinari-update) "udev-rinari" "util/udev-rinari.el" +;;;;;; (19256 5410)) +;;; Generated autoloads from util/udev-rinari.el +(web-autoload-require 'udev-rinari 'lp '(nxhtml-download-root-url nil) "util/udev-rinari" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'udev-rinari-update `(lp '(nxhtml-download-root-url nil) "util/udev-rinari" nxhtml-install-dir) "\ +Fetch and install Rinari from the devel sources. +To determine where to store the sources and how to start rinari +see `udev-rinari-dir' and `udev-rinari-load-rinari'. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (viper-tutorial) "viper-tut" "util/viper-tut.el" +;;;;;; (19388 44990)) +;;; Generated autoloads from util/viper-tut.el +(web-autoload-require 'viper-tut 'lp '(nxhtml-download-root-url nil) "util/viper-tut" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'viper-tutorial `(lp '(nxhtml-download-root-url nil) "util/viper-tut" nxhtml-install-dir) "\ +Run a tutorial for Viper. + +A simple classic tutorial in 5 parts that have been used by many +people starting to learn vi keys. You may learn enough to start +using `viper-mode' in Emacs. + +Some people find that vi keys helps against repetetive strain +injury, see URL + + `http://www.emacswiki.org/emacs/RepeatedStrainInjury'. + +Note: There might be a few clashes between vi key binding and +Emacs standard key bindings. You will be notified about those in +the tutorial. Even more, if your own key bindings comes in +between you will be notified about that too. + +\(fn PART &optional DONT-ASK-FOR-REVERT)" t nil) + +;;;*** + +;;;### (autoloads (vline-global-mode vline-mode) "vline" "util/vline.el" +;;;;;; (19157 2168)) +;;; Generated autoloads from util/vline.el +(web-autoload-require 'vline 'lp '(nxhtml-download-root-url nil) "util/vline" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'vline-mode `(lp '(nxhtml-download-root-url nil) "util/vline" nxhtml-install-dir) "\ +Display vertical line mode. + +\(fn &optional ARG)" t nil) + +(defvar vline-global-mode nil "\ +Non-nil if Vline-Global mode is enabled. +See the command `vline-global-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vline-global-mode'.") + +(nxhtml-custom-autoload 'vline-global-mode 'vline nil) + +(nxhtml-autoload 'vline-global-mode `(lp '(nxhtml-download-root-url nil) "util/vline" nxhtml-install-dir) "\ +Display vertical line mode as globally. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (whelp) "whelp" "util/whelp.el" (19277 65356)) +;;; Generated autoloads from util/whelp.el +(web-autoload-require 'whelp 'lp '(nxhtml-download-root-url nil) "util/whelp" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'whelp 'custom-loads))) (if (member '"whelp" loads) nil (put 'whelp 'custom-loads (cons '"whelp" loads)))) + +;;;*** + +;;;### (autoloads (wikipedia-draft-buffer wikipedia-draft-page wikipedia-draft +;;;;;; wikipedia-mode) "wikipedia-mode" "related/wikipedia-mode.el" +;;;;;; (19277 65356)) +;;; Generated autoloads from related/wikipedia-mode.el +(web-autoload-require 'wikipedia-mode 'lp '(nxhtml-download-root-url nil) "related/wikipedia-mode" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'wikipedia-mode `(lp '(nxhtml-download-root-url nil) "related/wikipedia-mode" nxhtml-install-dir) "\ +Major mode for editing wikimedia style wikis. +Major mode for editing articles written in the markup language +used by Wikipedia, the free on-line +encyclopedia (see URL `http://www.wikipedia.org'). + +There are several ways to use wikipedia-mode: + +- You can simply cut and paste articles between Emacs and your + web browser's text box. +- If you are using Firefox you can use the It's All Text add-on + for Firefox. +- You can use MozEx, a Mozilla/Firefox web browser extension that + allows you to call Emacs from a text + box (see URL `http://mozex.mozdev.org/'). +- Another way is to use the PERL script ee-helper, which allows + you to up and download wiki texts. + +Wikipedia articles are usually unfilled: newline characters are not +used for breaking paragraphs into lines. Unfortunately, Emacs does not +handle word wrapping yet. As a workaround, wikipedia-mode turns on +longlines-mode automatically. In case something goes wrong, the +following commands may come in handy: + +\\[wikipedia-fill-article] fills the buffer. +\\[wikipedia-unfill-article] unfills the buffer. +Be warned that function can be dead slow, better use wikipedia-unfill-paragraph-or-region. +\\[wikipedia-unfill-paragraph-or-region] unfills the paragraph +\\[wikipedia-unfill-paragraph-simple] doehe same but simpler. + + + +The following commands put in markup structures. + +\\[wikipedia-insert-bold-italic] bold+italic +\\[wikipedia-insert-bold] bold text +\\[wikipedia-insert-italics] italics +\\[wikipedia-insert-nowiki] no wiki markup +\\[wikipedia-insert-link-wiki] inserts a link + +The following commands are also defined: +\\[wikipedia-insert-user] inserts user name +\\[wikipedia-insert-signature] inserts ~~~~ +\\[wikipedia-insert-enumerate] inserts enumerate type structures +\\[wikipedia-insert-itemize] inserts itemize type structures +\\[wikipedia-insert-hline] inserts a hline + +The draft functionality +\\[wikipedia-draft] +\\[wikipedia-draft-region] +\\[wikipedia-draft-view-draft] +\\[wikipedia-draft-page] +\\[wikipedia-draft-buffer] + +Replying and sending functionality +\\[wikipedia-reply-at-point-simple] +\\[wikipedia-draft-reply] + + +The register functionality +\\[wikipedia-copy-page-to-register] +\\[defun wikipedia-insert-page-to-register] + + +Some simple editing commands. +\\[wikipedia-enhance-indent] +\\[wikipedia-yank-prefix] +\\[wikipedia-unfill-paragraph-or-region] + + + +\\[wikipedia-terminate-paragraph] starts a new list item or paragraph in a context-aware manner. + +\(fn)" t nil) + +(nxhtml-autoload 'wikipedia-draft `(lp '(nxhtml-download-root-url nil) "related/wikipedia-mode" nxhtml-install-dir) "\ +Open a temporary buffer in wikipedia mode for editing an + wikipedia draft, which an arbitrary piece of data. After + finishing the editing either use \\[wikipedia-draft-buffer] to + send the data into the wikipedia-draft-data-file, or send the + buffer using `wikipedia-draft-send-to-mozex' and insert it later + into a wikipedia article. + +\(fn)" t nil) + +(nxhtml-autoload 'wikipedia-draft-page `(lp '(nxhtml-download-root-url nil) "related/wikipedia-mode" nxhtml-install-dir) "\ +Not documented + +\(fn)" t nil) + +(nxhtml-autoload 'wikipedia-draft-buffer `(lp '(nxhtml-download-root-url nil) "related/wikipedia-mode" nxhtml-install-dir) "\ +Wikipedia-draft-buffer sends the contents of the current (temporary) +buffer to the wikipedia-draft-buffer, see the variable +wikipedia-draft-data-file. + +\(fn)" t nil) + +(defvar wikipedia-draft-send-archive t "\ +*Archive the reply.") + +;;;*** + +;;;### (autoloads (visual-basic-mode) "visual-basic-mode" "related/visual-basic-mode.el" +;;;;;; (19235 1650)) +;;; Generated autoloads from related/visual-basic-mode.el +(web-autoload-require 'visual-basic-mode 'lp '(nxhtml-download-root-url nil) "related/visual-basic-mode" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'visual-basic-mode `(lp '(nxhtml-download-root-url nil) "related/visual-basic-mode" nxhtml-install-dir) "\ +A mode for editing Microsoft Visual Basic programs. +Features automatic indentation, font locking, keyword capitalization, +and some minor convenience functions. +Commands: +\\{visual-basic-mode-map} + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (tt-mode) "tt-mode" "related/tt-mode.el" (18603 +;;;;;; 15792)) +;;; Generated autoloads from related/tt-mode.el +(web-autoload-require 'tt-mode 'lp '(nxhtml-download-root-url nil) "related/tt-mode" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'tt-mode `(lp '(nxhtml-download-root-url nil) "related/tt-mode" nxhtml-install-dir) "\ +Major mode for editing Template Toolkit files. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (smarty-mode smarty) "smarty-mode" "related/smarty-mode.el" +;;;;;; (19235 1650)) +;;; Generated autoloads from related/smarty-mode.el +(web-autoload-require 'smarty-mode 'lp '(nxhtml-download-root-url nil) "related/smarty-mode" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'smarty 'custom-loads))) (if (member '"smarty-mode" loads) nil (put 'smarty 'custom-loads (cons '"smarty-mode" loads)))) + +(nxhtml-autoload 'smarty-mode `(lp '(nxhtml-download-root-url nil) "related/smarty-mode" nxhtml-install-dir) "\ +Smarty Mode +*********** + +Smarty Mode is a GNU XEmacs major mode for editing Smarty templates. + +1 Introduction +************** + +Smarty-Mode is a mode allowing easy edit of Smarty templates: +highlight, templates, navigation into source files... + + + +Features (new features in bold) : + + * Completion + + * Customizable + + * Highlight + + * Menu + + * Stuttering + + * Templates + - Built-in Functions + + - User Functions + + - Variable Modifiers + + - Plugin (Functions) + * BlockRepeatPlugin + + * ClipCache + + * Smarty Formtool + + * Smarty Paginate + + * Smarty Validate + + - Plugin (Variable Modifiers) + * AlternativeDateModifierPlugin + + * B2Smilies + + * BBCodePlugin + + - Fonctions Non-Smarty + + + +This manual describes Smarty Mode version 0.0.5. + +2 Installation +************** + +2.1 Requirements +================ + +Smarty Mode is a XEmacs major mode that needs the following +software/packages: + + * XEmacs (http://www.xemacs.org/). + + * `font-lock' mode generaly installed with XEmacs. + + * `assoc' mode generaly installed with XEmacs. + + * `easymenu' mode generaly installed with XEmacs. + + * `hippie-exp' mode generaly installed with XEmacs. + +Before continuing, you must be sure to have all this packages +installed. + +2.2 Download +============ + +Two internet address to download Smarty Mode : + + * Principal: Smarty-Mode 0.0.5 + (http://deboutv.free.fr/lisp/smarty/download/smarty-0.0.5.tar.gz) + (http://deboutv.free.fr/lisp/smarty/) + + * Secondary: Smarty-Mode 0.0.5 + (http://www.morinie.fr/lisp/smarty/download/smarty-0.0.5.tar.gz) + (http://www.morinie.fr/lisp/smarty/) + + * Old releases: Smarty-Mode + (http://deboutv.free.fr/lisp/smarty/download.php) + (http://deboutv.free.fr/lisp/smarty/) + +2.3 Installation +================ + +2.3.1 Installation +------------------ + +To install Smarty Mode you need to choose an installation directory +\(for example `/usr/local/share/lisp' or `c:lisp'). The administrator +must have the write rights on this directory. + +With your favorite unzip software, unzip the archive in the +installation directory. + +Example: + cd /usr/local/share/lisp + tar zxvf smarty-0.0.5.tar.gz +Now you have a `smarty' directory in the installation directory. This +directory contains 2 files `smarty-mode.el' and `smarty-mode.elc' and +another directory `docs' containing the documentation. + +You need to configure XEmacs. open you initialization file `init.el' +\(open the file or start XEmacs then choose the Options menu and Edit +Init File). Add the following lines (the installation directory in +this example is `/usr/local/share/lisp') : + + (setq load-path + (append (list \"/usr/local/share/lisp/\") load-path)) + (nxhtml-autoload 'smarty-mode \"smarty-mode\" \"Smarty Mode\" t) + +2.3.2 Update +------------ + +The update is easy. You need to unzip the archive in the installation +directory to remove the old release. + +Example: + cd /usr/local/share/lisp + rm -rf smarty + tar zxvf smarty-0.0.5.tar.gz + +2.4 Invoke Smarty-Mode +====================== + +You have two possibilities to invoke the Smarty Mode. + + - Manually: At each file opening you need to launch Smarty Mode + with the following command: + + `M-x smarty-mode' + + - Automatically: Add the following linesin your initialization + file `init.el' : + + (setq auto-mode-alist + (append + '((\"\\.tpl$\" . smarty-mode)) + auto-mode-alist)) + + +3 Customization +*************** + +This chapter describes the differents parameters and functions that +you can change to customize Smarty Mode. To do that, open a Smarty +file, click on the Smarty menu and choose Options then Browse +Options.... + +3.1 Parameters +============== + +3.1.1 Mode +---------- + +Smarty Mode has 2 modes allowing to simplify the writing of Smarty +templates. You can enable/disable each mode individually. + +`smarty-electric-mode' + Type: boolean + Default value: `t' + Description: If `t'; enable automatic generation of template. + If `nil'; template generators can still be invoked through key + bindings and menu. Is indicated in the modeline by \"/e\" after + the mode name and can be toggled by `smarty-electric-mode'. + +`smarty-stutter-mode' + Type: boolean + Default value: `t' + Description: If `t'; enable the stuttering. Is indicated in the + modeline by \"/s\" after the mode name and can be toggled by + `smarty-stutter-mode'. + +3.1.2 Menu +---------- + +Smarty Mode has also 1 menu that you can enable/disable. The menu +Sources is specific to each Smarty files opened. + +`smarty-source-file-menu' + Type: boolean + Default value: `t' + Description: If `t'; the Sources menu is enabled. This menu + contains the list of Smarty file located in the current + directory. The Sources menu scans the directory when a file is + opened. + +3.1.3 Menu +---------- + +`smarty-highlight-plugin-functions' + Type: boolean + Default value: `t' + Description: If `t'; the functions described in the smarty + plugins are highlighted. + +3.1.4 Templates +--------------- + +3.1.4.1 Header +.............. + +`smarty-file-header' + Type: string + Default value: `\"\"' + Description: String or file to insert as file header. If the + string specifies an existing file name the contents of the file + is inserted; otherwise the string itself is inserted as file + header. + Type `C-j' for newlines. + The follonwing keywords are supported: + : replaced by the file name. + : replaced by the user name and email address. + : replaced by `user-login-name'. + : replaced by `smarty-company-name' content. + : replaced by the current date. + : replaced by the current year. + : replaced by `smarty-copyright-string' content. + : final cursor position. + +`smarty-file-footer' + Type: string + Default value: `\"\"' + Description: String or file to insert as file footer. See + `smarty-file-header' + +`smarty-company-name' + Type: string + Default value: `\"\"' + Description: Name of the company to insert in file header. + +`smarty-copyright-string' + Type: string + Default value: `\"\"' + Description: Coryright string to insert in file header. + +`smarty-date-format' + Type: string + Default value: `\"%Y-%m-%d\"' + Description: Date format. + +`smarty-modify-date-prefix-string' + Type: string + Default value: `\"\"' + Description: Prefix string of modification date in Smarty file + header. + +`smarty-modify-date-on-saving' + Type: bool + Default value: `nil' + Description: If `t'; update the modification date when the + buffer is saved. + +3.1.5 Miscellaneous +------------------- + +`smarty-left-delimiter' + Type: string + Default value: `\"\"' + Description: Left escaping delimiter for Smarty templates. + +`smarty-right-delimiter' + Type: string + Default value: `\"\"' + Description: Right escaping delimiter for Smarty templates. + +`smarty-intelligent-tab' + Type: bool + Default value: `t' + Description: If `t'; TAB does indentation; completion and insert + tabulations. If `nil'; TAB does only indentation. + +`smarty-word-completion-in-minibuffer' + Type: bool + Default value: `t' + Description: If `t'; enable completion in the minibuffer. + +`smarty-word-completion-case-sensitive' + Type: bool + Default value: `nil' + Description: If `t'; completion is case sensitive. + +3.2 Functions +============= + +3.2.1 Mode +---------- + +`smarty-electric-mode' + Menu: Smarty -> Options -> Mode -> Electric Mode + Keybinding: `C-c C-m C-e' + Description: This functions is used to enable/disable the + electric mode. + +`smarty-stutter-mode' + Menu: Smarty -> Options -> Mode -> Stutter Mode + Keybinding: `C-c C-m C-s' + Description: This function is used to enable/disable the stutter + mode. + +4 Menus +******* + +There are 2 menus: Smarty and Sources. All theses menus can be +accessed from the menubar or from the right click. This chapter +describes each menus. + +4.1 Smarty +========== + +This is the main menu of Smarty Mode. It allows an easy access to the +main features of the Smarty Mode: Templates (see *Note Templates::) +and Options (see *Note Customization::). + +This menu contains also 3 functions that are discussed in the next +part. + +4.1.1 Functions +--------------- + +`smarty-show-messages' + Menu: Smarty -> Show Messages + Keybinding: `C-c M-m' + Description: This function opens the *Messages* buffer to + display previous error messages. + +`smarty-doc-mode' + Menu: Smarty -> Smarty Mode Documentation + Keybinding: `C-c C-h' + Description: This function opens the *Help* buffer and prints in + it the Smarty Mode documentation. + +`smarty-version' + Menu: Smarty -> Version + Keybinding: `C-c C-v' + Description: This function displays in the minibuffer the + current Smarty Mode version with the timestamp. + +4.2 Sources +=========== + +The Sources menu shows the Smarty files in the current directory. If +you add or delete a file in the current directory, you need to +refresh the menu. + +4.2.1 Customization +------------------- + +`smarty-source-file-menu' + Type: boolean + Default value: `t' + Description: If `t'; the Sources menu is enabled. This menu + contains the list of Smarty file located in the current + directory. The Sources menu scans the directory when a file is + opened. + +4.2.2 Functions +--------------- + +`smarty-add-source-files-menu' + Menu: Sources -> *Rescan* + Keybinding: `C-c C-s C-u' + Description: This function is used to refresh the Sources menu. + +5 Stuttering +************ + +The stutter mode is a mode that affects a function to a key. For +example, when you use the `ENTER' key, the associated function will +create a new line and indent it. + +5.1 Customization +================= + +`smarty-stutter-mode' + Type: boolean + Default value: `t' + Description: If `t'; enable the stuttering. Is indicated in the + modeline by \"/s\" after the mode name and can be toggled by + `smarty-stutter-mode'. + +5.2 Functions +============= + +`SPACE' + If in comment, indent the comment and add new line if necessary. + In other case, add a space. + +`(' + If the previous character is a `(', the `((' will be replaced by + `['. + If the previous character is a `[', the `[(' will be replaced by + `{'. + In other case, insert a `('. + +`)' + If the previous character is a `)', the `))' will be replaced by + `]'. + If the previous character is a `]', the `])' will be replaced by + `}'. + In other case, insert a `)'. + +6 Templates +*********** + +In the Smarty Mode, the Smarty functions (like if, while, for, fopen, +fclose) are predefined in functions called \"Templates\". + +Each template can be invoked by the function name or by using the + key after the Smarty function name in the buffer (Note, using +`M-' disable the template). + +A template can be aborted by using the `C-g' or by lefting empty the +tempate prompt (in the minibuffer). + +6.1 Customization +================= + +`smarty-electric-mode' + Type: boolean + Default value: `t' + Description: If `t'; enable automatic generation of template. + If `nil'; template generators can still be invoked through key + bindings and menu. Is indicated in the modeline by \"/e\" after + the mode name and can be toggled by `smarty-electric-mode'. + +For a complete description of the template customizable variables, +see *Note Cu01-Pa01-Template:: + +6.2 Functions +============= + +6.2.1 Smarty Functions +---------------------- + +For Smarty functions, see PDF or HTML documentation. + +6.2.2 Non-Smarty Functions +-------------------------- + +`smarty-template-header' + Menu: Smarty -> Templates -> Insert Header + Keybinding: `C-c C-t C-h' + Description: This function is used to insert a header in the + current buffer. + +`smarty-template-footer' + Menu: Smarty -> Templates -> Insert Footer + Keybinding: `C-c C-t C-f' + Description: This function is used to insert a footer in the + current buffer. + +`smarty-template-insert-date' + Menu: Smarty -> Templates -> Insert Date + Keybinding: `C-c C-t C-d i' + Description: This function is used to insert the date in the + current buffer. + +`smarty-template-modify' + Menu: Smarty -> Templates -> Modify Date + Keybinding: `C-c C-t C-d m' + Description: This function is used to modify the last + modification date in the current buffer. + +7 Bugs, Help +************ + + * To report bugs: Bugtracker + (http://bugtracker.morinie.fr/lisp/set_project.php?project_id=2) + + * To obtain help you can post on the dedicated forum: Forum + (http://forum.morinie.fr/lisp/) + +8 Key bindings +************** + +\\{smarty-mode-map} + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (php-mode php-file-patterns php) "php-mode" "related/php-mode.el" +;;;;;; (19218 42180)) +;;; Generated autoloads from related/php-mode.el +(web-autoload-require 'php-mode 'lp '(nxhtml-download-root-url nil) "related/php-mode" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'php 'custom-loads))) (if (member '"php-mode" loads) nil (put 'php 'custom-loads (cons '"php-mode" loads)))) + +(defvar php-file-patterns '("\\.php[s34]?\\'" "\\.phtml\\'" "\\.inc\\'") "\ +List of file patterns for which to automatically invoke `php-mode'.") + +(nxhtml-custom-autoload 'php-file-patterns 'php-mode nil) + +(nxhtml-autoload 'php-mode `(lp '(nxhtml-download-root-url nil) "related/php-mode" nxhtml-install-dir) "\ +Major mode for editing PHP code. + +\\{php-mode-map} + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (global-mozadd-mirror-mode mozadd-mirror-mode global-mozadd-refresh-edited-on-save-mode +;;;;;; mozadd-refresh-edited-on-save-mode) "mozadd" "related/mozadd.el" +;;;;;; (19235 1650)) +;;; Generated autoloads from related/mozadd.el +(web-autoload-require 'mozadd 'lp '(nxhtml-download-root-url nil) "related/mozadd" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'mozadd-refresh-edited-on-save-mode `(lp '(nxhtml-download-root-url nil) "related/mozadd" nxhtml-install-dir) "\ +Refresh mozadd edited file in Firefox when saving file. +The mozadd edited file is the file in the last buffer visited in +`mozadd-mirror-mode'. + +You can use this for example when you edit CSS files. + +The mozadd edited file must be shown in Firefox and visible. + +\(fn &optional ARG)" t nil) + +(defvar global-mozadd-refresh-edited-on-save-mode nil "\ +Non-nil if Global-Mozadd-Refresh-Edited-On-Save mode is enabled. +See the command `global-mozadd-refresh-edited-on-save-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `global-mozadd-refresh-edited-on-save-mode'.") + +(nxhtml-custom-autoload 'global-mozadd-refresh-edited-on-save-mode 'mozadd nil) + +(nxhtml-autoload 'global-mozadd-refresh-edited-on-save-mode `(lp '(nxhtml-download-root-url nil) "related/mozadd" nxhtml-install-dir) "\ +Toggle Mozadd-Refresh-Edited-On-Save mode in every possible buffer. +With prefix ARG, turn Global-Mozadd-Refresh-Edited-On-Save mode on if and only if +ARG is positive. +Mozadd-Refresh-Edited-On-Save mode is enabled in all buffers where +`(lambda nil (when (or (derived-mode-p (quote css-mode)) (mozadd-html-buffer-file-p)) (mozadd-refresh-edited-on-save-mode 1)))' would do it. +See `mozadd-refresh-edited-on-save-mode' for more information on Mozadd-Refresh-Edited-On-Save mode. + +\(fn &optional ARG)" t nil) + +(nxhtml-autoload 'mozadd-mirror-mode `(lp '(nxhtml-download-root-url nil) "related/mozadd" nxhtml-install-dir) "\ +Mirror content of current file buffer immediately in Firefox. +When you turn on this mode the file will be opened in Firefox. +Every change you make in the buffer will trigger a redraw in +Firefox - regardless of if you save the file or not. + +For the mirroring to work the edited file must be shown in +Firefox and visible. + +If `nxml-where-mode' is on the marks will also be shown in +Firefox as CSS outline style. You can customize the style +through the option `mozadd-xml-path-outline-style'. + +See also `mozadd-refresh-edited-on-save-mode'. + +\(fn &optional ARG)" t nil) + +(defvar global-mozadd-mirror-mode nil "\ +Non-nil if Global-Mozadd-Mirror mode is enabled. +See the command `global-mozadd-mirror-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `global-mozadd-mirror-mode'.") + +(nxhtml-custom-autoload 'global-mozadd-mirror-mode 'mozadd nil) + +(nxhtml-autoload 'global-mozadd-mirror-mode `(lp '(nxhtml-download-root-url nil) "related/mozadd" nxhtml-install-dir) "\ +Toggle Mozadd-Mirror mode in every possible buffer. +With prefix ARG, turn Global-Mozadd-Mirror mode on if and only if +ARG is positive. +Mozadd-Mirror mode is enabled in all buffers where +`(lambda nil (when (mozadd-html-buffer-file-p) (mozadd-mirror-mode 1)))' would do it. +See `mozadd-mirror-mode' for more information on Mozadd-Mirror mode. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (inferior-moz-mode moz-minor-mode) "moz" "related/moz.el" +;;;;;; (19048 2102)) +;;; Generated autoloads from related/moz.el +(web-autoload-require 'moz 'lp '(nxhtml-download-root-url nil) "related/moz" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'moz-minor-mode `(lp '(nxhtml-download-root-url nil) "related/moz" nxhtml-install-dir) "\ +MozRepl minor mode for interaction with Firefox. +With no argument, this command toggles the mode. +Non-null prefix argument turns on the mode. +Null prefix argument turns off the mode. + +When this minor mode is enabled, some commands become available +to send current code area (as understood by c-mark-function) or +region or buffer to an inferior MozRepl process (which will be +started as needed). + +The following keys are bound in this minor mode: + +\\{moz-minor-mode-map} + +\(fn &optional ARG)" t nil) + +(nxhtml-autoload 'inferior-moz-mode `(lp '(nxhtml-download-root-url nil) "related/moz" nxhtml-install-dir) "\ +Major mode for interacting with Firefox via MozRepl. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (iss-mumamo-mode) "iss-mumamo" "related/iss-mumamo.el" +;;;;;; (19294 54042)) +;;; Generated autoloads from related/iss-mumamo.el +(web-autoload-require 'iss-mumamo 'lp '(nxhtml-download-root-url nil) "related/iss-mumamo" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'iss-mumamo-mode `(lp '(nxhtml-download-root-url nil) "related/iss-mumamo" nxhtml-install-dir) "\ +Turn on multiple major modes Inno Setup .iss files. +The main major mode will be `iss-mode'. +The [code] section, if any, will be in `pascal-mode'." t) + +;;;*** + +;;;### (autoloads (iss-mode) "iss-mode" "related/iss-mode.el" (19294 +;;;;;; 54042)) +;;; Generated autoloads from related/iss-mode.el +(web-autoload-require 'iss-mode 'lp '(nxhtml-download-root-url nil) "related/iss-mode" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'iss-mode `(lp '(nxhtml-download-root-url nil) "related/iss-mode" nxhtml-install-dir) "\ +Major mode for editing InnoSetup script files. Upon startup iss-mode-hook is run. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (flymake-js-load flymake-js) "flymake-js" "related/flymake-js.el" +;;;;;; (19218 42180)) +;;; Generated autoloads from related/flymake-js.el +(web-autoload-require 'flymake-js 'lp '(nxhtml-download-root-url nil) "related/flymake-js" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'flymake-js 'custom-loads))) (if (member '"flymake-js" loads) nil (put 'flymake-js 'custom-loads (cons '"flymake-js" loads)))) + +(nxhtml-autoload 'flymake-js-load `(lp '(nxhtml-download-root-url nil) "related/flymake-js" nxhtml-install-dir) "\ +Not documented + +\(fn)" nil nil) + +;;;*** + +;;;### (autoloads (flymake-java-1-load) "flymake-java-1" "related/flymake-java-1.el" +;;;;;; (19264 27004)) +;;; Generated autoloads from related/flymake-java-1.el +(web-autoload-require 'flymake-java-1 'lp '(nxhtml-download-root-url nil) "related/flymake-java-1" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'flymake-java-1-load `(lp '(nxhtml-download-root-url nil) "related/flymake-java-1" nxhtml-install-dir) "\ +Not documented + +\(fn)" nil nil) + +;;;*** + +;;;### (autoloads (flymake-css-load) "flymake-css" "related/flymake-css.el" +;;;;;; (19292 11678)) +;;; Generated autoloads from related/flymake-css.el +(web-autoload-require 'flymake-css 'lp '(nxhtml-download-root-url nil) "related/flymake-css" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'flymake-css-load `(lp '(nxhtml-download-root-url nil) "related/flymake-css" nxhtml-install-dir) "\ +Not documented + +\(fn)" nil nil) + +;;;*** + +;;;### (autoloads (django-mode) "django" "related/django.el" (19411 +;;;;;; 8520)) +;;; Generated autoloads from related/django.el +(web-autoload-require 'django 'lp '(nxhtml-download-root-url nil) "related/django" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'django-mode `(lp '(nxhtml-download-root-url nil) "related/django" nxhtml-install-dir) "\ +Simple Django mode for use with mumamo. +This mode only provides syntax highlighting. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (csharp-mode csharp-mode-hook) "csharp-mode" "related/csharp-mode.el" +;;;;;; (19410 9973)) +;;; Generated autoloads from related/csharp-mode.el +(web-autoload-require 'csharp-mode 'lp '(nxhtml-download-root-url nil) "related/csharp-mode" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(add-to-list 'auto-mode-alist '("\\.cs$" . csharp-mode)) + +(defvar csharp-mode-hook nil "\ +*Hook called by `csharp-mode'.") + +(nxhtml-custom-autoload 'csharp-mode-hook 'csharp-mode t) + +(nxhtml-autoload 'csharp-mode `(lp '(nxhtml-download-root-url nil) "related/csharp-mode" nxhtml-install-dir) "\ +Major mode for editing C# code. This mode is derived from CC Mode to +support C#. + +The hook `c-mode-common-hook' is run with no args at mode +initialization, then `csharp-mode-hook'. + +This mode will automatically add a regexp for Csc.exe error and warning +messages to the `compilation-error-regexp-alist'. + +Key bindings: +\\{csharp-mode-map} + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (winring-rename-configuration winring-delete-configuration +;;;;;; winring-jump-to-configuration winring-prev-configuration +;;;;;; winring-next-configuration winring-duplicate-configuration +;;;;;; winring-new-configuration) "winring" "util/winring.el" (19392 +;;;;;; 30980)) +;;; Generated autoloads from util/winring.el +(web-autoload-require 'winring 'lp '(nxhtml-download-root-url nil) "util/winring" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'winring-new-configuration `(lp '(nxhtml-download-root-url nil) "util/winring" nxhtml-install-dir) "\ +Save the current window configuration and create an empty new one. +The buffer shown in the new empty configuration is defined by +`winring-new-config-buffer-name'. + +With \\[universal-argument] prompt for the new configuration's name. +Otherwise, the function in `winring-name-generator' will be called to +get the new configuration's name. + +\(fn &optional ARG)" t nil) + +(nxhtml-autoload 'winring-duplicate-configuration `(lp '(nxhtml-download-root-url nil) "util/winring" nxhtml-install-dir) "\ +Push the current window configuration on the ring, and duplicate it. + +With \\[universal-argument] prompt for the new configuration's name. +Otherwise, the function in `winring-name-generator' will be called to +get the new configuration's name. + +\(fn &optional ARG)" t nil) + +(nxhtml-autoload 'winring-next-configuration `(lp '(nxhtml-download-root-url nil) "util/winring" nxhtml-install-dir) "\ +Switch to the next window configuration for this frame. + +\(fn)" t nil) + +(nxhtml-autoload 'winring-prev-configuration `(lp '(nxhtml-download-root-url nil) "util/winring" nxhtml-install-dir) "\ +Switch to the previous window configuration for this frame. + +\(fn)" t nil) + +(nxhtml-autoload 'winring-jump-to-configuration `(lp '(nxhtml-download-root-url nil) "util/winring" nxhtml-install-dir) "\ +Go to the named window configuration. + +\(fn)" t nil) + +(nxhtml-autoload 'winring-delete-configuration `(lp '(nxhtml-download-root-url nil) "util/winring" nxhtml-install-dir) "\ +Delete the current configuration and switch to the next one. +With \\[universal-argument] prompt for named configuration to delete. + +\(fn &optional ARG)" t nil) + +(nxhtml-autoload 'winring-rename-configuration `(lp '(nxhtml-download-root-url nil) "util/winring" nxhtml-install-dir) "\ +Rename the current configuration to NAME. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (winsav-switch-config winsav-save-full-config winsav-save-mode +;;;;;; winsav winsav-put-window-tree) "winsav" "util/winsav.el" +;;;;;; (19295 38082)) +;;; Generated autoloads from util/winsav.el +(web-autoload-require 'winsav 'lp '(nxhtml-download-root-url nil) "util/winsav" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'winsav-put-window-tree `(lp '(nxhtml-download-root-url nil) "util/winsav" nxhtml-install-dir) "\ +Put window structure SAVED-TREE into WINDOW. +Restore a structure SAVED-TREE returned from +`winsav-get-window-tree' into window WINDOW. + +If COPY-WIN-OVL is non-nil then overlays having a 'window +property pointing to one of the windows in SAVED-TREE where this +window still is shown will be copied to a new overlay with +'window property pointing to the corresponding new window. + +If WIN-OVL-ALL-BUFS is non-nil then all buffers will be searched +for overlays with a 'window property of the kind above. + +At the very end of this function the hook `winsav-after-put' is +run. + +\(fn SAVED-TREE WINDOW &optional COPY-WIN-OVL WIN-OVL-ALL-BUFS)" nil nil) + +(let ((loads (get 'winsav 'custom-loads))) (if (member '"winsav" loads) nil (put 'winsav 'custom-loads (cons '"winsav" loads)))) + +(defvar winsav-save-mode nil "\ +Non-nil if Winsav-Save mode is enabled. +See the command `winsav-save-mode' for a description of this minor mode.") + +(nxhtml-custom-autoload 'winsav-save-mode 'winsav nil) + +(nxhtml-autoload 'winsav-save-mode `(lp '(nxhtml-download-root-url nil) "util/winsav" nxhtml-install-dir) "\ +Toggle winsav configuration saving mode. +With numeric ARG, turn winsav saving on if ARG is positive, off +otherwise. + +When this mode is turned on, winsav configurations are saved from +one session to another. A winsav configuration consists of +frames, windows and visible buffers configurations plus +optionally buffers and files managed by the functions used by +option `desktop-save-mode' + +By default this is integrated with `desktop-save-mode'. If +`desktop-save-mode' is on and `winsav-handle-also-desktop' is +non-nil then save and restore also desktop. + +See the command `winsav-switch-config' for more information and +other possibilities. + +Note: If you want to avoid saving when you exit just turn off +this minor mode. + +For information about what is saved and restored and how to save +and restore additional information see the function +`winsav-save-configuration'. + +\(fn &optional ARG)" t nil) + +(nxhtml-autoload 'winsav-save-full-config `(lp '(nxhtml-download-root-url nil) "util/winsav" nxhtml-install-dir) "\ +Saved current winsav configuration in directory DIRNAME. +Then change to this configuration. + +See also `winsav-switch-config'. + +\(fn DIRNAME)" nil nil) + +(nxhtml-autoload 'winsav-switch-config `(lp '(nxhtml-download-root-url nil) "util/winsav" nxhtml-install-dir) "\ +Change to winsav configuration in directory DIRNAME. +If DIRNAME is the current winsav configuration directory then +offer to save it or restore it from saved values. + +Otherwise, before switching offer to save the current winsav +configuration. Then finally switch to the new winsav +configuration, creating it if it does not exist. + +If option `desktop-save-mode' is on then buffers and files are also +restored and saved the same way. + +See also option `winsav-save-mode' and command +`winsav-tell-configuration'. + +\(fn DIRNAME)" t nil) + +;;;*** + +;;;### (autoloads (winsav-rotate winsize-set-mode-line-colors winsize-save-window-configuration +;;;;;; winsize-balance-siblings resize-windows) "winsize" "util/winsize.el" +;;;;;; (19292 49706)) +;;; Generated autoloads from util/winsize.el +(web-autoload-require 'winsize 'lp '(nxhtml-download-root-url nil) "util/winsize" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'resize-windows `(lp '(nxhtml-download-root-url nil) "util/winsize" nxhtml-install-dir) "\ +Start window resizing. +During resizing a window is selected. You can move its +borders. In the default configuration the arrow keys moves the +right or bottom border if they are there. To move the opposite +border use S-arrowkeys. + +You can also do other window operations, like splitting, deleting +and balancing the sizes. The keybindings below describes the key +bindings during resizing:\\ + + `balance-windows' \\[balance-windows] + `winsize-balance-siblings' \\[winsize-balance-siblings] + `fit-window-to-buffer' \\[fit-window-to-buffer] + `shrink-window-if-larger-than-buffer' \\[shrink-window-if-larger-than-buffer] + + `winsav-rotate' \\[winsav-rotate] + + `winsize-move-border-up' \\[winsize-move-border-up] + `winsize-move-border-down' \\[winsize-move-border-down] + `winsize-move-border-left' \\[winsize-move-border-left] + `winsize-move-border-right' \\[winsize-move-border-right] + + `winsize-to-border-or-window-left' \\[winsize-to-border-or-window-left] + `winsize-to-border-or-window-up' \\[winsize-to-border-or-window-up] + `winsize-to-border-or-window-right' \\[winsize-to-border-or-window-right] + `winsize-to-border-or-window-down' \\[winsize-to-border-or-window-down] + + Note that you can also use your normal keys for + `forward-char', `backward-char', `next-line', `previous-line' + and what you have on HOME and END to move in the windows. That + might sometimes be necessary to directly select a + window. (You may however also use `other-window' or click + with the mouse, see below.) + + `delete-window' \\[delete-window] + `delete-other-windows' \\[delete-other-windows] + `split-window-vertically' \\[split-window-vertically] + `split-window-horizontally' \\[split-window-horizontally] + `other-window' \\[other-window] + + `winsize-save-window-configuration' \\[winsize-save-window-configuration] + `winsize-next-window-configuration' \\[winsize-next-window-configuration] + `winsize-previous-window-configuration' \\[winsize-previous-window-configuration] + + `mouse-set-point' \\[mouse-set-point] + + `winsize-quit' \\[winsize-quit] + `winsize-stop-go-back' \\[winsize-stop-go-back] + `winsize-stop' \\[winsize-stop] + `winsize-stop-and-execute' \\[winsize-stop-and-execute] + + `winsize-help' \\[winsize-help] + `describe-key' \\[describe-key] + `describe-key-briefly' \\[describe-key-briefly] + (All the normal help keys work, and at least those above will + play well with resizing.) + +Nearly all other keys exits window resizing and they are also +executed. However, the key sequences in `winsize-let-me-use' and +dito for commands there are also executed without exiting +resizing. + +The colors of the modelines are changed to those given in +`winsize-mode-line-colors' to indicate that you are resizing +windows. To make this indication more prominent the text in the +selected window is marked with the face hold in the variable +`winsize-selected-window-face'. + +The option `winsize-juris-way' decides how the borders to move +are selected. If this option is non-nil then the right or bottom +border are the ones that are moved with the arrow keys and the +opposite border with shift arrow keys. + +If `winsize-juris-way' is nil then the following apply: + +As you select other borders or move to new a window the mouse +pointer is moved inside the selected window to show which borders +are beeing moved. The mouse jumps a little bit to make its +position more visible. You can turn this off by customizing +`winsize-make-mouse-prominent'. + +Which borders initially are choosen are controlled by the +variable `winsize-autoselect-borders'. + +** Example: Border selection, movements and windows. + + Suppose you have a frame divided into windows like in the + figure below. If window B is selected when you start resizing + then (with default settings) the borders marked with 'v' and + 'h' will be the ones that the arrow keys moves. To indicate + this the mouse pointer is placed in the right lower corner of + the selected window B. + + +----------+-----------+--------+ + | | v | + | | v | + | A | _B_ v | + | | v | + | | v | + | | x v | + +hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh+ + | | | + | | | + | | | + | | | + | | | + | | | + +----------+---------+----------+ + + Now if you press M- then the picture below shows what has + happened. Note that the selected vertical border is now the one + between A and B. The mouse pointer has moved to the + corresponding corner in the window B, which is still selected. + + +----------+-----------+--------+ + | v | | + | v | | + | A v _B_ | | + | v | | + | v | | + | v x | | + +hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh+ + | | | + | | | + | | | + | | | + | | | + | | | + +----------+---------+----------+ + + Press M- once again. This gives this picture: + + +----------+-----------+--------+ + | v | | + | v | | + | _A_ v B | | + | v | | + | v | | + | x v | | + +hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh+ + | | | + | | | + | | | + | | | + | | | + | | | + +----------+---------+----------+ + + Note that the window A is now selected. However there is no + border that could be moved to the left of this window (which + would otherwise be chosen now) so the border between A and B is + still the one that and moves. The mouse has + moved to A. + + If we now delete window A the new situation will look like + this: + + +----------+-----------+--------+ + | | | + | | | + | _B_ | | + | | | + | | | + | x | | + +hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh+ + | | | + | | | + | | | + | | | + | | | + | | | + +----------+---------+----------+ + + + +>>>> testing stuff >>>> +`help-mode-hook' +`temp-buffer-show-function' +`view-exit-action' +<<<<<<<<<<<<<<<<<<<<<<< + +\(fn)" t nil) + +(nxhtml-autoload 'winsize-balance-siblings `(lp '(nxhtml-download-root-url nil) "util/winsize" nxhtml-install-dir) "\ +Make current window siblings the same height or width. +It works the same way as `balance-windows', but only for the +current window and its siblings. + +\(fn)" t nil) + +(nxhtml-autoload 'winsize-save-window-configuration `(lp '(nxhtml-download-root-url nil) "util/winsize" nxhtml-install-dir) "\ +Not documented + +\(fn)" t nil) + +(nxhtml-autoload 'winsize-set-mode-line-colors `(lp '(nxhtml-download-root-url nil) "util/winsize" nxhtml-install-dir) "\ +Turn mode line colors on if ON is non-nil, otherwise off. + +\(fn ON)" nil nil) + +(nxhtml-autoload 'winsav-rotate `(lp '(nxhtml-download-root-url nil) "util/winsize" nxhtml-install-dir) "\ +Rotate window configuration on selected frame. +MIRROR should be either 'mirror-left-right, 'mirror-top-bottom or +nil. In the first case the window configuration is mirrored +vertically and in the second case horizontally. If MIRROR is nil +the configuration is not mirrored. + +If TRANSPOSE is non-nil then the window structure is transposed +along the diagonal from top left to bottom right (in analogy with +matrix transosition). + +If called interactively MIRROR will is 'mirror-left-right by +default, but 'mirror-top-bottom if called with prefix. TRANSPOSE +is t. This mean that the window configuration will be turned one +quarter clockwise (or counter clockwise with prefix). + +\(fn MIRROR TRANSPOSE)" t nil) + +;;;*** + +;;;### (autoloads (wrap-to-fill-column-mode wrap-to-fill-left-marg-modes +;;;;;; wrap-to-fill-left-marg wrap-to-fill) "wrap-to-fill" "util/wrap-to-fill.el" +;;;;;; (19306 50510)) +;;; Generated autoloads from util/wrap-to-fill.el +(web-autoload-require 'wrap-to-fill 'lp '(nxhtml-download-root-url nil) "util/wrap-to-fill" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'wrap-to-fill 'custom-loads))) (if (member '"wrap-to-fill" loads) nil (put 'wrap-to-fill 'custom-loads (cons '"wrap-to-fill" loads)))) + +(defvar wrap-to-fill-left-marg nil "\ +Left margin handling for `wrap-to-fill-column-mode'. +Used by `wrap-to-fill-column-mode'. If nil then center the +display columns. Otherwise it should be a number which will be +the left margin.") + +(nxhtml-custom-autoload 'wrap-to-fill-left-marg 'wrap-to-fill t) + +(defvar wrap-to-fill-left-marg-modes '(text-mode fundamental-mode) "\ +Major modes where `wrap-to-fill-left-margin' may be nil.") + +(nxhtml-custom-autoload 'wrap-to-fill-left-marg-modes 'wrap-to-fill t) + +(nxhtml-autoload 'wrap-to-fill-column-mode `(lp '(nxhtml-download-root-url nil) "util/wrap-to-fill" nxhtml-install-dir) "\ +Use `fill-column' display columns in buffer windows. +By default the display columns are centered, but see the option +`wrap-to-fill-left-marg'. + +Fix-me: +Note 1: When turning this on `visual-line-mode' is also turned on. This +is not reset when turning off this mode. + +Note 2: The text properties 'wrap-prefix and 'wrap-to-fill-prefix +is set by this mode to indent continuation lines. + +Key bindings added by this minor mode: + +\\{wrap-to-fill-column-mode-map} + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (xhtml-help xhtml-help-show-tag-ref xhtml-help-tag-at-point +;;;;;; xhtml-help-show-css-ref) "xhtml-help" "nxhtml/xhtml-help.el" +;;;;;; (19364 56214)) +;;; Generated autoloads from nxhtml/xhtml-help.el +(web-autoload-require 'xhtml-help 'lp '(nxhtml-download-root-url nil) "nxhtml/xhtml-help" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'xhtml-help-show-css-ref `(lp '(nxhtml-download-root-url nil) "nxhtml/xhtml-help" nxhtml-install-dir) "\ +Show CSS reference for CSS property name at point. + +\(fn)" t nil) + +(nxhtml-autoload 'xhtml-help-tag-at-point `(lp '(nxhtml-download-root-url nil) "nxhtml/xhtml-help" nxhtml-install-dir) "\ +Get xhtml tag name at or before point. + +\(fn)" nil nil) + +(nxhtml-autoload 'xhtml-help-show-tag-ref `(lp '(nxhtml-download-root-url nil) "nxhtml/xhtml-help" nxhtml-install-dir) "\ +Show xhtml reference for tag name at or before point. + +\(fn)" t nil) + +(let ((loads (get 'xhtml-help 'custom-loads))) (if (member '"xhtml-help" loads) nil (put 'xhtml-help 'custom-loads (cons '"xhtml-help" loads)))) + +;;;*** + +;;;### (autoloads (tidy-build-menu tidy) "tidy-xhtml" "nxhtml/tidy-xhtml.el" +;;;;;; (19364 56214)) +;;; Generated autoloads from nxhtml/tidy-xhtml.el +(web-autoload-require 'tidy-xhtml 'lp '(nxhtml-download-root-url nil) "nxhtml/tidy-xhtml" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'tidy 'custom-loads))) (if (member '"tidy-xhtml" loads) nil (put 'tidy 'custom-loads (cons '"tidy-xhtml" loads)))) + +(nxhtml-autoload 'tidy-build-menu `(lp '(nxhtml-download-root-url nil) "nxhtml/tidy-xhtml" nxhtml-install-dir) "\ +Set up the tidy menu in MAP. +Used to set up a Tidy menu in your favourite mode. + +\(fn &optional MAP)" t nil) + +;;;*** + +;;;### (autoloads (rngalt-set-validation-header) "rngalt" "nxhtml/rngalt.el" +;;;;;; (19365 33760)) +;;; Generated autoloads from nxhtml/rngalt.el +(web-autoload-require 'rngalt 'lp '(nxhtml-download-root-url nil) "nxhtml/rngalt" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'rngalt-set-validation-header `(lp '(nxhtml-download-root-url nil) "nxhtml/rngalt" nxhtml-install-dir) "\ +Not documented + +\(fn START-OF-DOC)" nil nil) + +;;;*** + +;;;### (autoloads (nxml-where-global-mode nxml-where-mode nxml-where) +;;;;;; "nxml-where" "nxhtml/nxml-where.el" (19365 33760)) +;;; Generated autoloads from nxhtml/nxml-where.el +(web-autoload-require 'nxml-where 'lp '(nxhtml-download-root-url nil) "nxhtml/nxml-where" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'nxml-where 'custom-loads))) (if (member '"nxml-where" loads) nil (put 'nxml-where 'custom-loads (cons '"nxml-where" loads)))) + +(nxhtml-autoload 'nxml-where-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxml-where" nxhtml-install-dir) "\ +Shows path in mode line. + +\(fn &optional ARG)" t nil) + +(defvar nxml-where-global-mode nil "\ +Non-nil if Nxml-Where-Global mode is enabled. +See the command `nxml-where-global-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `nxml-where-global-mode'.") + +(nxhtml-custom-autoload 'nxml-where-global-mode 'nxml-where nil) + +(nxhtml-autoload 'nxml-where-global-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxml-where" nxhtml-install-dir) "\ +Toggle Nxml-Where mode in every possible buffer. +With prefix ARG, turn Nxml-Where-Global mode on if and only if +ARG is positive. +Nxml-Where mode is enabled in all buffers where +`nxml-where-turn-on-in-nxml-child' would do it. +See `nxml-where-mode' for more information on Nxml-Where mode. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (nxhtml-features-check nxhtml-customize nxhtml) +;;;;;; "nxhtml" "nxhtml/nxhtml.el" (19412 25954)) +;;; Generated autoloads from nxhtml/nxhtml.el +(web-autoload-require 'nxhtml 'lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'nxhtml 'custom-loads))) (if (member '"nxhtml" loads) nil (put 'nxhtml 'custom-loads (cons '"nxhtml" loads)))) + +(nxhtml-autoload 'nxhtml-customize `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml" nxhtml-install-dir) "\ +Customize nXhtml. + +\(fn)" t nil) + +(nxhtml-autoload 'nxhtml-features-check `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml" nxhtml-install-dir) "\ +Check if external modules used by nXhtml are found. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (mako-nxhtml-mumamo-mode asp-nxhtml-mumamo-mode +;;;;;; eruby-nxhtml-mumamo-mode jsp-nxhtml-mumamo-mode gsp-nxhtml-mumamo-mode +;;;;;; smarty-nxhtml-mumamo-mode mjt-nxhtml-mumamo-mode genshi-nxhtml-mumamo-mode +;;;;;; mason-nxhtml-mumamo-mode django-nxhtml-mumamo-mode embperl-nxhtml-mumamo-mode +;;;;;; nxhtml-mumamo-mode) "nxhtml-mumamo" "nxhtml/nxhtml-mumamo.el" +;;;;;; (19389 57826)) +;;; Generated autoloads from nxhtml/nxhtml-mumamo.el +(web-autoload-require 'nxhtml-mumamo 'lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\ +Turn on multiple major modes for (X)HTML with main mode `nxhtml-mode'. +This covers inlined style and javascript and PHP. + +See also `mumamo-alt-php-tags-mode'." t) + +(nxhtml-autoload 'embperl-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\ +Turn on multiple major modes for Embperl files with main mode `nxhtml-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'django-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\ +Turn on multiple major modes for Django with main mode `nxhtml-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'mason-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\ +Turn on multiple major modes for Mason using main mode `nxhtml-mode'. +This covers inlined style and javascript." t) + +(nxhtml-autoload 'genshi-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\ +Turn on multiple major modes for Genshi with main mode `nxhtml-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'mjt-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\ +Turn on multiple major modes for MJT with main mode `nxhtml-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'smarty-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\ +Turn on multiple major modes for Smarty with main mode `nxhtml-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'gsp-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\ +Turn on multiple major modes for GSP with main mode `nxhtml-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'jsp-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\ +Turn on multiple major modes for JSP with main mode `nxhtml-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'eruby-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\ +Turn on multiple major modes for eRuby with main mode `nxhtml-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'asp-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\ +Turn on multiple major modes for ASP with main mode `nxhtml-mode'. +This also covers inlined style and javascript." t) + +(nxhtml-autoload 'mako-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\ +Turn on multiple major modes for Mako with main mode `nxhtml-mode'. +This also covers inlined style and javascript." t) + +;;;*** + +;;;### (autoloads (nxhtml-validation-header-mode nxhtml-short-tag-help +;;;;;; nxhtml-mode) "nxhtml-mode" "nxhtml/nxhtml-mode.el" (19412 +;;;;;; 25947)) +;;; Generated autoloads from nxhtml/nxhtml-mode.el +(web-autoload-require 'nxhtml-mode 'lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mode" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(when (fboundp 'nxml-mode) +(nxhtml-autoload 'nxhtml-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mode" nxhtml-install-dir) "\ +Major mode for editing XHTML documents. +It is based on `nxml-mode' and adds some features that are useful +when editing XHTML files.\\ + +To see an overview in html format do \\[nxhtml-overview]. + +* Note: Please observe that when loading nXhtml some file + associations are done, see `nxhtml-setup-file-assoc'. + +The nXhtml menu is added by this mode (or actually the minor +mode `nxhtml-menu-mode') and gives quick access and an overview +of some other important features. These includes: + +- multiple major modes, see `define-mumamo-multi-major-mode' +- easy uploading and viewing of files, see for example + `html-upl-upload-file' +- validation in XHTML part for php etc, see + `nxhtml-validation-header-mode' (you probably also want to know about + `nxhtml-toggle-visible-warnings' for this!) +- converting of html to xhtml, see `tidy-buffer' + +The XML menu contains functionality added by `nxml-mode' (on +which this major mode is based). There is also a popup menu +added to the [apps] key. + +The most important features are probably completion and +validation, which is inherited from `nxml-mode' with some small +addtions. In very many situation you can use completion. To +access it type \\[nxml-complete]. Completion has been enhanced in +the following way: + +- If region is active and visible then completion will surround the + region with the chosen tag's start and end tag. However only the + starting point is checked for validity. If something is wrong after + insertion you will however immediately see it if you have validation + on. +- It can in some cases give assistance with attribute values. +- Completion can be customized, see the menus XHTML - Completion: + * You can use a menu popup style completion. + * You can have alternatives grouped. + * You can get a short help text shown for each alternative. +- There does not have to be a '<' before point for tag name + completion. (`nxml-mode' requires a '<' before point for tag name + completion.) +- Completes xml version and encoding. +- Completes in an empty buffer, ie inserts a skeleton. + +Some smaller, useful, but easy-to-miss features: + +* Following links. The href and src attribute names are + underlined and a special keymap is bound to + them:\\ + + \\[mlinks-backward-link], \\[mlinks-forward-link] Move + between underlined href/src attributes + + \\[mlinks-goto], Mouse-1 Follow link inside Emacs + (if possible) + + It is even a little bit quicker when the links are in an active + state (marked with the face `isearch'):\\ + + \\[mlinks-backward-link], \\[mlinks-forward-link] Move + between underlined href/src attributes + \\[mlinks-goto], Mouse-1 Follow link inside Emacs (if possible) + + If the link is not into a file that you can edit (a mailto link + for example) you will be prompted for an alternative action. + +* Creating links. To make it easier to create links to id/name + attribute in different files there are two special + functions:\\ + + \\[nxhtml-save-link-to-here] copy link to id/name (you must + be in the tag to get the link) + \\[nxhtml-paste-link-as-a-tag] paste this as an a-tag. + +Here are all key bindings in nxhtml-mode itself: + +\\{nxhtml-mode-map} + +The minor mode `nxhtml-menu-mode' adds some bindings: + +\\{nxhtml-menu-mode-map} + +Notice that other minor mode key bindings may also be active, as +well as emulation modes. Do \\[describe-bindings] to get a list +of all active key bindings. Also, *VERY IMPORTANT*, if mumamo is +used in the buffer each mumamo chunk has a different major mode +with different key bindings. You can however still see all +bindings with \\[describe-bindings], but you have to do that with +point in the mumamo chunk you want to know the key bindings in. + +--------- +* Note: Some of the features supported by this mode are optional + and available only if other Emacs modules are found. Use + \\[nxhtml-features-check] to get a list of these optional + features and modules needed. You should however have no problem + with this if you have followed the installation instructions + for nXhtml. + +\(fn)" t nil)) + +(nxhtml-autoload 'nxhtml-short-tag-help `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mode" nxhtml-install-dir) "\ +Display description of tag TAG. If TAG is omitted, try tag at point. + +\(fn TAG)" t nil) + +(when (fboundp 'nxml-mode) +(nxhtml-autoload 'nxhtml-validation-header-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mode" nxhtml-install-dir) "\ +If on use a Fictive XHTML Validation Header for the buffer. +See `nxhtml-set-validation-header' for information about Fictive XHTML Validation Headers. + +This mode may be turned on automatically in two ways: +- If you try to do completion of a XHTML tag or attribute then + `nxthml-mode' may ask you if you want to turn this mode on if + needed. +- You can also choose to have it turned on automatically whenever + a mumamo multi major mode is used, see + `nxhtml-validation-header-if-mumamo' for further information. + +\(fn &optional ARG)" t nil)) + +;;;*** + +;;;### (autoloads (nxhtml-overview nxhtml-menu-mode nxhtml-browse-region +;;;;;; nxhtml-browse-file nxhtml-edit-with-gimp) "nxhtml-menu" "nxhtml/nxhtml-menu.el" +;;;;;; (19412 26360)) +;;; Generated autoloads from nxhtml/nxhtml-menu.el +(web-autoload-require 'nxhtml-menu 'lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-menu" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'nxhtml-edit-with-gimp `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-menu" nxhtml-install-dir) "\ +Edit with GIMP buffer or file at point. + +\(fn)" t nil) + +(nxhtml-autoload 'nxhtml-browse-file `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-menu" nxhtml-install-dir) "\ +View file in web browser. + +\(fn FILE)" t nil) + +(nxhtml-autoload 'nxhtml-browse-region `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-menu" nxhtml-install-dir) "\ +View region in web browser. + +\(fn)" t nil) + +(defvar nxhtml-menu-mode nil "\ +Non-nil if Nxhtml-Menu mode is enabled. +See the command `nxhtml-menu-mode' for a description of this minor mode.") + +(nxhtml-custom-autoload 'nxhtml-menu-mode 'nxhtml-menu nil) + +(nxhtml-autoload 'nxhtml-menu-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-menu" nxhtml-install-dir) "\ +Minor mode to turn on some key and menu bindings. +See `nxhtml-mode' for more information. + +\(fn &optional ARG)" t nil) + +(nxhtml-autoload 'nxhtml-overview `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-menu" nxhtml-install-dir) "\ +Show a HTML page with an overview of nXhtml. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (nxhtml-report-bug) "nxhtml-bug" "nxhtml/nxhtml-bug.el" +;;;;;; (19277 65354)) +;;; Generated autoloads from nxhtml/nxhtml-bug.el +(web-autoload-require 'nxhtml-bug 'lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-bug" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'nxhtml-report-bug `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-bug" nxhtml-install-dir) "\ +Report a bug in nXhtml. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (html-wtoc) "html-wtoc" "nxhtml/html-wtoc.el" (19364 +;;;;;; 56214)) +;;; Generated autoloads from nxhtml/html-wtoc.el +(web-autoload-require 'html-wtoc 'lp '(nxhtml-download-root-url nil) "nxhtml/html-wtoc" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'html-wtoc 'custom-loads))) (if (member '"html-wtoc" loads) nil (put 'html-wtoc 'custom-loads (cons '"html-wtoc" loads)))) + +;;;*** + +;;;### (autoloads (html-upl-ediff-file html-upl-edit-remote-file-with-toc +;;;;;; html-upl-edit-remote-file html-upl-upload-file html-upl-remote-dired +;;;;;; html-upl-upload-site html-upl-upload-site-with-toc html-upl) +;;;;;; "html-upl" "nxhtml/html-upl.el" (19364 56214)) +;;; Generated autoloads from nxhtml/html-upl.el +(web-autoload-require 'html-upl 'lp '(nxhtml-download-root-url nil) "nxhtml/html-upl" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'html-upl 'custom-loads))) (if (member '"html-upl" loads) nil (put 'html-upl 'custom-loads (cons '"html-upl" loads)))) + +(nxhtml-autoload 'html-upl-upload-site-with-toc `(lp '(nxhtml-download-root-url nil) "nxhtml/html-upl" nxhtml-install-dir) "\ +Not documented + +\(fn)" t nil) + +(nxhtml-autoload 'html-upl-upload-site `(lp '(nxhtml-download-root-url nil) "nxhtml/html-upl" nxhtml-install-dir) "\ +Not documented + +\(fn)" t nil) + +(nxhtml-autoload 'html-upl-remote-dired `(lp '(nxhtml-download-root-url nil) "nxhtml/html-upl" nxhtml-install-dir) "\ +Start dired for remote directory or its parent/ancestor. + +\(fn DIRNAME)" t nil) + +(nxhtml-autoload 'html-upl-upload-file `(lp '(nxhtml-download-root-url nil) "nxhtml/html-upl" nxhtml-install-dir) "\ +Upload a single file in a site. +For the definition of a site see `html-site-current'. + +\(fn FILENAME)" t nil) + +(nxhtml-autoload 'html-upl-edit-remote-file `(lp '(nxhtml-download-root-url nil) "nxhtml/html-upl" nxhtml-install-dir) "\ +Not documented + +\(fn)" t nil) + +(nxhtml-autoload 'html-upl-edit-remote-file-with-toc `(lp '(nxhtml-download-root-url nil) "nxhtml/html-upl" nxhtml-install-dir) "\ +Not documented + +\(fn)" t nil) + +(nxhtml-autoload 'html-upl-ediff-file `(lp '(nxhtml-download-root-url nil) "nxhtml/html-upl" nxhtml-install-dir) "\ +Run ediff on local and remote file. +FILENAME could be either the remote or the local file. + +\(fn FILENAME)" t nil) + +;;;*** + +;;;### (autoloads (html-toc) "html-toc" "nxhtml/html-toc.el" (19364 +;;;;;; 56214)) +;;; Generated autoloads from nxhtml/html-toc.el +(web-autoload-require 'html-toc 'lp '(nxhtml-download-root-url nil) "nxhtml/html-toc" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'html-toc 'custom-loads))) (if (member '"html-toc" loads) nil (put 'html-toc 'custom-loads (cons '"html-toc" loads)))) + +(defconst html-toc-menu-map (let ((map (make-sparse-keymap))) (define-key map [html-toc-browse-frames-file] (list 'menu-item "Browse Frames File" 'html-toc-browse-frames-file)) (define-key map [html-toc-write-frames-file] (list 'menu-item "Write Frames File" 'html-toc-write-frames-file)) (define-key map [html-toc-write-toc-file] (list 'menu-item "Write TOC File for Frames" 'html-toc-write-toc-file)) (define-key map [html-toc-sep1] (list 'menu-item "--")) (define-key map [html-toc-edit-pages-file] (list 'menu-item "Edit List of Pages for TOC" 'html-site-edit-pages-file)) (define-key map [html-toc-create-pages-file] (list 'menu-item "Write List of Pages for TOC" 'html-toc-create-pages-file)) map)) + +;;;*** + +;;;### (autoloads (html-site-query-replace html-site-rgrep html-site-find-file +;;;;;; html-site-dired-current html-site-set-site html-site-buffer-or-dired-file-name +;;;;;; html-site) "html-site" "nxhtml/html-site.el" (19364 56214)) +;;; Generated autoloads from nxhtml/html-site.el +(web-autoload-require 'html-site 'lp '(nxhtml-download-root-url nil) "nxhtml/html-site" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'html-site 'custom-loads))) (if (member '"html-site" loads) nil (put 'html-site 'custom-loads (cons '"html-site" loads)))) + +(nxhtml-autoload 'html-site-buffer-or-dired-file-name `(lp '(nxhtml-download-root-url nil) "nxhtml/html-site" nxhtml-install-dir) "\ +Return buffer file name or file pointed to in dired. + +\(fn)" nil nil) + +(nxhtml-autoload 'html-site-set-site `(lp '(nxhtml-download-root-url nil) "nxhtml/html-site" nxhtml-install-dir) "\ +Not documented + +\(fn NAME)" t nil) + +(nxhtml-autoload 'html-site-dired-current `(lp '(nxhtml-download-root-url nil) "nxhtml/html-site" nxhtml-install-dir) "\ +Open `dired' in current site top directory. + +\(fn)" t nil) + +(nxhtml-autoload 'html-site-find-file `(lp '(nxhtml-download-root-url nil) "nxhtml/html-site" nxhtml-install-dir) "\ +Find file in current site. + +\(fn)" t nil) + +(nxhtml-autoload 'html-site-rgrep `(lp '(nxhtml-download-root-url nil) "nxhtml/html-site" nxhtml-install-dir) "\ +Search current site's files with `rgrep'. +See `rgrep' for the arguments REGEXP and FILES. + +\(fn REGEXP FILES)" t nil) + +(nxhtml-autoload 'html-site-query-replace `(lp '(nxhtml-download-root-url nil) "nxhtml/html-site" nxhtml-install-dir) "\ +Query replace in current site's files. + +\(fn FROM TO FILE-REGEXP DELIMITED)" t nil) + +;;;*** + +;;;### (autoloads (html-pagetoc-rebuild-toc html-pagetoc-insert-toc +;;;;;; html-pagetoc) "html-pagetoc" "nxhtml/html-pagetoc.el" (19364 +;;;;;; 56214)) +;;; Generated autoloads from nxhtml/html-pagetoc.el +(web-autoload-require 'html-pagetoc 'lp '(nxhtml-download-root-url nil) "nxhtml/html-pagetoc" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'html-pagetoc 'custom-loads))) (if (member '"html-pagetoc" loads) nil (put 'html-pagetoc 'custom-loads (cons '"html-pagetoc" loads)))) + +(nxhtml-autoload 'html-pagetoc-insert-toc `(lp '(nxhtml-download-root-url nil) "nxhtml/html-pagetoc" nxhtml-install-dir) "\ +Inserts a table of contents for the current html file. +The html header tags h1-h6 found in the file are inserted into +this table. MIN-LEVEL and MAX-LEVEL specifies the minimum and +maximum level of h1-h6 to include. They should be integers. + +\(fn &optional MIN-LEVEL MAX-LEVEL)" t nil) + +(nxhtml-autoload 'html-pagetoc-rebuild-toc `(lp '(nxhtml-download-root-url nil) "nxhtml/html-pagetoc" nxhtml-install-dir) "\ +Update the table of contents inserted by `html-pagetoc-insert-toc'. + +\(fn)" t nil) + +(defconst html-pagetoc-menu-map (let ((map (make-sparse-keymap))) (define-key map [html-pagetoc-rebuild-toc] (list 'menu-item "Update Page TOC" 'html-pagetoc-rebuild-toc)) (define-key map [html-pagetoc-insert-style-guide] (list 'menu-item "Insert CSS Style for Page TOC" 'html-pagetoc-insert-style-guide)) (define-key map [html-pagetoc-insert-toc] (list 'menu-item "Insert Page TOC" 'html-pagetoc-insert-toc)) map)) + +;;;*** + +;;;### (autoloads (html-chklnk) "html-chklnk" "nxhtml/html-chklnk.el" +;;;;;; (19364 56214)) +;;; Generated autoloads from nxhtml/html-chklnk.el +(web-autoload-require 'html-chklnk 'lp '(nxhtml-download-root-url nil) "nxhtml/html-chklnk" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'html-chklnk 'custom-loads))) (if (member '"html-chklnk" loads) nil (put 'html-chklnk 'custom-loads (cons '"html-chklnk" loads)))) + +;;;*** + +;;;### (autoloads (web-vcs-investigate-elisp-file web-vcs-byte-compile-file +;;;;;; web-vcs-message-with-face web-vcs-get-files-from-root web-vcs-log-edit +;;;;;; web-vcs-default-download-directory) "web-vcs" "web-vcs.el" +;;;;;; (19412 16397)) +;;; Generated autoloads from web-vcs.el +(web-autoload-require 'web-vcs 'lp '(nxhtml-download-root-url nil) "web-vcs" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'web-vcs-default-download-directory `(lp '(nxhtml-download-root-url nil) "web-vcs" nxhtml-install-dir) "\ +Try to find a suitable place. +Considers site-start.el, site- + +\(fn)" nil nil) + +(nxhtml-autoload 'web-vcs-log-edit `(lp '(nxhtml-download-root-url nil) "web-vcs" nxhtml-install-dir) "\ +Open log file. + +\(fn)" t nil) + +(nxhtml-autoload 'web-vcs-get-files-from-root `(lp '(nxhtml-download-root-url nil) "web-vcs" nxhtml-install-dir) "\ +Download a file tree from VCS system using the web interface. +Use WEB-VCS entry in variable `web-vcs-links-regexp' to download +files via http from URL to directory DL-DIR. + +Show URL first and offer to visit the page. That page will give +you information about version control system (VCS) system used +etc. + +\(fn WEB-VCS URL DL-DIR)" nil nil) + +(nxhtml-autoload 'web-vcs-message-with-face `(lp '(nxhtml-download-root-url nil) "web-vcs" nxhtml-install-dir) "\ +Display a colored message at the bottom of the string. +FACE is the face to use for the message. +FORMAT-STRING and ARGS are the same as for `message'. + +Also put FACE on the message in *Messages* buffer. + +\(fn FACE FORMAT-STRING &rest ARGS)" nil nil) + +(nxhtml-autoload 'web-vcs-byte-compile-file `(lp '(nxhtml-download-root-url nil) "web-vcs" nxhtml-install-dir) "\ +Byte compile FILE in a new Emacs sub process. +EXTRA-LOAD-PATH is added to the front of `load-path' during +compilation. + +FILE is set to `buffer-file-name' when called interactively. +If LOAD + +\(fn FILE &optional LOAD EXTRA-LOAD-PATH COMP-DIR)" t nil) + +(nxhtml-autoload 'web-vcs-investigate-elisp-file `(lp '(nxhtml-download-root-url nil) "web-vcs" nxhtml-install-dir) "\ +Not documented + +\(fn FILE-OR-BUFFER)" t nil) + +;;;*** + +;;;### (autoloads (nxhtmlmaint-byte-uncompile-all nxhtmlmaint-byte-recompile +;;;;;; nxhtmlmaint-start-byte-compilation) "nxhtmlmaint" "nxhtmlmaint.el" +;;;;;; (19378 31293)) +;;; Generated autoloads from nxhtmlmaint.el +(web-autoload-require 'nxhtmlmaint 'lp '(nxhtml-download-root-url nil) "nxhtmlmaint" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'nxhtmlmaint-start-byte-compilation `(lp '(nxhtml-download-root-url nil) "nxhtmlmaint" nxhtml-install-dir) "\ +Start byte compilation of nXhtml in new Emacs instance. +Byte compiling in general makes elisp code run 5-10 times faster +which is quite noticeable when you use nXhtml. + +This will also update the file nxhtml-loaddefs.el. + +You must restart Emacs to use the byte compiled files. + +If for some reason the byte compiled files does not work you can +remove then with `nxhtmlmaint-byte-uncompile-all'. + +\(fn)" t nil) + +(nxhtml-autoload 'nxhtmlmaint-byte-recompile `(lp '(nxhtml-download-root-url nil) "nxhtmlmaint" nxhtml-install-dir) "\ +Recompile or compile all nXhtml files in current Emacs. + +\(fn)" t nil) + +(nxhtml-autoload 'nxhtmlmaint-byte-uncompile-all `(lp '(nxhtml-download-root-url nil) "nxhtmlmaint" nxhtml-install-dir) "\ +Delete byte compiled files in nXhtml. +This will also update the file nxhtml-loaddefs.el. + +See `nxhtmlmaint-start-byte-compilation' for byte compiling. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (zencoding-preview zencoding-expand-yas zencoding-mode +;;;;;; zencoding-expand-line zencoding) "zencoding-mode" "util/zencoding-mode.el" +;;;;;; (19275 63380)) +;;; Generated autoloads from util/zencoding-mode.el +(web-autoload-require 'zencoding-mode 'lp '(nxhtml-download-root-url nil) "util/zencoding-mode" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(let ((loads (get 'zencoding 'custom-loads))) (if (member '"zencoding-mode" loads) nil (put 'zencoding 'custom-loads (cons '"zencoding-mode" loads)))) + +(nxhtml-autoload 'zencoding-expand-line `(lp '(nxhtml-download-root-url nil) "util/zencoding-mode" nxhtml-install-dir) "\ +Replace the current line's zencode expression with the corresponding expansion. +If prefix ARG is given or region is visible call `zencoding-preview' to start an +interactive preview. + +Otherwise expand line directly. + +For more information see `zencoding-mode'. + +\(fn ARG)" t nil) + +(nxhtml-autoload 'zencoding-mode `(lp '(nxhtml-download-root-url nil) "util/zencoding-mode" nxhtml-install-dir) "\ +Minor mode for writing HTML and CSS markup. +With zen coding for HTML and CSS you can write a line like + + ul#name>li.item*2 + +and have it expanded to + +
    +
  • +
  • +
+ +This minor mode defines keys for quick access: + +\\{zencoding-mode-keymap} + +Home page URL `http://www.emacswiki.org/emacs/ZenCoding'. + +See also `zencoding-expand-line'. + +\(fn &optional ARG)" t nil) + +(nxhtml-autoload 'zencoding-expand-yas `(lp '(nxhtml-download-root-url nil) "util/zencoding-mode" nxhtml-install-dir) "\ +Not documented + +\(fn)" t nil) + +(nxhtml-autoload 'zencoding-preview `(lp '(nxhtml-download-root-url nil) "util/zencoding-mode" nxhtml-install-dir) "\ +Expand zencode between BEG and END interactively. +This will show a preview of the expanded zen code and you can +accept it or skip it. + +\(fn BEG END)" t nil) + +;;;*** + +;;;### (autoloads nil nil ("autostart.el" "autostart22.el" "etc/schema/schema-path-patch.el" +;;;;;; "nxhtml-base.el" "nxhtml/html-imenu.el" "nxhtml/html-move.el" +;;;;;; "nxhtml/html-quote.el" "nxhtml/nxhtml-autoload.el" "nxhtml/nxhtml-strval.el" +;;;;;; "nxhtml/nxhtmljs.el" "nxhtml/outline-magic.el" "nxhtml/wtest.el" +;;;;;; "related/flymake-helpers.el" "related/flymakemsg.el" "related/flymu.el" +;;;;;; "related/php-imenu.el" "tests/angus77-setup-jde.el" "tests/emacstest-suites.el" +;;;;;; "tests/ert2.el" "tests/hfy-test.el" "tests/inemacs/bug1013.el" +;;;;;; "tests/mumamo-test.el" "tests/nxhtmltest-helpers.el" "tests/temp-test.el" +;;;;;; "util/appmenu-fold.el" "util/css-simple-completion.el" "util/custsets.el" +;;;;;; "util/ecb-batch-compile.el" "util/fupd.el" "util/idn.el" +;;;;;; "util/key-cat.el" "util/mumamo-aspnet.el" "util/mumamo-trace.el" +;;;;;; "util/new-key-seq-widget.el" "util/nxml-mode-os-additions.el" +;;;;;; "util/org-panel.el" "util/rxi.el" "util/useful-commands.el" +;;;;;; "web-autoload.el") (19412 26385 593000)) + +;;;*** + +;;;### (autoloads (nxhtml-byte-recompile-file nxhtml-byte-compile-file +;;;;;; nxhtml-get-missing-files nxhtml-update-existing-files nxhtml-setup-download-all +;;;;;; nxhtml-setup-auto-download nxhtml-setup-install) "nxhtml-web-vcs" +;;;;;; "nxhtml-web-vcs.el" (19412 16464)) +;;; Generated autoloads from nxhtml-web-vcs.el +(web-autoload-require 'nxhtml-web-vcs 'lp '(nxhtml-download-root-url nil) "nxhtml-web-vcs" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'nxhtml-setup-install `(lp '(nxhtml-download-root-url nil) "nxhtml-web-vcs" nxhtml-install-dir) "\ +Setup and start nXhtml installation. + +This is for installation and updating directly from the nXhtml +development sources. + +There are two different ways to install: + + (1) Download all at once: `nxhtml-setup-download-all' + (2) Automatically download part by part: `nxhtml-setup-auto-download' + +You can convert between those ways by calling this function again. +You can also do this by setting the option `nxhtml-autoload-web' yourself. + +When you have nXhtml installed you can update it: + + (3) Update new files in nXhtml: `nxhtml-update-existing-files' + +To learn more about nXhtml visit its home page at URL +`http://www.emacswiki.com/NxhtmlMode/'. + +If you want to test auto download (but not use it further) there +is a special function for that, you answer T here: + + (T) Test automatic download part by part: `nxhtml-setup-test-auto-download' + +====== +*Note* +If you want to download a zip file with latest released version instead then +please see URL `http://ourcomments.org/Emacs/nXhtml/doc/nxhtml.html'. + +\(fn WAY)" t nil) + +(nxhtml-autoload 'nxhtml-setup-auto-download `(lp '(nxhtml-download-root-url nil) "nxhtml-web-vcs" nxhtml-install-dir) "\ +Set up to autoload nXhtml files from the web. + +This function will download some initial files and then setup to +download the rest when you need them. + +Files will be downloaded under the directory root you specify in +DL-DIR. + +Note that files will not be upgraded automatically. The auto +downloading is just for files you are missing. (This may change a +bit in the future.) If you want to upgrade those files that you +have downloaded you can just call `nxhtml-update-existing-files'. + +You can easily switch between this mode of downloading or +downloading the whole of nXhtml by once. To switch just call the +command `nxhtml-setup-install'. + +See also the command `nxhtml-setup-download-all'. + +Note: If your nXhtml is to old you can't use this function + directly. You have to upgrade first, se the function + above. Version 2.07 or above is good for this. + +\(fn DL-DIR)" t nil) + +(nxhtml-autoload 'nxhtml-setup-download-all `(lp '(nxhtml-download-root-url nil) "nxhtml-web-vcs" nxhtml-install-dir) "\ +Download or update all of nXhtml. + +You can download all if nXhtml with this command. + +To update existing files use `nxhtml-update-existing-files'. + +If you want to download only those files you are actually using +then call `nxhtml-setup-auto-download' instead. + +See the command `nxhtml-setup-install' for a convenient way to +call these commands. + +For more information about auto download of nXhtml files see +`nxhtml-setup-auto-download'. + +\(fn DL-DIR)" t nil) + +(nxhtml-autoload 'nxhtml-update-existing-files `(lp '(nxhtml-download-root-url nil) "nxhtml-web-vcs" nxhtml-install-dir) "\ +Update existing nXhtml files from the development sources. +Only files you already have will be updated. + +Note that this works both if you have setup nXhtml to auto +download files as you need them or if you have downloaded all of +nXhtml at once. + +For more information about installing and updating nXhtml see the +command `nxhtml-setup-install'. + +\(fn)" t nil) + +(nxhtml-autoload 'nxhtml-get-missing-files `(lp '(nxhtml-download-root-url nil) "nxhtml-web-vcs" nxhtml-install-dir) "\ +Not documented + +\(fn SUB-DIR FILE-NAME-LIST)" nil nil) + +(nxhtml-autoload 'nxhtml-byte-compile-file `(lp '(nxhtml-download-root-url nil) "nxhtml-web-vcs" nxhtml-install-dir) "\ +Not documented + +\(fn FILE &optional LOAD)" nil nil) + +(nxhtml-autoload 'nxhtml-byte-recompile-file `(lp '(nxhtml-download-root-url nil) "nxhtml-web-vcs" nxhtml-install-dir) "\ +Byte recompile FILE file if necessary. +For more information see `nxhtml-byte-compile-file'. +Loading is done if recompiled and LOAD is t. + +\(fn FILE &optional LOAD)" t nil) + +;;;*** diff --git a/emacs/nxhtml/nxhtml-web-vcs.el b/emacs/nxhtml/nxhtml-web-vcs.el new file mode 100644 index 0000000..fb0fb09 --- /dev/null +++ b/emacs/nxhtml/nxhtml-web-vcs.el @@ -0,0 +1,689 @@ +;;; nxhtml-web-vcs.el --- nXhtml things for web-vcs.el +;; +;; Author: Lennart Borgman (lennart O borgman A gmail O com) +;; Created: 2010-01-13 Wed +;; Version: +;; Last-Updated: +;; URL: +;; Keywords: +;; Compatibility: +;; +;; Features that might be required by this library: +;; +;; None +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 3, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile (require 'cl)) +(eval-when-compile (require 'nxhtml-base nil t)) +;;(eval-when-compile (require 'nxhtmlmaint nil t)) +(eval-when-compile (require 'web-vcs nil t)) + +(defvar nxhtml-web-vcs-file (or load-file-name + (when (boundp 'bytecomp-filename) bytecomp-filename) + buffer-file-name) + "This file.") + +(defun nxhtml-require-base () + (require 'nxhtml-base nil t) + (unless (featurep 'nxhtml-base) + ;; At startup, need to load it by hand. + (let ((load-path load-path)) + (add-to-list 'load-path (file-name-directory nxhtml-web-vcs-file)) + (require 'nxhtml-base)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Repository URL + + +;;(nxhtml-default-download-directory) +(defun nxhtml-default-download-directory () + (let* ((ur (expand-file-name "" "~")) + (ur-len (length ur)) + (full (if (and (boundp 'nxhtml-install-dir) + nxhtml-install-dir) + nxhtml-install-dir + (file-name-as-directory + (expand-file-name "" + (web-vcs-default-download-directory))))) + (full-len (length full))) + (if (and (> full-len ur-len) + (string= ur (substring full 0 ur-len))) + (concat "~" (substring full ur-len)) + full))) + + +(defun nxhtml-web-vcs-read-dl-dir (prompt) + "Return current nXhtml install dir or read dir." + (or (and (boundp 'nxhtml-install-dir) + nxhtml-install-dir) + (let* ((pr (concat + "A directory named 'nxhtml' will be created below the root you give." + "\n" + prompt)) + (root (read-directory-name pr (nxhtml-default-download-directory)))) + (when root + (expand-file-name "nxhtml" root))))) + +;;(call-interactively 'nxhtml-setup-install) +;; (read-key "Prompt: ") +;; (y-or-n-p "Prompt") +;;;###autoload +(defun nxhtml-setup-install (way) + "Setup and start nXhtml installation. + +This is for installation and updating directly from the nXhtml +development sources. + +There are two different ways to install: + + (1) Download all at once: `nxhtml-setup-download-all' + (2) Automatically download part by part: `nxhtml-setup-auto-download' + +You can convert between those ways by calling this function again. +You can also do this by setting the option `nxhtml-autoload-web' yourself. + +When you have nXhtml installed you can update it: + + (3) Update new files in nXhtml: `nxhtml-update-existing-files' + +To learn more about nXhtml visit its home page at URL +`http://www.emacswiki.com/NxhtmlMode/'. + +If you want to test auto download \(but not use it further) there +is a special function for that, you answer T here: + + (T) Test automatic download part by part: `nxhtml-setup-test-auto-download' + +====== +*Note* +If you want to download a zip file with latest released version instead then +please see URL `http://ourcomments.org/Emacs/nXhtml/doc/nxhtml.html'." + (interactive (let ((curr-cfg (current-window-configuration))) + (describe-function 'nxhtml-setup-install) + (select-window (get-buffer-window (help-buffer))) + (delete-other-windows) + (list + (let* ((key nil) + (has-nxhtml (and (boundp 'nxhtml-install-dir) nxhtml-install-dir)) + (current-way (if has-nxhtml + (if (and (boundp 'nxhtml-autoload-web) + nxhtml-autoload-web) + "Your current setup is to download part by part from the web." + "Your current setup it to download all of nXhtml at once.") + "(You have not currently installed nXhtml.)")) + (prompt (concat "Setup nXhtml install." + "\n" current-way + "\n" + "\n(1) Download whole at once, or (2) part by part as needed" + (if has-nxhtml "\n(3) Update your existing nXhtml" "") + "\n(T) For temporary testing downloading part by part" + "\n" + "\n(? for help, q to quit): ")) + (allowed-keys (if has-nxhtml + '(?1 ?2 ?3 ?T ?q 7) + '(?1 ?2 ?T ?q 7))) + (please nil)) + (while (not (member key allowed-keys)) + (if (not (member key '(??))) + (when key + (unless please + (setq prompt (concat "Please answer with one of the alternatives.\n\n" + prompt)) + (setq please t))) + (describe-function 'nxhtml-setup-install) + (select-window (get-buffer-window (help-buffer))) + (delete-other-windows)) + (setq key (web-vcs-read-key prompt)) + ;;(message "key = %S" key) (sit-for 1) + ) + (case key + (7 (set-window-configuration curr-cfg) + nil) + (?1 'whole) + (?2 'part-by-part) + (?3 'update-existing) + (?T 'test-part-by-part) + ))))) + (message "") + (case way + (whole (call-interactively 'nxhtml-setup-download-all)) + (part-by-part (call-interactively 'nxhtml-setup-auto-download)) + (update-existing (call-interactively 'nxhtml-update-existing-files)) + (test-part-by-part (call-interactively 'nxhtml-setup-test-auto-download)) + ((eq nil way) nil) + (t (error "Unknown way = %S" way)))) + +(defvar nxhtml-basic-files '( + "nxhtml-base.el" + "nxhtml-loaddefs.el" + "web-autoload.el" + "etc/schema/schema-path-patch.el" + "nxhtml/nxhtml-autoload.el" + "autostart.el" + )) + +;;;###autoload +(defun nxhtml-setup-auto-download (dl-dir) + "Set up to autoload nXhtml files from the web. + +This function will download some initial files and then setup to +download the rest when you need them. + +Files will be downloaded under the directory root you specify in +DL-DIR. + +Note that files will not be upgraded automatically. The auto +downloading is just for files you are missing. (This may change a +bit in the future.) If you want to upgrade those files that you +have downloaded you can just call `nxhtml-update-existing-files'. + +You can easily switch between this mode of downloading or +downloading the whole of nXhtml by once. To switch just call the +command `nxhtml-setup-install'. + +See also the command `nxhtml-setup-download-all'. + +Note: If your nXhtml is to old you can't use this function + directly. You have to upgrade first, se the function + above. Version 2.07 or above is good for this." + (interactive (progn + (describe-function 'nxhtml-setup-auto-download) + (select-window (get-buffer-window (help-buffer))) + (delete-other-windows) + (nxhtml-check-convert-to-part-by-part) + (list + (progn + (when (and (boundp 'nxhtml-autoload-web) + (not nxhtml-autoload-web)) + (unless (yes-or-no-p "Convert to updating nXhtml part by part? ") + (throw 'command-level nil))) + (nxhtml-web-vcs-read-dl-dir "Download nXhtml part by part to directory: "))))) + (catch 'command-level + (if (not dl-dir) + (unless (with-no-warnings (called-interactively-p)) + (error "dl-dir should be a directory")) + (nxhtml-check-convert-to-part-by-part) + (when (and (boundp 'nxhtml-install-dir) + nxhtml-install-dir) + (unless (string= (file-truename dl-dir) + (file-truename nxhtml-install-dir)) + (error "Download dir must be same as nxhtml-install-dir=%S" nxhtml-install-dir))) + (let* (;; Need some files: + (web-vcs-el-src (concat (file-name-sans-extension web-vcs-el-this) ".el")) + (web-vcs-el (expand-file-name (file-name-nondirectory web-vcs-el-src) + dl-dir)) + (vcs 'lp) + (base-url (nxhtml-download-root-url nil)) + (byte-comp (if (boundp 'web-autoload-autocompile) + web-autoload-autocompile + t)) + (has-nxhtml (and (boundp 'nxhtml-install-dir) + nxhtml-install-dir)) + (web-vcs-folder-cache nil)) + (setq nxhtml-install-dir dl-dir) + (let ((root (file-name-directory dl-dir))) + (unless (file-exists-p root) + (unless (yes-or-no-p (format "Directory %S does not exist, create it? " root)) + (error "Aborted by user")))) + (make-directory dl-dir t) + (setq message-log-max t) + (view-echo-area-messages) + (message "") + (message "") + (web-vcs-message-with-face 'web-vcs-green "==== Starting nXhtml part by part state ====") + (message "has-nxhtml=%s" has-nxhtml) + ;; Fix-me: First copy this file and web-vcs.el to its destination: + (unless (string= (file-truename dl-dir) + (file-truename (file-name-directory nxhtml-web-vcs-file))) + (dolist (f (list web-vcs-el-src nxhtml-web-vcs-file)) + (copy-file f (expand-file-name (file-name-nondirectory f) dl-dir) + 'ok-overwrite))) + (when byte-comp (web-vcs-byte-compile-newer-file web-vcs-el t)) + ;; Get basic file list: + (catch 'web-autoload-comp-restart + ;;(let ((file-mask (regexp-opt nxhtml-basic-files))) + ;; (web-vcs-get-missing-matching-files vcs base-url dl-dir file-mask)) + (dolist (f nxhtml-basic-files) + (web-vcs-get-missing-matching-files vcs base-url dl-dir f)) + ;; Autostart.el has not run yet, add download dir to load-path. + (let ((load-path (cons (file-name-directory web-vcs-el) load-path))) + (when byte-comp + (dolist (file nxhtml-basic-files) + (let ((el-file (expand-file-name file dl-dir))) + (web-vcs-byte-compile-newer-file el-file nil))))) + (let ((autostart-file (expand-file-name "autostart" dl-dir))) + ;;(ad-deactivate 'require) + (web-vcs-set&save-option 'nxhtml-autoload-web t) + (web-vcs-log nil nil "* nXhtml: Download Part by Part as Needed\n") + (load autostart-file) + (unless (ad-is-active 'require) (ad-activate 'require)) + (web-vcs-log-save) + (web-vcs-message-with-face 'web-vcs-green "==== Basic files for nXhtml part by part are now installed ====") + (web-vcs-display-messages t) + (unless has-nxhtml (nxhtml-add-loading-to-custom-file autostart-file t)))))))) + +;;(call-interactively 'nxhtml-download) +;;;###autoload +(defun nxhtml-setup-download-all (dl-dir) + "Download or update all of nXhtml. + +You can download all if nXhtml with this command. + +To update existing files use `nxhtml-update-existing-files'. + +If you want to download only those files you are actually using +then call `nxhtml-setup-auto-download' instead. + +See the command `nxhtml-setup-install' for a convenient way to +call these commands. + +For more information about auto download of nXhtml files see +`nxhtml-setup-auto-download'." + (interactive (progn + (describe-function 'nxhtml-setup-auto-download) + (select-window (get-buffer-window (help-buffer))) + (delete-other-windows) + ;;(nxhtml-check-convert-to-part-by-part) + (list + (nxhtml-web-vcs-read-dl-dir "Download whole nXhtml to directory: ")))) + + (let ((root (file-name-directory dl-dir))) + (unless (file-exists-p root) + (unless (yes-or-no-p (format "Directory %S does not exist, create it? " root)) + (error "Aborted by user")))) + (make-directory dl-dir t) + (let ((msg (concat "Downloading nXhtml through Launchpad web interface will take rather long\n" + "time (5-15 minutes) so you may want to do it in a separate Emacs session.\n\n" + "Do you want to download using this Emacs session? " + ))) + (if (not (y-or-n-p msg)) + (message "Aborted") + (setq message-log-max t) + (let ((do-byte (y-or-n-p "Do you want to byte compile the files after downloading? "))) + (nxhtml-download-1 dl-dir nil do-byte))))) + + +(defun nxhtml-download-1 (dl-dir revision do-byte) + "Download nXhtml to directory DL-DIR. +If REVISION is nil download latest revision, otherwise the +specified one. + +If DO-BYTE is non-nil byte compile nXhtml after download." + (let* ((has-nxhtml (and (boundp 'nxhtml-install-dir) + nxhtml-install-dir)) + (base-url nxhtml-web-vcs-base-url) + (files-url (concat base-url "files/")) + ;;(revs-url (concat base-url "changes/")) + (rev-part (if revision (number-to-string revision) "head%3A/")) + (full-root-url (concat files-url rev-part)) + (web-vcs-folder-cache nil) + (web-autoload-paranoid nil)) + ;;(nxhtml-require-base) + (when (web-vcs-get-files-from-root 'lp full-root-url dl-dir) + (web-vcs-display-messages t) + (web-vcs-log nil nil "* nXhtml: Download All\n") + (web-vcs-set&save-option 'nxhtml-autoload-web nil) + (message "") + (web-vcs-message-with-face 'web-vcs-green "==== Starting downloading whole nXhtml ====") + (let ((autostart-file (expand-file-name "autostart" dl-dir))) + (load autostart-file) + (web-vcs-log-save) + (web-vcs-message-with-face 'web-vcs-green "==== All files for nXhtml are now installed ====") + (nxhtmlmaint-byte-recompile) + (unless has-nxhtml (nxhtml-add-loading-to-custom-file autostart-file nil)))))) + +(defun nxhtml-check-convert-to-part-by-part () + (when (and (boundp 'nxhtml-install-dir) + nxhtml-install-dir) + (unless (and (boundp 'nxhtml-autoload-web) + nxhtml-autoload-web) + (if (not (boundp 'nxhtml-menu:version)) + (error "nxhtml-install-dir set but no version found") + (unless (string-match "[\.0-9]+" nxhtml-menu:version) + (error "Can't find current version nxhtml-menu:version=%S" nxhtml-menu:version)) + (let* ((ver-str (match-string 0 nxhtml-menu:version)) + (ver-num (string-to-number ver-str))) + (when (< ver-num 2.07) + (web-vcs-message-with-face 'web-vcs-red "Too old nXhtml for download part by part.") + (throw 'command-level nil))))))) + + +;;(directory-files default-directory nil "\\el$") +;;(directory-files default-directory nil "[^#~]$") +;;;###autoload +(defun nxhtml-update-existing-files () + "Update existing nXhtml files from the development sources. +Only files you already have will be updated. + +Note that this works both if you have setup nXhtml to auto +download files as you need them or if you have downloaded all of +nXhtml at once. + +For more information about installing and updating nXhtml see the +command `nxhtml-setup-install'." + ;; Fix-me: download new files too if you are not auto downloading. + (interactive) + (when (y-or-n-p "Do you want to update your nXhtml files? ") + (message "") + (web-vcs-display-messages t) + (web-vcs-message-with-face 'web-vcs-yellow "*\nStarting updating your nXhtml files.\n*\n") + (message nil) + (web-vcs-clear-folder-cache) + (let ((vcs 'lp) + (base-url (nxhtml-download-root-url nil)) + (dl-dir nxhtml-install-dir) + web-vcs-folder-cache) + (setq dl-dir (file-name-as-directory dl-dir)) + (web-vcs-update-existing-files vcs base-url dl-dir dl-dir) + (web-vcs-clear-folder-cache)) + (display-buffer (get-buffer-create "*Compile-Log*")) + (nxhtmlmaint-byte-recompile) + (web-vcs-log-save) + (web-vcs-message-with-face 'web-vcs-yellow "*\nFinished updating your nXhtml files.\n*\n") + (message nil))) + + +;;(nxhtml-maybe-download-files (expand-file-name "nxhtml/doc/img/" nxhtml-install-dir) nil) +;;;###autoload +(defun nxhtml-get-missing-files (sub-dir file-name-list) + (let (file-mask + (root-url (nxhtml-download-root-url nil)) + files-regexp + (full-dir (expand-file-name sub-dir nxhtml-install-dir)) + miss-names) + (if file-name-list + (progn + (dolist (f file-name-list) + (let ((full-f (expand-file-name f full-dir))) + (unless (file-exists-p full-f) + (setq miss-names (cons f miss-names))))) + (setq files-regexp (regexp-opt miss-names))) + (setq files-regexp ".*")) + ;;(unless (file-exists-p full-dir) (make-directory full-dir t)) + (setq file-mask + (concat (file-relative-name (file-name-as-directory full-dir) + nxhtml-install-dir) + files-regexp)) + (let ((web-vcs-folder-cache nil)) + (web-vcs-get-missing-matching-files 'lp root-url nxhtml-install-dir + file-mask)))) + +;; Fix-me: Does not work, Emacs Bug +;; Maybe use wget? http://gnuwin32.sourceforge.net/packages/wget.htm +;; http://emacsbugs.donarmstrong.com/cgi-bin/bugreport.cgi?bug=5103 +;; (nxhtml-get-release-revision) +(defun nxhtml-get-release-revision () + "Get revision number for last release." + (let* ((all-rev-url "http://code.launchpad.net/%7Enxhtml/nxhtml/main") + (url-buf (url-retrieve-synchronously all-rev-url)) + (vcs-rec (or (assq 'lp web-vcs-links-regexp) + (error "Does not know web-vcs 'lp"))) + (rel-ver-regexp (nth 6 vcs-rec)) + ) + (message "%S" url-buf) + (with-current-buffer url-buf + (when (re-search-forward rel-ver-regexp nil t) + (match-string 1))))) + +;;;###autoload +(defun nxhtml-byte-compile-file (file &optional load) + (let ((extra-load-path (when nxhtml-install-dir + (mapcar (lambda (p) + (file-name-as-directory + (expand-file-name p nxhtml-install-dir))) + '("tests" "related" "nxhtml" "util" "."))))) + ;; (message "nxhtml-byte-compile-file:extra-load-path=%s" extra-load-path) + (web-vcs-byte-compile-file file load extra-load-path))) + +;; fix-me: change web-vcs-byte-compile-file instead +;;;###autoload +(defun nxhtml-byte-recompile-file (file &optional load) + "Byte recompile FILE file if necessary. +For more information see `nxhtml-byte-compile-file'. +Loading is done if recompiled and LOAD is t." + (interactive (list (buffer-file-name) + t)) + (let ((elc-file (byte-compile-dest-file file))) + (if (file-newer-than-file-p file elc-file) + (nxhtml-byte-compile-file file load) + (message "Byte compilation of this file is up to date.")))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Add to custom file + + +(defvar nxhtml-handheld-wincfg nil) +(defun nxhtml-handheld-restore-wincg () + (when nxhtml-handheld-wincfg + (set-window-configuration nxhtml-handheld-wincfg) + (setq nxhtml-handheld-wincfg nil))) + +;;(nxhtml-handheld-add-loading-to-custom-file "TEST-ME") +(defun nxhtml-handheld-add-loading-to-custom-file (file-to-load) + (setq nxhtml-handheld-wincfg (current-window-configuration)) + (delete-other-windows) + (let ((info-buf (get-buffer-create "Information about how to add nXhtml to (custom-file)")) + (load-str (format "(load %S)" file-to-load))) + (with-current-buffer info-buf + (add-hook 'kill-buffer-hook 'nxhtml-handheld-restore-wincg nil t) + (insert "Insert the following line to (custom-file), ie the file in the other window:\n\n") + (let ((here (point))) + (insert " " + (propertize load-str 'face 'secondary-selection) + "\n") + (copy-region-as-kill here (point)) + (insert "\nThe line above is in the clipboard so you can just paste it where you want it.\n") + (insert "When ready kill this buffer.") + (goto-char here)) + (setq buffer-read-only t) + (set-buffer-modified-p nil)) + (set-window-buffer (selected-window) info-buf) + (find-file-other-window (custom-file)))) + +;; (nxhtml-add-loading-to-custom-file "test-file") +(defun nxhtml-add-loading-to-custom-file (file-to-load part-by-part) + (message "") + (require 'cus-edit) + (if (not (condition-case nil (custom-file) (error nil))) + (progn + (message "\n\n") + (web-vcs-message-with-face + 'web-vcs-red + (concat "Since you have started this Emacs session without running your init files" + "\nthey are unknown and the installation can not add the statement below." + "\nTo finish the setup of nXhtml you must add" + "\n\n (load %S)" + "\n\nto your custom-file if you have not done it yet." + "\nYou must also customize the variable `nxhtml-autoload-web' to tell that" + (if part-by-part + "\nyou want to download nXhml files as you need them." + "\nyou do not want to allow automatic downloading of nXhtml files." + ) + "\n") + file-to-load) + (message "") + (web-vcs-display-messages t)) + (let ((prompt (concat "Basic setup of nXhtml is done, but it must be loaded from (custom-file)." + "\nShould I add loading of nXhtml to (custom-file) for you? "))) + (if (yes-or-no-p prompt) + (nxhtml-add-loading-to-custom-file-auto file-to-load) + (if (yes-or-no-p "Should I guide you through how to do it? ") + (nxhtml-handheld-add-loading-to-custom-file file-to-load) + (web-vcs-message-with-face 'web-vcs-green + "OK. You need to add (load %S) to your init file" file-to-load)))))) + +;; Fix-me: really do this? Is it safe enough? +(defun nxhtml-add-loading-to-custom-file-auto (file-to-load) + (unless (file-name-absolute-p file-to-load) + (error "nxhtml-add-loading-to-custom-file: Not abs file name: %S" file-to-load)) + (let ((old-buf (find-buffer-visiting (custom-file))) + (full-to-load (expand-file-name file-to-load))) + (with-current-buffer (or old-buf (find-file-noselect (custom-file))) + (save-restriction + (widen) + (catch 'done + (while (progn + (while (progn (skip-chars-forward " \t\n\^l") + (looking-at ";")) + (forward-line 1)) + (not (eobp))) + (let ((start (point)) + (form (read (current-buffer)))) + (when (eq (nth 0 form) 'load) + (let* ((form-file (nth 1 form)) + (full-form-file (expand-file-name form-file))) + (when (string= full-form-file full-to-load) + (throw 'done nil)) + (when (and (string= (file-name-nondirectory full-form-file) + (file-name-nondirectory full-to-load)) + (not (string= full-form-file full-to-load))) + (if (yes-or-no-p "Replace current nXhtml loading in (custom-file)? ") + (progn + (goto-char start) ;; at form start now + (forward-char (length "(load ")) + (skip-chars-forward " \t\n\^l") ;; at start of string + (setq start (point)) + (setq form (read (current-buffer))) + (delete-region start (point)) + (insert (format "%S" full-to-load)) + (basic-save-buffer)) + (web-vcs-message-with-face 'web-vcs-red "Can't continue then") + (web-vcs-display-messages t) + (throw 'command-level nil))))))) + ;; At end of file + (insert (format "\n(load %S)\n" file-to-load)) + (basic-save-buffer)) + (unless old-buf (kill-buffer old-buf)))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;; Start Testing function +(defun emacs-Q-no-nxhtml (&rest args) + (let* ((old-env-load-path (getenv "EMACSLOADPATH")) + sub-env-load-path + (elp-list (or (when old-env-load-path + ;;(split-string old-env-load-path ";")) + (split-string old-env-load-path path-separator)) + load-path)) + (sub-elp-list nil) + ret + (this-emacs-exe (locate-file invocation-name + (list invocation-directory) + exec-suffixes))) + (dolist (p elp-list) + (when (file-exists-p p) + (unless (string= nxhtml-install-dir p) + (let* ((dir (file-name-directory p)) + (last (file-name-nondirectory p)) + (last-dir (file-name-nondirectory + (directory-file-name dir)))) + (unless (and (string= "nxhtml" last-dir) + (member last '("util" "test" "nxhtml" "related" "alt"))) + (setq sub-elp-list (cons p sub-elp-list))))))) + ;;(setq sub-env-load-path (mapconcat 'identity (reverse sub-elp-list) ";")) + (setq sub-env-load-path (mapconcat 'identity (reverse sub-elp-list) path-separator)) + (setenv "EMACSLOADPATH" sub-env-load-path) + (setq ret (apply 'call-process this-emacs-exe nil 0 nil "-Q" args)) + (setenv "EMACSLOADPATH" old-env-load-path) + ret)) + +;; (call-interactively-p 'nxhtml-setup-test-auto-download) +;; (nxhtml-setup-test-auto-download "c:/test2/") +(defun nxhtml-setup-test-auto-download (test-dir) + "Test autoload in a new emacs, started with 'emacs -Q'. +You can choose where to download the files and just delete them +when you have tested enough." + (interactive (list (read-directory-name "Directory for test of auto download of nXhtml: "))) + (let ((this-dir (file-name-directory web-vcs-el-this)) + (this-name (file-name-nondirectory web-vcs-el-this)) + that-file) + (when (and (file-exists-p test-dir) + (not (y-or-n-p (format "Directory %S exists, really test there? " test-dir)))) + (error "Aborted")) + (unless (file-exists-p test-dir) (make-directory test-dir)) + (setq that-file (expand-file-name this-name test-dir)) + (when (file-exists-p that-file) (delete-file that-file)) + (copy-file web-vcs-el-this that-file) + (emacs-Q-no-nxhtml "-l" that-file "-f" "nxhtml-setup-test-auto-download-do-it-here"))) + +(defun nxhtml-setup-test-auto-download-do-it-here () + "Helper for `nxhtml-setup-test-auto-down-load'." + (let ((this-dir (file-name-directory web-vcs-el-this))) + (nxhtml-setup-auto-download this-dir))) + +(defun web-vcs-check-if-modified () + (let ( + (t1 (format-time-string "%Y-%m-%dT%T%z" (date-to-time "2010-01-01 18:20"))) + (t2 (format-time-string "%Y-%m-%dT%T%z" (date-to-time "Mon, 28 Dec 2009 08:57:44 GMT"))) + (url-request-extra-headers + (list + (cons "If-Modified-Since" + (format-time-string + ;;"%Y-%m-%dT%T%z" + "%a, %e %b %Y %H:%M:%S GMT" + (nth 5 (file-attributes "c:/test/temp.el" ))) + ))) + xb) + (setq xb (url-retrieve-synchronously "http://www.emacswiki.org/emacs/download/anything.el")) + (switch-to-buffer xb) + )) +;; (emacs-Q-no-nxhtml "web-vcs.el" "-l" "c:/test/d27/web-autostart.el") +;; (emacs-Q-no-nxhtml "web-vcs.el" "-l" "c:/test/d27/autostart.el") +;; (emacs-Q-no-nxhtml "web-vcs.el" "-f" "eval-buffer" "-f" "nxhtml-temp-setup-auto-download") +;; (emacs-Q-no-nxhtml "-l" "c:/test/d27/web-vcs" "-l" "c:/test/d27/nxhtml-web-vcs" "-f" "nxhtml-temp-setup-auto-download") +;; (emacs-Q-no-nxhtml "-l" "c:/test/d27/nxhtml-web-vcs" "-f" "nxhtml-temp-setup-auto-download") +;; (emacs-Q-no-nxhtml "--geometry=200x50+100+100" "-l" "c:/test/d27/web-vcs" "-f" "web-vcs-nxhtml") +(defun nxhtml-temp-setup-auto-download () + ;;(when (fboundp 'w32-send-sys-command) (w32-send-sys-command #xf030) (sit-for 2)) + (set-frame-size (selected-frame) + (/ 1024 (frame-char-width)) + (/ 512 (frame-char-height)) + ) + (tool-bar-mode -1) + (set-frame-position (selected-frame) 100 50) + (when (y-or-n-p "Do nXhtml? ") + (view-echo-area-messages) + (setq truncate-lines t) + (split-window-horizontally) + (let ((load-path (cons default-directory load-path))) + (require 'web-vcs)) + ;(nxhtml-setup-auto-download "c:/test/d27") + (call-interactively 'nxhtml-setup-auto-download) + )) +;;;;;; End Testing function +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(provide 'nxhtml-web-vcs) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; nxhtml-web-vcs.el ends here diff --git a/emacs/nxhtml/nxhtml/ChangeLog b/emacs/nxhtml/nxhtml/ChangeLog new file mode 100644 index 0000000..c24d360 --- /dev/null +++ b/emacs/nxhtml/nxhtml/ChangeLog @@ -0,0 +1,17 @@ +2006-04-26 + + * nxhtml.el (nxhtml-insert-skeleton-if-empty) + (nxhtml-insert-frame-skeleton): New functions. + +2006-04-25 + + * nxhtml.el (nxhtml-coding-systems-complete) + (nxhtml-script-url-predicate, nxhtml-script-completion-pattern) + (nxhtml-image-url-predicate, nxhtml-image-completion-pattern) + (nxhtml-mailto-predicate, nxhtml-predicate-error) + (nxhtml-in-xml-attribute-value-regex) + (nxhtml-read-mail-url-history, nxhtml-read-web-url-history) + (nxhtml-read-url-history, nxhtml-read-url-type) + (nxhtml-read-url-type-help, nxhtml-read-url) + (rng-complete-attribute-value): New entries for completion. + diff --git a/emacs/nxhtml/nxhtml/doc/demo.html b/emacs/nxhtml/nxhtml/doc/demo.html new file mode 100644 index 0000000..8696032 --- /dev/null +++ b/emacs/nxhtml/nxhtml/doc/demo.html @@ -0,0 +1,71 @@ + + + + + nXhtml Short Tour + + + + + + + + + +
+ +
+

Popup completion

+

nXhtml can use popup style completion too (for XHTML)

+ + Popup completion + Popup completion (thumbnail) +
+

+ more about popup +

+

+ more about popup +

+
+
+ +
+

Emacs style completion

+

Emacs default style for completion uses the minibuffer and an Emacs window

+ + Emacs style completion + Emacs style completion (thumbnail) +
du
+
+
+ +
+ desc div +
+ + diff --git a/emacs/nxhtml/nxhtml/doc/html2xhtml.html b/emacs/nxhtml/nxhtml/doc/html2xhtml.html new file mode 100644 index 0000000..2228c80 --- /dev/null +++ b/emacs/nxhtml/nxhtml/doc/html2xhtml.html @@ -0,0 +1,39 @@ + + + + + + How to Convert to XHTML + + + + +

+ How to Convert to XHTML +

+

+ With nxhtml-mode you can edit XHTML documents, but not HTML + dito. So what do you do with your old HTML documents? The + answer is simple: You convert them to XHTML! There is today + not many reasons not to convert them to XHTML. You may say + "but what about old browsers?". Most users just do not have + old browsers today. Old browsers are too dangerous to use on the + Internet. +

+

+ You can convert the documents easily from within nxhtml-mode + with Tidy. However + Tidy does not come with nxhtml, you have to install it yourself. +

+

+ When Tidy is called from Emacs you can do a whole directory tree + at once. When a buffer is in nxhtml-mode (and tidy.el is found) + there is an entry on the menus called Tidy from which you + can access tidy and set the options for it. Note especially the + Quick Options Settings where you can set options for + converting to XHTML easily. +

+ + + diff --git a/emacs/nxhtml/nxhtml/doc/htmlfontify-example.html b/emacs/nxhtml/nxhtml/doc/htmlfontify-example.html new file mode 100644 index 0000000..0eafb8d --- /dev/null +++ b/emacs/nxhtml/nxhtml/doc/htmlfontify-example.html @@ -0,0 +1,424 @@ + + + + + + + + + + +

Example of htmlfontify.el output

+ +

+ The following is an example of the output you can get with htmlfontify.el. + The version used here is shipped with nXhtml. + (A new version from the original author is on its way.) +

+ + + + + + + + + + + +
Emacs Icon (patched)  Emacs - Frame Dump
+ + + + + + + + + + + + + + + +
+ + + +
+ +
;; This buffer is for notes you don't want to save, and for Lisp evaluation.
+;; If you want to create a file, visit that file with C-x C-f,
+;; then enter the text in that file's own buffer.
+
+
+ +
+
-- (Unix)-- *scratch* (Lisp Interaction Abbrev hs) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ + + + +
cadr is a compiled Lisp function in `subr.el'.
+(cadr x)
+
+Return the car of the cdr of x.
+
+[back]
+
+ +
+
-- (Unix)%% *Help* (Help View Abbrev) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+ + + +
+ + + + +
comint-highlight-prompt                       abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+compilation-column-number                     abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+compilation-error                             abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+compilation-info                              abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+compilation-line-number                       abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+compilation-warning                           abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+completion-dynamic-face                       abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+completion-tooltip-face                       abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+
+ + +
Truncated to line 11 - 19!
+
+
-- (Unix)%% *Faces* (Help View Abbrev) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ + + + +
snow                   snow                                                                                                                        #fffafa
+ghost white            GhostWhite                                                                                                                  #f8f8ff
+white smoke            WhiteSmoke                                                                                                                  #f5f5f5
+gainsboro              gainsboro                                                                                                                   #dcdcdc
+floral white           FloralWhite                                                                                                                 #fffaf0
+old lace               OldLace                                                                                                                     #fdf5e6
+linen                  linen                                                                                                                       #faf0e6
+antique white          AntiqueWhite                                                                                                                #faebd7
+
+ + +
Truncated to line 1 - 9!
+
+
-- (Unix)%% *Colors* (Help View Abbrev) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+ + + + +
________________________
+Program and Value Search
+
+When you use Emacs on MS Windows you sometimes want to fetch values
+and program locations from MS Windows.  Many of these values are
+stored in the MS Windows Registry.  Since Emacs is written to be used
+on many platforms (with the emphasis on GPL platforms) the effort to
+let Emacs read the Registry directly has not been made.  Below you can
+
+ + +
Truncated to line 29 - 37!
+
+
-- (Unix)** *Customize EmacsW32* (Custom Abbrev) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ + + + +
  Add quick printing to File menu (htmlize-view-print-visible): t
+  Keep default print entries in File menu (w32-print-menu-show-print): nil
+  Keep default ps print entries in File menu (w32-print-menu-show-ps-print): nil
+  Use keyboard Window keys as Emacs META (w32-meta-style): w32-lr
+  Underlined accelerators in menu bar (menuacc-active): t
+  Inferior shell + path for unix style programs (w32shell-shell): cmd
+
+   Set all to w32 style!   Reset all to default!   Customize EmacsW32 ... 
+
+ + +
Truncated to line 13 - 21!
+
+
-- (Unix)** *Customize EmacsW32* (Custom Abbrev) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ + + +
+ + + + +
-*- mode: grep; default-directory: "c:/emacs/p/070604/EmacsW32/nxml/util/" -*-
+Grep started at Fri Dec 28 22:54:06
+
+grep -i -nH -e "hfy-tmpfont-stack" *.el
+htmlfontify.el:596:(defvar hfy-tmpfont-stack nil
+htmlfontify.el:999:           (entry (assoc key hfy-tmpfont-stack))
+htmlfontify.el:1003:        (setq tag               (format "%04d" (length hfy-tmpfont-stack))
+htmlfontify.el:1005:              hfy-tmpfont-stack (cons entry hfy-tmpfont-stack)))
+
+ + +
Truncated to line 1 - 9!
+
+
-- (Unix)%% *grep* (Grep Abbrev) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ + + + +
5 matches for "hfy-tmpfont-stack" in buffer: htmlfontify.el
+    596:(defvar hfy-tmpfont-stack nil
+    999:           (entry (assoc key hfy-tmpfont-stack))
+   1003:        (setq tag               (format "%04d" (length hfy-tmpfont-stack))
+   1005:              hfy-tmpfont-stack (cons entry hfy-tmpfont-stack)))
+   1228:        ;;(hfy-tmpfont-stack nil)
+
+ +
+
-- (Unix)%% *Occur* (Occur Abbrev) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+ M-x  hfyview-frame
+ + diff --git a/emacs/nxhtml/nxhtml/doc/img/Las_Medulas.jpg b/emacs/nxhtml/nxhtml/doc/img/Las_Medulas.jpg new file mode 100644 index 0000000..694a2c5 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/Las_Medulas.jpg differ diff --git a/emacs/nxhtml/nxhtml/doc/img/Toco_toucan.jpg b/emacs/nxhtml/nxhtml/doc/img/Toco_toucan.jpg new file mode 100644 index 0000000..269886c Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/Toco_toucan.jpg differ diff --git a/emacs/nxhtml/nxhtml/doc/img/bacchante2.jpg b/emacs/nxhtml/nxhtml/doc/img/bacchante2.jpg new file mode 100644 index 0000000..a736099 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/bacchante2.jpg differ diff --git a/emacs/nxhtml/nxhtml/doc/img/butterflies.jpg b/emacs/nxhtml/nxhtml/doc/img/butterflies.jpg new file mode 100644 index 0000000..a7352a6 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/butterflies.jpg differ diff --git a/emacs/nxhtml/nxhtml/doc/img/butterflies.png b/emacs/nxhtml/nxhtml/doc/img/butterflies.png new file mode 100644 index 0000000..8d60637 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/butterflies.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/butterflies.xcf b/emacs/nxhtml/nxhtml/doc/img/butterflies.xcf new file mode 100644 index 0000000..9260725 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/butterflies.xcf differ diff --git a/emacs/nxhtml/nxhtml/doc/img/continue-play.jpg b/emacs/nxhtml/nxhtml/doc/img/continue-play.jpg new file mode 100644 index 0000000..587113e Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/continue-play.jpg differ diff --git a/emacs/nxhtml/nxhtml/doc/img/divine2.jpg b/emacs/nxhtml/nxhtml/doc/img/divine2.jpg new file mode 100644 index 0000000..6a8ea51 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/divine2.jpg differ diff --git a/emacs/nxhtml/nxhtml/doc/img/edit-part.png b/emacs/nxhtml/nxhtml/doc/img/edit-part.png new file mode 100644 index 0000000..7c6ab2a Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/edit-part.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/editing-web-files.png b/emacs/nxhtml/nxhtml/doc/img/editing-web-files.png new file mode 100644 index 0000000..ce30bdf Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/editing-web-files.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/editing-web-files.xcf b/emacs/nxhtml/nxhtml/doc/img/editing-web-files.xcf new file mode 100644 index 0000000..6703882 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/editing-web-files.xcf differ diff --git a/emacs/nxhtml/nxhtml/doc/img/emacs-style-completion.png b/emacs/nxhtml/nxhtml/doc/img/emacs-style-completion.png new file mode 100644 index 0000000..0a404fb Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/emacs-style-completion.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/emacsP.png b/emacs/nxhtml/nxhtml/doc/img/emacsP.png new file mode 100644 index 0000000..e0a5ecb Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/emacsP.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/emacsP16.png b/emacs/nxhtml/nxhtml/doc/img/emacsP16.png new file mode 100644 index 0000000..54b597b Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/emacsP16.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/embedded-css.png b/emacs/nxhtml/nxhtml/doc/img/embedded-css.png new file mode 100644 index 0000000..25c11d4 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/embedded-css.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/embedded-xhtml.png b/emacs/nxhtml/nxhtml/doc/img/embedded-xhtml.png new file mode 100644 index 0000000..85b98f3 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/embedded-xhtml.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/foldit-closed.png b/emacs/nxhtml/nxhtml/doc/img/foldit-closed.png new file mode 100644 index 0000000..fc1b49c Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/foldit-closed.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/foldit-temp-opened.png b/emacs/nxhtml/nxhtml/doc/img/foldit-temp-opened.png new file mode 100644 index 0000000..5e02725 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/foldit-temp-opened.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/fun-brain-2.png b/emacs/nxhtml/nxhtml/doc/img/fun-brain-2.png new file mode 100644 index 0000000..a24f0f4 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/fun-brain-2.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/getitbuttons-1.png b/emacs/nxhtml/nxhtml/doc/img/getitbuttons-1.png new file mode 100644 index 0000000..5f3c757 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/getitbuttons-1.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/getitbuttons-1.xcf b/emacs/nxhtml/nxhtml/doc/img/getitbuttons-1.xcf new file mode 100644 index 0000000..8ec9aaa Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/getitbuttons-1.xcf differ diff --git a/emacs/nxhtml/nxhtml/doc/img/getitbuttons-2.png b/emacs/nxhtml/nxhtml/doc/img/getitbuttons-2.png new file mode 100644 index 0000000..c3615f3 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/getitbuttons-2.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/getitbuttons.png b/emacs/nxhtml/nxhtml/doc/img/getitbuttons.png new file mode 100644 index 0000000..b9b0c43 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/getitbuttons.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/getitbuttons.xcf b/emacs/nxhtml/nxhtml/doc/img/getitbuttons.xcf new file mode 100644 index 0000000..ce416ce Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/getitbuttons.xcf differ diff --git a/emacs/nxhtml/nxhtml/doc/img/giraffe.jpg b/emacs/nxhtml/nxhtml/doc/img/giraffe.jpg new file mode 100644 index 0000000..6bf9b57 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/giraffe.jpg differ diff --git a/emacs/nxhtml/nxhtml/doc/img/healthy_feet2.jpg b/emacs/nxhtml/nxhtml/doc/img/healthy_feet2.jpg new file mode 100644 index 0000000..ed3ab6f Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/healthy_feet2.jpg differ diff --git a/emacs/nxhtml/nxhtml/doc/img/itsalltext-pref.png b/emacs/nxhtml/nxhtml/doc/img/itsalltext-pref.png new file mode 100644 index 0000000..3b3d9f1 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/itsalltext-pref.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/links-appmenu.png b/emacs/nxhtml/nxhtml/doc/img/links-appmenu.png new file mode 100644 index 0000000..a03ba4a Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/links-appmenu.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/nxml-where.png b/emacs/nxhtml/nxhtml/doc/img/nxml-where.png new file mode 100644 index 0000000..102d084 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/nxml-where.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/php-in-nxhtml-2.png b/emacs/nxhtml/nxhtml/doc/img/php-in-nxhtml-2.png new file mode 100644 index 0000000..c204f4d Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/php-in-nxhtml-2.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/php-in-nxhtml.png b/emacs/nxhtml/nxhtml/doc/img/php-in-nxhtml.png new file mode 100644 index 0000000..cda754a Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/php-in-nxhtml.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/php-in-php.png b/emacs/nxhtml/nxhtml/doc/img/php-in-php.png new file mode 100644 index 0000000..c7664da Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/php-in-php.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/php-in-xhtml.png b/emacs/nxhtml/nxhtml/doc/img/php-in-xhtml.png new file mode 100644 index 0000000..310d07f Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/php-in-xhtml.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/popup-compl.png b/emacs/nxhtml/nxhtml/doc/img/popup-compl.png new file mode 100644 index 0000000..a40bd49 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/popup-compl.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/raindrops2.jpg b/emacs/nxhtml/nxhtml/doc/img/raindrops2.jpg new file mode 100644 index 0000000..04d0610 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/raindrops2.jpg differ diff --git a/emacs/nxhtml/nxhtml/doc/img/region-selected-after.png b/emacs/nxhtml/nxhtml/doc/img/region-selected-after.png new file mode 100644 index 0000000..c7ea553 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/region-selected-after.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/region-selected-completion.png b/emacs/nxhtml/nxhtml/doc/img/region-selected-completion.png new file mode 100644 index 0000000..b971b9d Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/region-selected-completion.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/region-selected.png b/emacs/nxhtml/nxhtml/doc/img/region-selected.png new file mode 100644 index 0000000..0a2358b Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/region-selected.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/rembrandt-self-portrait.jpg b/emacs/nxhtml/nxhtml/doc/img/rembrandt-self-portrait.jpg new file mode 100644 index 0000000..2689598 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/rembrandt-self-portrait.jpg differ diff --git a/emacs/nxhtml/nxhtml/doc/img/style-in-nxhtml.png b/emacs/nxhtml/nxhtml/doc/img/style-in-nxhtml.png new file mode 100644 index 0000000..151681d Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/style-in-nxhtml.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/use-nXhtml-trans.png b/emacs/nxhtml/nxhtml/doc/img/use-nXhtml-trans.png new file mode 100644 index 0000000..4ae2ff8 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/use-nXhtml-trans.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/use-nXhtml-trans2.png b/emacs/nxhtml/nxhtml/doc/img/use-nXhtml-trans2.png new file mode 100644 index 0000000..c348c92 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/use-nXhtml-trans2.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/use-nXhtml.png b/emacs/nxhtml/nxhtml/doc/img/use-nXhtml.png new file mode 100644 index 0000000..408980f Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/use-nXhtml.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/use-nXhtml.xcf b/emacs/nxhtml/nxhtml/doc/img/use-nXhtml.xcf new file mode 100644 index 0000000..d42da0b Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/use-nXhtml.xcf differ diff --git a/emacs/nxhtml/nxhtml/doc/img/validation-error.png b/emacs/nxhtml/nxhtml/doc/img/validation-error.png new file mode 100644 index 0000000..7682642 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/validation-error.png differ diff --git a/emacs/nxhtml/nxhtml/doc/img/volga.jpg b/emacs/nxhtml/nxhtml/doc/img/volga.jpg new file mode 100644 index 0000000..c11e93c Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/volga.jpg differ diff --git a/emacs/nxhtml/nxhtml/doc/img/xml-validation-header.png b/emacs/nxhtml/nxhtml/doc/img/xml-validation-header.png new file mode 100644 index 0000000..2093781 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/img/xml-validation-header.png differ diff --git a/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/carrow1.gif b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/carrow1.gif new file mode 100644 index 0000000..316dea7 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/carrow1.gif differ diff --git a/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/carrow2.gif b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/carrow2.gif new file mode 100644 index 0000000..24a6be1 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/carrow2.gif differ diff --git a/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche1.gif b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche1.gif new file mode 100644 index 0000000..218233d Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche1.gif differ diff --git a/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche1.png b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche1.png new file mode 100644 index 0000000..61e8660 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche1.png differ diff --git a/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche2.gif b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche2.gif new file mode 100644 index 0000000..dc91f06 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche2.gif differ diff --git a/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche2.png b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche2.png new file mode 100644 index 0000000..bbf66a1 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche2.png differ diff --git a/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/loading-bar-black.gif b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/loading-bar-black.gif new file mode 100644 index 0000000..99368d6 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/loading-bar-black.gif differ diff --git a/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/open.gif b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/open.gif new file mode 100644 index 0000000..d145e66 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/open.gif differ diff --git a/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/open.png b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/open.png new file mode 100644 index 0000000..aebf498 Binary files /dev/null and b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/img/open.png differ diff --git a/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/jd.gallery.css b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/jd.gallery.css new file mode 100644 index 0000000..b0d87ec --- /dev/null +++ b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/jd.gallery.css @@ -0,0 +1,238 @@ +#myGallery +{ + width: 460px; + height: 345px; + z-index:5; + display: none; + border: 1px solid #000; +} + +.jdGallery +{ + overflow: hidden; + position: relative; +} + +.jdGallery img +{ + border: 0; + margin: 0; +} + +.jdGallery .slideElement +{ + width: 100%; + height: 100%; + background-color: #000; + background-repeat: no-repeat; +} + +.jdGallery .loadingElement +{ + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; + background-color: #000; + background-repeat: no-repeat; + background-position: center center; + background-image: url('img/loading-bar-black.gif'); +} + +.jdGallery .slideInfoZone +{ + position: absolute; + z-index: 10; + width: 100%; + margin: 0px; + left: 0; + bottom: 0; + height: 40px; + background: #333; + color: #fff; + text-indent: 0; + overflow: hidden; +} + +* html .jdGallery .slideInfoZone +{ + bottom: -1px; +} + +.jdGallery .slideInfoZone h2 +{ + padding: 0; + font-size: 80%; + margin: 0; + margin: 2px 5px; + font-weight: bold; + color: inherit; +} + +.jdGallery .slideInfoZone p +{ + padding: 0; + font-size: 80%; + margin: 2px 5px; + color: #eee; +} + +.jdGallery div.carouselContainer +{ + position: absolute; + height: 135px; + width: 100%; + z-index: 10; + margin: 0px; + left: 0; + top: 0; +} + +.jdGallery a.carouselBtn +{ + position: absolute; + bottom: 0; + right: 30px; + height: 20px; + /*width: 100px; background: url('img/carousel_btn.gif') no-repeat;*/ + text-align: center; + padding: 0 10px; + font-size: 13px; + background: #333; + color: #fff; + cursor: pointer; +} + +.jdGallery .carousel +{ + position: absolute; + width: 100%; + margin: 0px; + left: 0; + top: 0; + height: 115px; + background: #333; + color: #fff; + text-indent: 0; + overflow: hidden; +} + +.jdGallery .carousel .carouselWrapper +{ + position: absolute; + width: 100%; + height: 78px; + top: 10px; + left: 0; + overflow: hidden; +} + +.jdGallery .carousel .carouselInner +{ + position: relative; +} + +.jdGallery .carousel .carouselInner .thumbnail +{ + cursor: pointer; + background: #000; + background-position: center center; + float: left; + border: solid 1px #fff; +} + +.jdGallery .carousel .label +{ + font-size: 13px; + position: absolute; + bottom: 5px; + left: 10px; + padding: 0; + margin: 0; +} + +.jdGallery .carousel .label .number +{ + color: #b5b5b5; +} + +.jdGallery a +{ + font-size: 100%; + text-decoration: none; + color: inherit; +} + +.jdGallery a.right, .jdGallery a.left +{ + position: absolute; + height: 99%; + width: 25%; + cursor: pointer; + z-index:10; + filter:alpha(opacity=20); + -moz-opacity:0.2; + -khtml-opacity: 0.2; + opacity: 0.2; +} + +* html .jdGallery a.right, * html .jdGallery a.left +{ + filter:alpha(opacity=50); +} + +.jdGallery a.right:hover, .jdGallery a.left:hover +{ + filter:alpha(opacity=80); + -moz-opacity:0.8; + -khtml-opacity: 0.8; + opacity: 0.8; +} + +.jdGallery a.left +{ + left: 0; + top: 0; + background: url('img/fleche1.png') no-repeat center left; +} + +* html .jdGallery a.left { background: url('img/fleche1.gif') no-repeat center left; } + +.jdGallery a.right +{ + right: 0; + top: 0; + background: url('img/fleche2.png') no-repeat center right; +} + +* html .jdGallery a.right { background: url('img/fleche2.gif') no-repeat center right; } + +.jdGallery a.open +{ + left: 0; + top: 0; + width: 100%; + height: 100%; +} + +.withArrows a.open +{ + position: absolute; + top: 0; + left: 25%; + height: 99%; + width: 50%; + cursor: pointer; + z-index: 10; + background: none; + -moz-opacity:0.8; + -khtml-opacity: 0.8; + opacity: 0.8; +} + +.withArrows a.open:hover { background: url('img/open.png') no-repeat center center; } + +* html .withArrows a.open:hover { background: url('img/open.gif') no-repeat center center; + filter:alpha(opacity=80); } + diff --git a/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/layout.css b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/layout.css new file mode 100644 index 0000000..9c807b6 --- /dev/null +++ b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/css/layout.css @@ -0,0 +1,91 @@ +body { + color: #ccc; + font-family: "Trebuchet MS", "Lucida Grande", Arial, Helvetica, sans-serif; + margin: 0 auto; + padding: 0; + font-size: 1.0em; + background: #111 url('../images/bg/gradient1.gif') top left repeat-x; +} + +h1 +{ + color: #fff; + font-size: 47px; + font-weight: bolder; + margin: 0 40px; + padding: 0.08em 0; +} + +h1 sup +{ + color: #ddd; +} + +h1 a +{ + color: #fff; + text-decoration: none; +} + +h1 .company, h1 a .company +{ + color: #d01a71; +} + +h2 +{ + color: #ddd; + font-size: 2.5em; +} + +h3 +{ + color: #fff; + font-size: 1.5em; +} + +h4 +{ + font-size: 1.3em; +} + +.content +{ + margin: 0 20px; +} + +.content a +{ + color: #fff; +} + + +.content p.linkage +{ + margin-top: 2em; + text-align: right; + font-size: 1.7em; + color: #ddd; +} + +.content p.linkage a { color: #fff; } + +/*.content p.linkage a +{ + color: #fff; + background: url('../images/bg/biglink_off.gif') center right no-repeat; + padding: 10px 20px; + text-decoration: none; +} + +.content p.linkage a:hover +{ + background: url('../images/bg/biglink_on.gif') center right no-repeat; + font-style: italic; +}*/ + +#myGallery +{ + text-align: left; + margin: 0 auto; +} diff --git a/emacs/nxhtml/nxhtml/doc/js/smoothgallery/scripts/jd.gallery.js b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/scripts/jd.gallery.js new file mode 100644 index 0000000..af83b13 --- /dev/null +++ b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/scripts/jd.gallery.js @@ -0,0 +1,449 @@ +/* + This file is part of JonDesign's SmoothGallery v1.0.1. + + JonDesign's SmoothGallery is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + JonDesign's SmoothGallery is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JonDesign's SmoothGallery; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Main Developer: Jonathan Schemoul (JonDesign: http://www.jondesign.net/) + Contributed code by: + - Christian Ehret (bugfix) + - Nitrix (bugfix) + - Valerio from Mad4Milk for his great help with the carousel scrolling and many other things. + - Archie Cowan for helping me find a bugfix on carousel inner width problem. + Many thanks to: + - The mootools team for the great mootools lib, and it's help and support throughout the project. +*/ + + +var $removeEvents = function (object, type) +{ + if (!object.events) return object; + if (type){ + if (!object.events[type]) return object; + for (var fn in object.events[type]) object.removeEvent(type, fn); + object.events[type] = null; + } else { + for (var evType in object.events) object.removeEvents(evType); + object.events = null; + } + return object; +}; + + +// declaring the class +var gallery = new Class({ + initialize: function(element, options) { + this.setOptions({ + showArrows: true, + showCarousel: true, + showInfopane: true, + showDescription: false, + thumbHeight: 75, + thumbWidth: 100, + thumbSpacing: 10, + embedLinks: true, + fadeDuration: 500, + timed: false, + delay: 9000, + preloader: true, + manualData: [], + populateData: true, + elementSelector: "div.imageElement", + titleSelector: "h3", + subtitleSelector: "p", + descriptionSelector: "div", + linkSelector: "a.open", + imageSelector: "img.full", + thumbnailSelector: "img.thumbnail", + slideInfoZoneOpacity: 0.7, + carouselMinimizedOpacity: 0.4, + carouselMinimizedHeight: 20, + carouselMaximizedOpacity: 0.7, + destroyAfterPopulate: true, + baseClass: 'jdGallery', + withArrowsClass: 'withArrows', + textShowCarousel: 'Pictures', + useThumbGenerator: false, + thumbGenerator: 'resizer.php' + }, options); + this.fireEvent('onInit'); + this.currentIter = 0; + this.lastIter = 0; + this.maxIter = 0; + this.galleryElement = element; + this.galleryData = this.options.manualData; + this.galleryInit = 1; + this.galleryElements = Array(); + this.thumbnailElements = Array(); + this.galleryElement.addClass(this.options.baseClass); + if (this.options.populateData) + this.populateData(); + element.style.display="block"; + + if (this.options.embedLinks) + { + this.currentLink = new Element('a').addClass('open').setProperties({ + href: '#', + title: '' + }).injectInside(element); + if ((!this.options.showArrows) && (!this.options.showCarousel)) + this.galleryElement = element = this.currentLink; + else + this.currentLink.setStyle('display', 'none'); + } + + this.constructElements(); + if ((data.length>1)&&(this.options.showArrows)) + { + var leftArrow = new Element('a').addClass('left').addEvent( + 'click', + this.prevItem.bind(this) + ).injectInside(element); + var rightArrow = new Element('a').addClass('right').addEvent( + 'click', + this.nextItem.bind(this) + ).injectInside(element); + this.galleryElement.addClass(this.options.withArrowsClass); + } + this.loadingElement = new Element('div').addClass('loadingElement').injectInside(element); + if (this.options.showInfopane) this.initInfoSlideshow(); + if (this.options.showCarousel) this.initCarousel(); + this.doSlideShow(1); + }, + populateData: function() { + currentArrayPlace = this.galleryData.length; + options = this.options; + data = this.galleryData; + this.galleryElement.getElements(options.elementSelector).each(function(el) { + elementDict = { + image: el.getElement(options.imageSelector).getProperty('src'), + number: currentArrayPlace + }; + if ((options.showInfopane) | (options.showCarousel)) + Object.extend(elementDict, { + title: el.getElement(options.titleSelector).innerHTML, + description: el.getElement(options.subtitleSelector).innerHTML + }); + if ((options.showDescription)) + Object.extend(elementDict, { + outsideDescription: el.getElement(options.descriptionSelector).innerHTML + }); + if (options.embedLinks) + Object.extend(elementDict, { + link: el.getElement(options.linkSelector).href||false, + linkTitle: el.getElement(options.linkSelector).title||false + }); + if ((!options.useThumbGenerator) && (options.showCarousel)) + Object.extend(elementDict, { + thumbnail: el.getElement(options.thumbnailSelector).src + }); + else if (options.useThumbGenerator) + Object.extend(elementDict, { + thumbnail: 'resizer.php?imgfile=' + elementDict.image + '&max_width=' + options.thumbWidth + '&max_height=' + options.thumbHeight + }); + + data[currentArrayPlace] = elementDict; + currentArrayPlace++; + if (this.options.destroyAfterPopulate) + el.remove(); + }); + this.galleryData = data; + this.fireEvent('onPopulated'); + }, + constructElements: function() { + el = this.galleryElement; + this.maxIter = this.galleryData.length; + var currentImg; + for(i=0;i= this.maxIter) + this.nextIter = 0; + this.galleryInit = 0; + this.goTo(this.nextIter); + }, + prevItem: function() { + this.fireEvent('onPreviousCalled'); + this.nextIter = this.currentIter-1; + if (this.nextIter <= -1) + this.nextIter = this.maxIter - 1; + this.galleryInit = 0; + this.goTo(this.nextIter); + }, + goTo: function(num) { + this.clearTimer(); + if (this.options.embedLinks) + this.clearLink(); + if (this.options.showInfopane) + { + this.slideInfoZone.clearChain(); + this.hideInfoSlideShow().chain(this.changeItem.pass(num, this)); + } else + this.changeItem.delay(500, this, num); + if (this.options.embedLinks) + this.makeLink(num); + if (this.options.showDescription) + this.showDescription(num); + this.prepareTimer(); + /*if (this.options.showCarousel) + this.clearThumbnailsHighlights();*/ + }, + changeItem: function(num) { + this.fireEvent('onStartChanging'); + this.galleryInit = 0; + if (this.currentIter != num) + { + for(i=0;i this.currentIter) this.galleryElements[num].custom(1); + else + { + this.galleryElements[num].set(1); + this.galleryElements[this.currentIter].custom(0); + } + this.currentIter = num; + } + this.doSlideShow.bind(this)(); + this.fireEvent('onChanged'); + }, + clearTimer: function() { + if (this.options.timed) + $clear(this.timer); + }, + prepareTimer: function() { + if (this.options.timed) + this.timer = this.nextItem.delay(this.options.delay, this); + }, + doSlideShow: function(position) { + if (this.galleryInit == 1) + { + imgPreloader = new Image(); + imgPreloader.onload=function(){ + this.startSlideShow.delay(10, this); + }.bind(this); + imgPreloader.src = this.galleryData[0].image; + } else { + if (this.options.showInfopane) + { + if (this.options.showInfopane) + { + this.showInfoSlideShow.delay((500 + this.options.fadeDuration), this); + } else + if (this.options.showCarousel) + this.centerCarouselOn(position); + } + } + }, + initCarousel: function () { + var carouselContainerElement = new Element('div').addClass('carouselContainer').injectInside(this.galleryElement); + this.carouselContainer = new Fx.Styles(carouselContainerElement, {transition: Fx.Transitions.expoOut}); + this.carouselContainer.normalHeight = carouselContainerElement.offsetHeight; + this.carouselContainer.set({'opacity': this.options.carouselMinimizedOpacity, 'top': (this.options.carouselMinimizedHeight - this.carouselContainer.normalHeight)}); + + this.carouselBtn = new Element('a').addClass('carouselBtn').setProperties({ + title: this.options.textShowCarousel + }).setHTML(this.options.textShowCarousel).injectInside(carouselContainerElement); + + this.carouselBtn.addEvent( + 'click', + function () { + this.carouselContainer.clearTimer(); + this.toggleCarousel(); + }.bind(this) + ); + this.carouselActive = false; + + var carouselElement = new Element('div').addClass('carousel').injectInside(carouselContainerElement); + this.carousel = new Fx.Styles(carouselElement); + + this.carouselLabel = new Element('p').addClass('label').injectInside(this.carousel.element); + this.carouselWrapper = new Element('div').addClass('carouselWrapper').injectInside(this.carousel.element); + this.carouselInner = new Element('div').addClass('carouselInner').injectInside(this.carouselWrapper); + + this.carouselWrapper.scroller = new Scroller(this.carouselWrapper, { + area: 100, + velocity: 0.2 + }) + + this.carouselWrapper.elementScroller = new Fx.Scroll(this.carouselWrapper, { + duration: 400, + onStart: this.carouselWrapper.scroller.stop.bind(this.carouselWrapper.scroller), + onComplete: this.carouselWrapper.scroller.start.bind(this.carouselWrapper.scroller) + }); + + this.constructThumbnails(); + + this.carouselInner.style.width = ((this.maxIter * (this.options.thumbWidth + this.options.thumbSpacing)) - this.options.thumbSpacing + this.options.thumbWidth) + "px"; + }, + toggleCarousel: function() { + if (this.carouselActive) + this.hideCarousel(); + else + this.showCarousel(); + }, + showCarousel: function () { + this.fireEvent('onShowCarousel'); + this.carouselContainer.custom({ + 'opacity': this.options.carouselMaximizedOpacity, + 'top': 0 + }).addEvent('onComplete', function() { this.carouselActive = true; this.carouselWrapper.scroller.start(); }.bind(this)); + }, + hideCarousel: function () { + this.fireEvent('onHideCarousel'); + this.carouselContainer.custom({ + 'opacity': this.options.carouselMinimizedOpacity, + 'top': (this.options.carouselMinimizedHeight - this.carouselContainer.normalHeight) + }).addEvent('onComplete', function() { this.carouselActive = false; this.carouselWrapper.scroller.stop(); }.bind(this)); + }, + constructThumbnails: function () { + element = this.carouselInner; + for(i=0;i' + (myself.relatedImage.number + 1) + "/" + this.maxIter + ": " + myself.relatedImage.title); + }.pass(currentImg, this), + 'mouseout': function (myself) { + myself.clearTimer(); + myself.custom(0.2); + }.pass(currentImg, this), + 'click': function (myself) { + this.goTo(myself.relatedImage.number); + }.pass(currentImg, this) + }); + + currentImg.relatedImage = this.galleryData[i]; + this.thumbnailElements[parseInt(i)] = currentImg; + } + }, + clearThumbnailsHighlights: function() + { + for(i=0;i, MIT Style License. +eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('k 11=f(1S){k 4s=f(){j(9.1e&&Y[0]!=\'7h\')h 9.1e.2m(9,Y);Q h 9};I(k n W 9)4s[n]=9[n];4s.U=1S;h 4s};11.1G=f(){};11.U={N:f(1S){k 4r=M 9(\'7h\');k 7g=f(2s,2f){j(!2s.2m||!2f.2m)h T;h f(){9.1t=2s;h 2f.2m(9,Y)}};I(k n W 1S){k 2s=4r[n];k 2f=1S[n];j(2s&&2s!=2f)2f=7g(2s,2f)||2f;4r[n]=2f}h M 11(4r)},1T:f(1S){I(k n W 1S)9.U[n]=1S[n]}};1H.N=f(){k R=Y;R=(R[1])?[R[0],R[1]]:[9,R[0]];I(k n W R[1])R[0][n]=R[1][n];h R[0]};1H.5p=f(){I(k i=0;i\'));$1o(9.96,f(4e){j(4e.24!=\'24\')l.4d(4e.24,4e.K)});j(9.26)9.6G(l);h l}6F:9.6E(n,K)}h 9},95:f(1L){I(k n W 1L)9.4d(n,1L[n]);h 9},94:f(6D){9.93=6D;h 9},92:f(n){h(n==\'6C\')?9.1d:9.6k(n)},3C:f(){h 9.41.3G()},2O:f(){k l=9,4c=0,4b=0;91{4c+=l.4c||0;4b+=l.4b||0;l=l.90}34(l);h{\'x\':4c,\'y\':4b}},2a:f(x,y){9.3U=x;9.3V=y},3P:f(){h{\'1V\':{\'x\':9.3U,\'y\':9.3V},\'2A\':{\'x\':9.2x,\'y\':9.2v},\'3O\':{\'x\':9.68,\'y\':9.69}}},4D:f(){h 9.2O().y},4F:f(){h 9.2O().x},8Z:f(){k 5i=9.2O();k u={\'3j\':9.2x,\'3i\':9.2v,\'2i\':5i.x,\'2w\':5i.y};u.5a=u.2i+u.3j;u.6B=u.2w+u.3i;h u},2F:f(){2c(9.3C()){1c\'2U\':j(9.6A!=-1)h 9.m[9.6A].K;1P;1c\'8Y\':j(!(9.8X&&[\'8W\',\'8V\'].15(9.q))&&![\'3S\',\'33\',\'8U\'].15(9.q))1P;1c\'8T\':h 9.K}h T}});k 8S=12;12.1a=L.1a=1b.U.1a;12.1E=L.1E=1b.U.1E;k 31={1w:[],6z:f(r){31.1w.18(r)},5g:f(){12.1E(\'6y\',31.5g);31.1w.1o(f(l){l.5h();I(k p W 1b.U)2I[p]=12[p]=L[p]=l[p]=1K;l.N=1K})}};12.1a(\'6y\',31.5g);k 3F=M 11({1e:f(o){9.o=o||12.o;9.q=9.o.q;9.3H=9.o.3H||9.o.8R;j(9.3H.6x==3)9.3H=9.3H.26;9.8Q=9.o.8P;9.8O=9.o.8N;9.8M=9.o.8L;9.8K=9.o.8J;j([\'5f\',\'2M\'].15(9.q)){9.3f=9.o.6w?(9.o.6w/ (12.51 ? -6v : 6v)) : -(9.o.8I || 0) /3}Q j(9.q.15(\'1O\')){9.5d=9.o.6r||9.o.8H;I(k 24 W 3F.1u){j(3F.1u[24]==9.5d)k 6u=24}9.1O=6u||5e.8G(9.5d).3G()}Q j(9.q.15(\'2l\')||9.q==\'8F\'){9.1y={\'x\':9.o.5c||9.o.6t+L.2r.3U,\'y\':9.o.5b||9.o.6s+L.2r.3V};9.5y={\'x\':9.o.5c?9.o.5c-12.66:9.o.6t,\'y\':9.o.5b?9.o.5b-12.67:9.o.6s};9.8E=(9.o.6r==3)||(9.o.8D==2);2c(9.q){1c\'8C\':9.4a=9.o.4a||9.o.8B;1P;1c\'8A\':9.4a=9.o.4a||9.o.5L}}},1s:f(){9.49();9.48();h 9},49:f(){j(9.o.49)9.o.49();Q 9.o.8z=1g;h 9},48:f(){j(9.o.48)9.o.48();Q 9.o.8y=T;h 9}});3F.1u={\'8x\':13,\'8w\':38,\'8v\':40,\'2i\':37,\'5a\':39,\'8u\':27,\'8t\':32,\'8s\':8,\'8r\':46};59.N({2y:f(J,R){h 9.2e({\'J\':J,\'Y\':R,\'o\':3F})}});k 5S=M 11({8q:f(O){9.2H=9.2H||[];9.2H.18(O);h 9},5Z:f(){j(9.2H&&9.2H.14)9.2H.47(0,1)[0].2d(10,9)},8p:f(){9.2H=[]}});k 3c=M 11({1a:f(q,O){j(O!=11.1G){9.V=9.V||{};9.V[q]=9.V[q]||[];j(!9.V[q].15(O))9.V[q].18(O)}h 9},1x:f(q,R,2d){j(9.V&&9.V[q]){9.V[q].1o(f(O){O.2e({\'J\':9,\'2d\':2d,\'Y\':R})()},9)}h 9},1E:f(q,O){j(9.V&&9.V[q])9.V[q].3Z(O);h 9}});k 3b=M 11({2N:f(6q,m){9.m=1H.N(6q,m);j(9.1a){I(k 3E W 9.m){j(($q(9.m[3E])==\'f\')&&3E.15(\'^58[A-Z]\'))9.1a(3E,9.m[3E])}}h 9}});f $E(1v,3D){h($(3D)||L).42(1v)};f $8o(1v,3D){h($(3D)||L).2G(1v)};1b.N({3B:f(1v){k 1Q=[];1v.45().4Y(\' \').1o(f(43,i){k 1q=43.28(\'^(\\\\w*|\\\\*)(?:#([\\\\6p-]+)|\\\\.([\\\\6p-]+))?(?:\\\\[["\\\']?(\\\\w+)["\\\']?(?:([\\\\*\\\\^\\\\$]?=)["\\\']?(\\\\w*)["\\\']?)?\\\\])?$\');j(!1q)h;1q[1]=1q[1]||\'*\';j(i==0){j(1q[2]){k l=9.44(1q[2]);j(!l||((1q[1]!=\'*\')&&(1b.U.3C.1i(l)!=1q[1])))h;1Q=[l]}Q{1Q=$A(9.56(1q[1]))}}Q{1Q=1N.U.6m.1i(1Q,1q[1]);j(1q[2])1Q=1N.U.6o.1i(1Q,1q[2])}j(1q[3])1Q=1N.U.6n.1i(1Q,1q[3]);j(1q[4])1Q=1N.U.6l.1i(1Q,1q[4],1q[6],1q[5])},9);h $$(1Q)},44:f(2Z){k l=L.44(2Z);j(!l)h T;I(k 1t=l.26;1t!=9;1t=1t.26){j(!1t)h T}h l},42:f(1v){h 9.2G(1v)[0]},2G:f(1v){k 57=[];1v.4Y(\',\').1o(f(43){57.N(9.3B(43))},9);h $$(57)}});L.N=1H.N;L.N({8n:f(1d){h L.3B(\'.\'+1d)},42:1b.U.42,3B:1b.U.3B,2G:1b.U.2G});1N.N({6o:f(2Z,8m){k 1p=[];9.1o(f(l){j(l.2Z==2Z)1p.18(l)});h 1p},6n:f(1d){k 1p=[];9.1o(f(l){j(1b.U.3A.1i(l,1d))1p.18(l)});h 1p},6m:f(41){k 1p=[];9.1o(f(l){1p.N(l.56(41))});h 1p},6l:f(24,K,55){k 1p=[];9.1o(f(l){k 30=l.6k(24);j(!30)h 1p;j(!55)h 1p.18(l);2c(55){1c\'*=\':j(30.15(K))1p.18(l);1P;1c\'=\':j(30==K)1p.18(l);1P;1c\'^=\':j(30.15(\'^\'+K))1p.18(l);1P;1c\'$=\':j(30.15(K+\'$\'))1p.18(l)}h 1p});h 1p}});k 6j=M 11({14:0,1e:f(u){9.u={};I(k n W u){9.u[n]=u[n];9.14++}},8l:f(1O){h 9.u[1O]},1U:f(1O,K){j(K==1K)h T;j(9.u[1O]==3z)9.14++;9.u[1O]=K;h 9},3Z:f(1O){j(9.u[1O]==3z)h T;k u={};9.14--;I(k n W 9.u){j(n!=1O)u[n]=9.u[n]}9.u=u;h 9},1o:f(O,J){I(k n W 9.u)O.1i(J||9,n,9.u[n])},N:f(u){9.1e(1H.N(9.u,u));h 9},1G:f(){h(9.14==0)},1u:f(){k 1u=[];I(k n W 9.u)1u.18(n);h 1u},1z:f(){k 1z=[];I(k n W 9.u)1z.18(9.u[n]);h 1z}});f $H(u){h M 6j(u)};k 2q=M 11({1e:f(1A){j(1A.6i&&1A.6h)h 1A;k 1l=(1A.18)?1A:1A.3s(1g);h 1H.N(1l,2q.U)},6i:f(){k 3y=$A(Y);k 3x=50;j($q(3y[3y.14-1])==\'5N\')3x=3y.8k();k 1l=9.54();3y.1o(f(1A){1A=M 2q(1A);I(k i=0;i<3;i++)1l[i]=G.3e((1l[i]/ 3g * (3g - 3x)) + (1A[i] /3g*3x))});h M 2q(1l)},6h:f(){k 1l=[];I(k i=0;i<3;i++)1l.18(8j-9[i]);h M 2q(1l)}});f $C(1A){h M 2q(1A)};12.N=1H.N;12.N({8i:f(){j(9.53)6g{L.8h("8g",T,1g)}6f(e){}},1a:f(q,O){j(q==\'3u\'){j(9.3Y)O();Q j(!9.V||!9.V.3u){k 3v=f(){j(9.3Y)h;9.3Y=1g;j(9.1f)9.1f=$3Q(9.1f);1b.U.1x.1i(9,\'3u\');9.V.3u=1K}.J(9);j(L.3X&&9.3W){9.1f=f(){j([\'3Y\',\'6d\'].15(L.3X))3v()}.2k(50)}Q j(L.3X&&9.3w){L.8f("<52 2Z=6e 8e 8d=8c:8b(0)><\\/52>");$(\'6e\').8a=f(){j(9.3X==\'6d\')3v()}}Q{9.1a("89",3v);L.1a("88",3v)}}}1b.U.1a.1i(9,q,O);h 9},87:f(6c){h 9.1a(\'3u\',6c)}});12.N({63:f(){j(9.3W||9.51)h 9.86;Q h L.2r.6b||L.4N.6b},62:f(){j(9.3W||9.51)h 9.85;h L.2r.6a||L.4N.6a},60:f(){h L.2r.69},61:f(){h L.2r.68},64:f(){h 9.67||L.2r.3V},65:f(){h 9.66||L.2r.3U},3P:f(){h{\'1V\':{\'x\':9.65(),\'y\':9.64()},\'2A\':{\'x\':9.63(),\'y\':9.62()},\'3O\':{\'x\':9.61(),\'y\':9.60()}}},2O:f(){h{\'x\':0,\'y\':0}}});k X={};X.1C=M 11({2j:f(){h{2K:11.1G,2g:11.1G,5T:11.1G,5Y:X.2Q.4U,4Z:84,1J:\'4I\',2T:1g,5U:50}},1e:f(m){9.r=9.r||1K;9.2N(9.2j(),m);j(9.m.1e)9.m.1e.1i(9)},19:f(){k 2Y=M 5W().5V();j(2Y<9.2Y+9.m.4Z){9.5X=2Y-9.2Y;9.2E();9.2o()}Q{9.1s(1g);9.P=9.B;9.2o();9.1x(\'2g\',9.r,10);9.5Z()}},1U:f(B){9.P=B;9.2o();h 9},2E:f(){9.P=9.2D(9.F,9.B)},2D:f(F,B){h 9.m.5Y(9.5X,F,(B-F),9.m.4Z)},1m:f(F,B){j(!9.m.2T)9.1s();Q j(9.1f)h 9;9.F=F;9.B=B;9.2Y=M 5W().5V();9.1f=9.19.2k(G.3e(83/9.m.5U),9);9.1x(\'2K\',9.r);h 9},1s:f(2h){j(!9.1f)h 9;9.1f=$3Q(9.1f);j(!2h)9.1x(\'5T\',9.r);h 9},82:f(F,B){h 9.1m(F,B)},81:f(2h){h 9.1s(2h)}});X.1C.1T(M 5S);X.1C.1T(M 3c);X.1C.1T(M 3b);X.2Q={5F:f(t,b,c,d){h c*t/d+b},4U:f(t,b,c,d){h-c/2*(G.4T(G.1X*t/d)-1)+b}};X.23={2U:f(n,B){j(n.15(\'1A\',\'i\'))h 9.2q;j(B.15&&B.15(\' \'))h 9.3T;h 9.5R},1M:f(l,n,2X){j(!2X.18)2X=[2X];k F=2X[0],B=2X[1];j(!B&&B!=0){B=F;F=l.1W(n)}k 17=9.2U(n,B);h{F:17.1M(F),B:17.1M(B),17:17}}};X.23.5R={1M:f(K){h 3t(K)},2V:f(F,B,2W){h 2W.2D(F,B)},2F:f(K,1J){h K+1J}};X.23.3T={1M:f(K){h K.18?K:K.4Y(\' \').4X(f(v){h 3t(v)})},2V:f(F,B,2W){k P=[];I(k i=0;i9.m.3N){L.1E(\'2P\',9.1I.3l);L.1a(\'2P\',9.1I.29);9.29(o);9.1x(\'5B\',9.r)}o.1s()},29:f(o){9.4O=T;9.2l.P=o.1y;I(k z W 9.m.2u){9.K.P[z]=o.1y[z]-9.2l.1D[z];j(9.1j[z]){j($2B(9.1j[z][1])&&(9.K.P[z]>9.1j[z][1])){9.K.P[z]=9.1j[z][1];9.4O=1g}Q j($2B(9.1j[z][0])&&(9.K.P[z]<9.1j[z][0])){9.K.P[z]=9.1j[z][0];9.4O=1g}}9.r.1F(9.m.2u[z],9.K.P[z]+9.m.1J)}9.1x(\'4A\',9.r);o.1s()},7k:f(){9.3k.1E(\'4H\',9.1I.1m)},1s:f(){L.1E(\'2P\',9.1I.29);L.1E(\'5A\',9.1I.1s);9.1x(\'2g\',9.r)}});2L.1C.1T(M 3c);2L.1C.1T(M 3b);1b.N({7j:f(m){h M 2L.1C(9,1H.N(m||{},{2u:{x:\'3j\',y:\'3i\'}}))}});k 4J=M 11({2j:f(){h{3h:20,4K:1,3K:f(x,y){9.r.2a(x,y)}}},1e:f(r,m){9.2N(9.2j(),m);9.r=$(r);9.4M=([12,L].15(r))?$(L.4N):9.r},1m:f(){9.4L=9.5z.2y(9);9.4M.1a(\'2P\',9.4L)},1s:f(){9.4M.1E(\'2P\',9.4L);9.1f=$3Q(9.1f)},5z:f(o){9.1y=(9.r==12)?o.5y:o.1y;j(!9.1f)9.1f=9.1V.2k(50,9)},1V:f(){k l=9.r.3P();k 1D=9.r.2O();k 2z={\'x\':0,\'y\':0};I(k z W 9.1y){j(9.1y[z]<(9.m.3h+1D[z])&&l.1V[z]!=0)2z[z]=(9.1y[z]-9.m.3h-1D[z])*9.m.4K;Q j(9.1y[z]+9.m.3h>(l.2A[z]+1D[z])&&l.1V[z]+l.2A[z]!=l.3O[z])2z[z]=(9.1y[z]-l.2A[z]+9.m.3h-1D[z])*9.m.4K}j(2z.y||2z.x)9.1x(\'3K\',[l.1V.x+2z.x,l.1V.y+2z.y])}});4J.1T(M 3c);4J.1T(M 3b);k 4t=M 11({2j:f(){h{3K:11.1G,2g:11.1G,4x:f(1D){9.21.1F(9.p,1D+\'4I\')},3d:3g,1k:\'4G\',3f:T}},1e:f(l,21,m){9.r=$(l);9.21=$(21);9.2N(9.2j(),m);9.4w=-1;9.4v=-1;9.19=-1;9.r.1a(\'4H\',9.5w.2y(9));j(9.m.3f)9.r.1a(\'2M\',9.5x.2y(9));j(9.m.1k==\'4G\'){9.z=\'x\';9.p=\'2i\';9.1B=9.r.2x-9.21.2x;9.4y=9.21.2x/2;9.4z=9.r.4F.J(9.r)}Q j(9.m.1k==\'4E\'){9.z=\'y\';9.p=\'2w\';9.1B=9.r.2v-9.21.2v;9.4y=9.21.2v/2;9.4z=9.r.4D.J(9.r)}9.21.1F(\'1Z\',\'7i\').1F(9.p,0);k 4B={},4C={};4C[9.z]=[0,9.1B];4B[9.z]=9.p;9.29=M 2L.1C(9.21,{1j:4C,3N:0,2u:4B,2K:f(){9.3M()}.J(9),4A:f(){9.3M()}.J(9),2g:f(){9.3M();9.2h()}.J(9)});j(9.m.1e)9.m.1e.1i(9)},1U:f(19){j(19>9.m.3d)19=9.m.3d;Q j(19<0)19=0;9.19=19;9.3L();9.2h();9.1x(\'4x\',9.5v(9.19)+\'\');h 9},5x:f(o){j(o.3f<0)9.1U(9.19+1);Q j(o.3f>0)9.1U(9.19-1);o.1s()},5w:f(o){k 1Z=o.1y[9.z]-9.4z()-9.4y;j(1Z>9.1B)1Z=9.1B;Q j(1Z<0)1Z=0;9.19=9.4u(1Z);9.3L();9.2h();9.1x(\'4x\',1Z+\'\')},3M:f(){9.19=9.4u(9.29.K.P[9.z]);9.3L()},3L:f(){j(9.4w!=9.19){9.4w=9.19;9.1x(\'3K\',9.19)}},2h:f(){j(9.4v!==9.19){9.4v=9.19;9.1x(\'2g\',9.19+\'\')}},4u:f(1Z){h G.3e(1Z/9.1B*9.m.3d)},5v:f(19){h(9.1B)*19/9.m.3d}});4t.1T(M 3c);4t.1T(M 3b);',62,619,'|||||||||this||||||function||return||if|var|el|options|property|event||type|element|||obj|||||||to||||from|Math||for|bind|value|document|new|extend|fn|now|else|args||false|prototype|events|in|Fx|arguments|||Class|window||length|test||css|push|step|addEvent|Element|case|className|initialize|timer|true|style|call|limit|mode|rgb|start|parsed|each|found|param|Array|stop|parent|keys|selector|elements|fireEvent|page|values|color|max|Base|pos|removeEvent|setStyle|empty|Object|bound|unit|null|source|parse|Elements|key|break|filters|array|properties|implement|set|scroll|getStyle|PI|opacity|position||knob|pow|CSS|name||parentNode||match|drag|scrollTo|iCss|switch|delay|create|current|onComplete|end|left|getOptions|periodical|mouse|apply|margin|increase|iTo|Color|documentElement|previous|returns|modifiers|offsetHeight|top|offsetWidth|bindWithEvent|change|size|chk|toInt|compute|setNow|getValue|getElementsBySelector|chains|HTMLElement|hex|onStart|Drag|mousewheel|setOptions|getOffsets|mousemove|Transitions|wrapper|offset|wait|select|getNow|fx|fromTo|time|id|att|Garbage||text|while|replace|newArray||||item|Options|Events|steps|round|wheel|100|area|height|width|handle|checkAndDrag|sqrt|sin|min|iNow|iFrom|join|hexToRgb|parseFloat|domready|domReady|ie|alpha|colors|undefined|hasClass|getElements|getTag|filter|option|Event|toLowerCase|target|rgbToHex|items|onChange|checkStep|draggedKnob|snap|scrollSize|getSize|clear|5625|hidden|Multi|scrollLeft|scrollTop|khtml|readyState|loaded|remove||tagName|getElement|sel|getElementById|clean||splice|preventDefault|stopPropagation|relatedTarget|offsetTop|offsetLeft|setProperty|attribute|whitespace|indexOf|currentStyle|visibility|string|appendChild|inject|instanceof|ms|attempt|bit|forEach|pr0t0typ3|klass|Slider|toStep|previousEnd|previousChange|onTick|half|getPos|onDrag|modSlide|limSlide|getTop|vertical|getLeft|horizontal|mousedown|px|Scroller|velocity|coord|mousemover|body|out|bounceOut|70158|asin|abs|cos|sineInOut|layout|iProps|map|split|duration||opera|script|ie6|copy|operator|getElementsByTagName|els|on|Function|right|pageY|pageX|code|String|DOMMouseScroll|trash|removeEvents|offs|getBrother|getNext|what|gecko|camelCase|object|Native|result|typeof|parseInt|charAt|results|toPosition|clickedElement|scrolledElement|client|getCoords|mouseup|onSnap|distance|bounceIn|525|linear|slideOut|slideIn|hide|adopt|injectAfter|toElement|full|number|iParsed|Styles|Style|Single|Chain|onCancel|fps|getTime|Date|cTime|transition|callChain|getScrollHeight|getScrollWidth|getHeight|getWidth|getScrollTop|getScrollLeft|pageXOffset|pageYOffset|scrollWidth|scrollHeight|clientHeight|clientWidth|init|complete|ie_ready|catch|try|invert|mix|Hash|getAttribute|filterByAttribute|filterByTagName|filterByClassName|filterById|w_|defaults|which|clientY|clientX|special|120|wheelDelta|nodeType|unload|collect|selectedIndex|bottom|class|html|setAttribute|default|replaceWith|createElement|setStyles|childNodes|Sibling|evType|removeEventListener|addEventListener|hyphenate|defaultView|visible|setOpacity|cssText|addClass|removeClass|contents|inside|after|before|insertBefore|where|_elements_extended_|_element_extended_|err|toFloat||Number|trim|toUpperCase|params|regex|iterable|some|every|random|picked|parentize|noinit|relative|makeResizable|detach|bounceInOut|984375|625|9375|backInOut|backOut|backIn|elasticInOut|elasticOut|elasticIn|circInOut|circOut|circIn|expoInOut|expoOut|expoIn|sineOut|sineIn|quintInOut|quintOut|quintIn|quartInOut|quartOut|quartIn|cubicInOut|cubicOut|cubicIn|quadInOut|quadOut|quadIn|toggle|show|overflow|div|Slide|toRight|toLeft|toBottom|toTop|Scroll|effects|effect|clearTimer|custom|1000|500|innerHeight|innerWidth|onDomReady|DOMContentLoaded|load|onreadystatechange|void|javascript|src|defer|write|BackgroundImageCache|execCommand|disableImageCache|255|pop|get|tag|getElementsByClassName|ES|clearChain|chain|delete|backspace|space|esc|down|up|enter|returnValue|cancelBubble|mouseout|fromElement|mouseover|button|rightClick|click|fromCharCode|keyCode|detail|metaKey|meta|altKey|alt|ctrlKey|control|shiftKey|shift|srcElement|Window|textarea|password|radio|checkbox|checked|input|getPosition|offsetParent|do|getProperty|innerHTML|setHTML|setProperties|attributes|getChildren|getParent|previousSibling|lastChild|getLast|nextSibling|firstChild|getFirst|next|getPrevious|detachEvent|addEvents|attachEvent|getPropertyValue|getComputedStyle|padding|zoom|hasLayout|toggleClass|createTextNode|styleSheet|appendText|replaceChild|cloneNode|clone|removeChild|injectInside|injectBefore|embed|bindAsEventListener|pass|finally|setInterval|setTimeout|concat|toString|transparent|capitalize|RegExp|associate|getBoxObjectFor|taintEnabled|navigator|all|ie7|XMLHttpRequest|ActiveXObject|clearInterval|clearTimeout|floor|pick|textnode|nodeValue|nodeName'.split('|'),0,{})) diff --git a/emacs/nxhtml/nxhtml/doc/js/smoothgallery/scripts/mootools.uncompressed.js b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/scripts/mootools.uncompressed.js new file mode 100644 index 0000000..d0ef7e8 --- /dev/null +++ b/emacs/nxhtml/nxhtml/doc/js/smoothgallery/scripts/mootools.uncompressed.js @@ -0,0 +1,4078 @@ +/* +Script: Moo.js + My Object Oriented javascript. + +Author: + Valerio Proietti, + +License: + MIT-style license. + +Credits: + - Class is slightly based on Base.js (c) 2006 Dean Edwards, License + - Some functions are based on those found in prototype.js (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license + - Documentation by Aaron Newton (aaron.newton [at] cnet [dot] com) and Valerio Proietti. +*/ + +/* +Class: Class + The base class object of the framework. + +Arguments: + properties - the collection of properties that apply to the class. Creates a new class, its initialize method will fire upon class instantiation. + +Example: + (start code) + var Cat = new Class({ + initialize: function(name){ + this.name = name; + } + }); + var myCat = new Cat('Micia'); + alert myCat.name; //alerts 'Micia' + (end) +*/ + +var Class = function(properties){ + var klass = function(){ + if (this.initialize && arguments[0] != 'noinit') return this.initialize.apply(this, arguments); + else return this; + }; + for (var property in this) klass[property] = this[property]; + klass.prototype = properties; + return klass; +}; + +/* +Property: empty + Returns an empty function +*/ + +Class.empty = function(){}; + +Class.prototype = { + + /* + Property: extend + Returns the copy of the Class extended with the passed in properties. + + Arguments: + properties - the properties to add to the base class in this new Class. + + Example: + (start code) + var Animal = new Class({ + initialize: function(age){ + this.age = age; + } + }); + var Cat = Animal.extend({ + initialize: function(name, age){ + this.parent(age); //will call the previous initialize; + this.name = name; + } + }); + var myCat = new Cat('Micia', 20); + alert myCat.name; //alerts 'Micia' + alert myCat.age; //alerts 20 + (end) + */ + + extend: function(properties){ + var pr0t0typ3 = new this('noinit'); + + var parentize = function(previous, current){ + if (!previous.apply || !current.apply) return false; + return function(){ + this.parent = previous; + return current.apply(this, arguments); + }; + }; + + for (var property in properties){ + var previous = pr0t0typ3[property]; + var current = properties[property]; + if (previous && previous != current) current = parentize(previous, current) || current; + pr0t0typ3[property] = current; + } + return new Class(pr0t0typ3); + }, + + /* + Property: implement + Implements the passed in properties to the base Class prototypes, altering the base class, unlike . + + Arguments: + properties - the properties to add to the base class. + + Example: + (start code) + var Animal = new Class({ + initialize: function(age){ + this.age = age; + } + }); + Animal.implement({ + setName: function(name){ + this.name = name + } + }); + var myAnimal = new Animal(20); + myAnimal.setName('Micia'); + alert(myAnimal.name); //alerts 'Micia' + (end) + */ + + implement: function(properties){ + for (var property in properties) this.prototype[property] = properties[property]; + } + +}; + +/* Section: Object related Functions */ + +/* +Function: Object.extend + Copies all the properties from the second passed object to the first passed Object. + If you do myWhatever.extend = Object.extend the first parameter will become myWhatever, and your extend function will only need one parameter. + +Example: + (start code) + var firstOb = { + 'name': 'John', + 'lastName': 'Doe' + }; + var secondOb = { + 'age': '20', + 'sex': 'male', + 'lastName': 'Dorian' + }; + Object.extend(firstOb, secondOb); + //firstOb will become: + { + 'name': 'John', + 'lastName': 'Dorian', + 'age': '20', + 'sex': 'male' + }; + (end) + +Returns: + The first object, extended. +*/ + +Object.extend = function(){ + var args = arguments; + args = (args[1]) ? [args[0], args[1]] : [this, args[0]]; + for (var property in args[1]) args[0][property] = args[1][property]; + return args[0]; +}; + +/* +Function: Object.Native + Will add a .extend method to the objects passed as a parameter, equivalent to + +Arguments: + a number of classes/native javascript objects + +*/ + +Object.Native = function(){ + for (var i = 0; i < arguments.length; i++) arguments[i].extend = Class.prototype.implement; +}; + +new Object.Native(Function, Array, String, Number, Class); + +/* +Script: Utility.js + Contains Utility functions + +Author: + Valerio Proietti, + +License: + MIT-style license. +*/ + +//htmlelement mapping + +if (typeof HTMLElement == 'undefined'){ + var HTMLElement = Class.empty; + HTMLElement.prototype = {}; +} + +/* +Function: $type + Returns the type of object that matches the element passed in. + +Arguments: + obj - the object to inspect. + +Example: + >var myString = 'hello'; + >$type(myString); //returns "string" + +Returns: + 'element' - if obj is a DOM element node + 'textnode' - if obj is a DOM text node + 'whitespace' - if obj is a DOM whitespace node + 'array' - if obj is an array + 'object' - if obj is an object + 'string' - if obj is a string + 'number' - if obj is a number + 'boolean' - if obj is a boolean + 'function' - if obj is a function + false - (boolean) if the object is not defined or none of the above. +*/ + +function $type(obj){ + if (obj === null || obj === undefined) return false; + var type = typeof obj; + if (type == 'object'){ + if (obj instanceof HTMLElement) return 'element'; + if (obj instanceof Array) return 'array'; + if (obj.nodeName){ + switch (obj.nodeType){ + case 1: return 'element'; + case 3: return obj.nodeValue.test('\\S') ? 'textnode' : 'whitespace'; + } + } + } + return type; +}; + +/* +Function: $chk + Returns true if the passed in value/object exists or is 0, otherwise returns false. + Useful to accept zeroes. +*/ + +function $chk(obj){ + return !!(obj || obj === 0); +}; + +/* +Function: $pick + Returns the first object if defined, otherwise returns the second. +*/ + +function $pick(obj, picked){ + return ($type(obj)) ? obj : picked; +}; + +/* +Function: $random + Returns a random integer number between the two passed in values. + +Arguments: + min - integer, the minimum value (inclusive). + max - integer, the maximum value (inclusive). + +Returns: + a random integer between min and max. +*/ + +function $random(min, max){ + return Math.floor(Math.random() * (max - min + 1) + min); +}; + +/* +Function: $clear + clears a timeout or an Interval. + +Returns: + null + +Arguments: + timer - the setInterval or setTimeout to clear. + +Example: + >var myTimer = myFunction.delay(5000); //wait 5 seconds and execute my function. + >myTimer = $clear(myTimer); //nevermind + +See also: + , +*/ + +function $clear(timer){ + clearTimeout(timer); + clearInterval(timer); + return null; +}; + +/* Section: Browser Detection */ + +/* +Properties: + window.ie - will be set to true if the current browser is internet explorer (any). + window.ie6 - will be set to true if the current browser is internet explorer 6. + window.ie7 - will be set to true if the current browser is internet explorer 7. + window.khtml - will be set to true if the current browser is Safari/Konqueror. + window.gecko - will be set to true if the current browser is Mozilla/Gecko. +*/ + +if (window.ActiveXObject) window.ie = window[window.XMLHttpRequest ? 'ie7' : 'ie6'] = true; +else if (document.childNodes && !document.all && !navigator.taintEnabled) window.khtml = true; +else if (document.getBoxObjectFor != null) window.gecko = true; + +/* +Script: Array.js + Contains Array prototypes and the function <$A>; + +Author: + Valerio Proietti, + +License: + MIT-style license. +*/ + +/* +Class: Array + A collection of The Array Object prototype methods. +*/ + +//emulated methods + +/* +Property: forEach + Iterates through an array; This method is only available for browsers without native *forEach* support. + For more info see +*/ + +Array.prototype.forEach = Array.prototype.forEach || function(fn, bind){ + for (var i = 0; i < this.length; i++) fn.call(bind, this[i], i, this); +}; + +/* +Property: map + This method is provided only for browsers without native *map* support. + For more info see +*/ + +Array.prototype.map = Array.prototype.map || function(fn, bind){ + var results = []; + for (var i = 0; i < this.length; i++) results[i] = fn.call(bind, this[i], i, this); + return results; +}; + +/* +Property: every + This method is provided only for browsers without native *every* support. + For more info see +*/ + +Array.prototype.every = Array.prototype.every || function(fn, bind){ + for (var i = 0; i < this.length; i++){ + if (!fn.call(bind, this[i], i, this)) return false; + } + return true; +}; + +/* +Property: some + This method is provided only for browsers without native *some* support. + For more info see +*/ + +Array.prototype.some = Array.prototype.some || function(fn, bind){ + for (var i = 0; i < this.length; i++){ + if (fn.call(bind, this[i], i, this)) return true; + } + return false; +}; + +/* +Property: indexOf + This method is provided only for browsers without native *indexOf* support. + For more info see +*/ + +Array.prototype.indexOf = Array.prototype.indexOf || function(item, from){ + from = from || 0; + if (from < 0) from = Math.max(0, this.length + from); + while (from < this.length){ + if(this[from] === item) return from; + from++; + } + return -1; +}; + +//custom methods + +Array.extend({ + + /* + Property: each + Same as . + + Arguments: + fn - the function to execute with each item in the array + bind - optional, the object that the "this" of the function will refer to. + + Example: + >var Animals = ['Cat', 'Dog', 'Coala']; + >Animals.forEach(function(animal){ + > document.write(animal) + >}); + */ + + each: Array.prototype.forEach, + + /* + Property: copy + Copy the array and returns it. + + Returns: + an Array + + Example: + >var letters = ["a","b","c"]; + >var copy = ["a","b","c"].copy(); + */ + + copy: function(){ + var newArray = []; + for (var i = 0; i < this.length; i++) newArray[i] = this[i]; + return newArray; + }, + + /* + Property: remove + Removes all occurrences of an item from the array. + + Arguments: + item - the item to remove + + Returns: + the Array with all occurrences of the item removed. + + Example: + >["1","2","3","2"].remove("2") // ["1","3"]; + */ + + remove: function(item){ + var i = 0; + while (i < this.length){ + if (this[i] == item) this.splice(i, 1); + else i++; + } + return this; + }, + + /* + Property: test + Tests an array for the presence of an item. + + Arguments: + item - the item to search for in the array. + from - optional, the index at which to begin the search, default is 0. If negative, it is taken as the offset from the end of the array. + + Returns: + true - the item was found + false - it wasn't + + Example: + >["a","b","c"].test("a"); // true + >["a","b","c"].test("d"); // false + */ + + test: function(item, from){ + return this.indexOf(item, from) != -1; + }, + + /* + Property: extend + Extends an array with another + + Arguments: + newArray - the array to extend ours with + + Example: + >var Animals = ['Cat', 'Dog', 'Coala']; + >Animals.extend(['Lizard']); + >//Animals is now: ['Cat', 'Dog', 'Coala', 'Lizard']; + */ + + extend: function(newArray){ + for (var i = 0; i < newArray.length; i++) this.push(newArray[i]); + return this; + }, + + /* + Property: associate + Creates an object with key-value pairs based on the array of keywords passed in + and the current content of the array. + + Arguments: + keys - the array of keywords. + + Example: + (start code) + var Animals = ['Cat', 'Dog', 'Coala', 'Lizard']; + var Speech = ['Miao', 'Bau', 'Fruuu', 'Mute']; + var Speeches = Animals.associate(speech); + //Speeches['Miao'] is now Cat. + //Speeches['Bau'] is now Dog. + //... + (end) + */ + + associate: function(keys){ + var obj = {}, length = Math.min(this.length, keys.length); + for (var i = 0; i < length; i++) obj[keys[i]] = this[i]; + return obj; + } + +}); + +/* Section: Utility Functions */ + +/* +Function: $A() + Same as , but as function. + Useful to apply Array prototypes to iterable objects, as a collection of DOM elements or the arguments object. + +Example: + (start code) + function myFunction(){ + $A(arguments).each(argument, function(){ + alert(argument); + }); + }; + //the above will alert all the arguments passed to the function myFunction. + (end) +*/ + +function $A(array){ + return Array.prototype.copy.call(array); +}; + +/* +Function: $each + use to iterate through iterables that are not regular arrays, such as builtin getElementsByTagName calls, or arguments of a function. + +Arguments: + iterable - an iterable element. + function - function to apply to the iterable. + bind - optional, the 'this' of the function will refer to this object. +*/ + +function $each(iterable, fn, bind){ + return Array.prototype.forEach.call(iterable, fn, bind); +}; + +/* +Script: String.js + Contains String prototypes and Number prototypes. + +Author: + Valerio Proietti, + +License: + MIT-style license. +*/ + +/* +Class: String + A collection of The String Object prototype methods. +*/ + +String.extend({ + + /* + Property: test + Tests a string with a regular expression. + + Arguments: + regex - the regular expression you want to match the string with + params - optional, any parameters you want to pass to the regex ('g' has no effect) + + Returns: + true if a match for the regular expression is found in the string, false if not. + See + + Example: + >"I like cookies".test("cookie"); // returns true + >"I like cookies".test("COOKIE", "i") // ignore case, returns true + >"I like cookies".test("cake"); // returns false + */ + + test: function(regex, params){ + return new RegExp(regex, params).test(this); + }, + + /* + Property: toInt + parses a string to an integer. + + Returns: + either an int or "NaN" if the string is not a number. + + Example: + >var value = "10px".toInt(); // value is 10 + */ + + toInt: function(){ + return parseInt(this); + }, + + toFloat: function(){ + return parseFloat(this); + }, + + /* + Property: camelCase + Converts a hiphenated string to a camelcase string. + + Example: + >"I-like-cookies".camelCase(); //"ILikeCookies" + + Returns: + the camel cased string + */ + + camelCase: function(){ + return this.replace(/-\D/g, function(match){ + return match.charAt(1).toUpperCase(); + }); + }, + + /* + Property: hyphenate + Converts a camelCased string to a hyphen-ated string. + + Example: + >"ILikeCookies".hyphenate(); //"I-like-cookies" + */ + + hyphenate: function(){ + return this.replace(/\w[A-Z]/g, function(match){ + return (match.charAt(0)+'-'+match.charAt(1).toLowerCase()); + }); + }, + + /* + Property: capitalize + Converts the first letter in each word of a string to Uppercase. + + Example: + >"i like cookies".capitalize(); //"I Like Cookies" + + Returns: + the capitalized string + */ + + capitalize: function(){ + return this.toLowerCase().replace(/\b[a-z]/g, function(match){ + return match.toUpperCase(); + }); + }, + + /* + Property: trim + Trims the leading and trailing spaces off a string. + + Example: + >" i like cookies ".trim() //"i like cookies" + + Returns: + the trimmed string + */ + + trim: function(){ + return this.replace(/^\s+|\s+$/g, ''); + }, + + /* + Property: clean + trims () a string AND removes all the double spaces in a string. + + Returns: + the cleaned string + + Example: + >" i like cookies \n\n".clean() //"i like cookies" + */ + + clean: function(){ + return this.replace(/\s{2,}/g, ' ').trim(); + }, + + /* + Property: rgbToHex + Converts an RGB value to hexidecimal. The string must be in the format of "rgb(255, 255, 255)" or "rgba(255, 255, 255, 1)"; + + Arguments: + array - boolean value, defaults to false. Use true if you want the array ['FF', '33', '00'] as output instead of #FF3300 + + Returns: + hex string or array. returns transparent if the fourth value of rgba in input string is 0, + + Example: + >"rgb(17,34,51)".rgbToHex(); //"#112233" + >"rgba(17,34,51,0)".rgbToHex(); //"transparent" + >"rgb(17,34,51)".rgbToHex(true); //[11,22,33] + */ + + rgbToHex: function(array){ + var rgb = this.match(/\d{1,3}/g); + return (rgb) ? rgb.rgbToHex(array) : false; + }, + + /* + Property: hexToRgb + Converts a hexidecimal color value to RGB. Input string must be the hex color value (with or without the hash). Also accepts triplets ('333'); + + Arguments: + array - boolean value, defaults to false. Use true if you want the array ['255', '255', '255'] as output instead of "rgb(255,255,255)"; + + Returns: + rgb string or array. + + Example: + >"#112233".hexToRgb(); //"rgb(17,34,51)" + >"#112233".hexToRgb(true); //[17,34,51] + */ + + hexToRgb: function(array){ + var hex = this.match('^#?(\\w{1,2})(\\w{1,2})(\\w{1,2})$'); + return (hex) ? hex.hexToRgb(array) : false; + } + +}); + +Array.extend({ + + rgbToHex: function(array){ + if (this.length < 3) return false; + if (this[3] && this[3] == 0) return 'transparent'; + var hex = []; + for (var i = 0; i < 3; i++){ + var bit = (this[i]-0).toString(16); + hex.push(bit.length == 1 ? '0'+bit : bit); + } + return array ? hex : '#'+hex.join(''); + }, + + hexToRgb: function(array){ + if (this.length != 4) return false; + var rgb = []; + for (var i = 1; i < 4; i++){ + if (this[i].length == 1) this[i] += this[i]; + rgb.push(parseInt(this[i], 16)); + } + return array ? rgb : 'rgb('+rgb.join(',')+')'; + } + +}); + +/* +Class: Number + contains the internal method toInt. +*/ + +Number.extend({ + + /* + Property: toInt + Returns this number; useful because toInt must work on both Strings and Numbers. + */ + + toInt: function(){ + return parseInt(this); + }, + + toFloat: function(){ + return parseFloat(this); + } + +}); + +/* +Script: Function.js + Contains Function prototypes and utility functions . + +Author: + Valerio Proietti, + +License: + MIT-style license. + +Credits: + - Some functions are inspired by those found in prototype.js (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license +*/ + +/* +Class: Function + A collection of The Function Object prototype methods. +*/ + +Function.extend({ + + create: function(options){ + var fn = this; + options = Object.extend({ + 'bind': fn, + 'event': false, + 'arguments': null, + 'delay': false, + 'periodical': false, + 'attempt': false + }, options || {}); + if (options.arguments != null && typeof options.arguments != 'undefined' && !(options.arguments instanceof Array)) + options.arguments = [options.arguments]; + return function(event){ + var args = options.arguments || arguments; + if (options.event){ + event = (options.event === true) ? event || window.event : new options.event(event); + args = [event].concat(args); + } + var returns = function(){ + return fn.apply(options.bind, args); + }; + if (options.delay) return setTimeout(returns, options.delay); + if (options.periodical) return setInterval(returns, options.periodical); + if (options.attempt){ + try { + var result = returns(); + } catch(err){ + result = err; + } finally { + return result; + } + } else return returns(); + }; + }, + + /* + Property: pass + Shortcut to create closures with arguments and bind. + + Returns: + a function. + + Arguments: + args - the arguments passed. must be an array if arguments > 1 + bind - optional, the object that the "this" of the function will refer to. + + Example: + >myFunction.pass([arg1, arg2], myElement); + */ + + pass: function(args, bind){ + return this.create({'arguments': args, 'bind': bind}); + }, + + /* + Property: attempt + Tries to execute the function, returns either the function results or the error. + + Arguments: + args - the arguments passed. must be an array if arguments > 1 + bind - optional, the object that the "this" of the function will refer to. + + Example: + >myFunction.attempt([arg1, arg2], myElement); + */ + + attempt: function(args, bind){ + return this.create({'arguments': args, 'bind': bind, 'attempt': true})(); + }, + + /* + Property: bind + method to easily create closures with "this" altered. + + Arguments: + bind - optional, the object that the "this" of the function will refer to. + args - optional, the arguments passed. must be an array if arguments > 1 + + Returns: + a function. + + Example: + >function myFunction(){ + > this.setStyle('color', 'red'); + > // note that 'this' here refers to myFunction, not an element + > // we'll need to bind this function to the element we want to alter + >}; + >var myBoundFunction = myFunction.bind(myElement); + >myBoundFunction(); // this will make the element myElement red. + */ + + bind: function(bind, args){ + return this.create({'bind': bind, 'arguments': args}); + }, + + /* + Property: bindAsEventListener + cross browser method to pass event firer + + Arguments: + bind - optional, the object that the "this" of the function will refer to. + args - optional, the arguments passed. must be an array if arguments > 1 + + Returns: + a function with the parameter bind as its "this" and as a pre-passed argument event or window.event, depending on the browser. + + Example: + >function myFunction(event){ + > alert(event.clientx) //returns the coordinates of the mouse.. + >}; + >myElement.onclick = myFunction.bindAsEventListener(myElement); + */ + + bindAsEventListener: function(bind, args){ + return this.create({'bind': bind, 'event': true, 'arguments': args}); + }, + + /* + Property: delay + Delays the execution of a function by a specified duration. + + Arguments: + ms - the duration to wait in milliseconds + bind - optional, the object that the "this" of the function will refer to. + args - optional, the arguments passed. must be an array if arguments > 1 + + Example: + >myFunction.delay(50, myElement) //wait 50 milliseconds, then call myFunction and bind myElement to it + >(function(){alert('one second later...')}).delay(1000); //wait a second and alert + */ + + delay: function(ms, bind, args){ + return this.create({'delay': ms, 'bind': bind, 'arguments': args})(); + }, + + /* + Property: periodical + Executes a function in the specified intervals of time + + Arguments: + ms - the duration of the intervals between executions. + bind - optional, the object that the "this" of the function will refer to. + args - optional, the arguments passed. must be an array if arguments > 1 + */ + + periodical: function(ms, bind, args){ + return this.create({'periodical': ms, 'bind': bind, 'arguments': args})(); + } + +}); + +/* +Script: Element.js + Contains useful Element prototypes, to be used with the dollar function <$>. + +Author: + Valerio Proietti, + +License: + MIT-style license. + +Credits: + - Some functions are inspired by those found in prototype.js (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license +*/ + +/* +Class: Element + Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. +*/ + +var Element = new Class({ + + /* + Property: initialize + Creates a new element of the type passed in. + + Arguments: + el - the tag name for the element you wish to create. + + Example: + >var div = new Element('div'); + */ + + initialize: function(el){ + if ($type(el) == 'string') el = document.createElement(el); + return $(el); + } + +}); + +/* +Function: $() + returns the element passed in with all the Element prototypes applied. + +Arguments: + el - a reference to an actual element or a string representing the id of an element + +Example: + >$('myElement') // gets a DOM element by id with all the Element prototypes applied. + >var div = document.getElementById('myElement'); + >$(div) //returns an Element also with all the mootools extentions applied. + + You'll use this when you aren't sure if a variable is an actual element or an id, as + well as just shorthand for document.getElementById(). + +Returns: + a DOM element or false (if no id was found). + +Note: + you need to call $ on an element only once to get all the prototypes. + But its no harm to call it multiple times, as it will detect if it has been already extended. +*/ + +function $(el){ + if (!el) return false; + if (el._element_extended_ || [window, document].test(el)) return el; + if ($type(el) == 'string') el = document.getElementById(el); + if ($type(el) != 'element') return false; + if (['object', 'embed'].test(el.tagName.toLowerCase()) || el.extend) return el; + el._element_extended_ = true; + Garbage.collect(el); + el.extend = Object.extend; + if (!(el instanceof HTMLElement)) el.extend(Element.prototype); + return el; +}; + +//elements class + +var Elements = new Class({}); + +new Object.Native(Elements); + +document.getElementsBySelector = document.getElementsByTagName; + +/* +Function: $$() + Selects, and extends DOM elements. + +Arguments: + HTMLCollection(document.getElementsByTagName, element.childNodes), an array of elements, a string. + +Note: + if you loaded , $$ will also accept CSS Selectors. + +Example: + >$$('a') //an array of all anchor tags on the page + >$$('a', 'b') //an array of all anchor and bold tags on the page + >$$('#myElement') //array containing only the element with id = myElement. (only with ) + >$$('#myElement a.myClass') //an array of all anchor tags with the class "myClass" within the DOM element with id "myElement" (only with ) + +Returns: + array - array of all the dom elements matched +*/ + +function $$(){ + if (!arguments) return false; + if (arguments.length == 1){ + if (!arguments[0]) return false; + if (arguments[0]._elements_extended_) return arguments[0]; + } + var elements = []; + $each(arguments, function(selector){ + switch ($type(selector)){ + case 'element': elements.push($(selector)); break; + case 'string': selector = document.getElementsBySelector(selector); + default: + if (selector.length){ + $each(selector, function(el){ + if ($(el)) elements.push(el); + }); + } + } + }); + elements._elements_extended_ = true; + return Object.extend(elements, new Elements); +}; + +Elements.Multi = function(property){ + return function(){ + var args = arguments; + var items = []; + var elements = true; + $each(this, function(el){ + var returns = el[property].apply(el, args); + if ($type(returns) != 'element') elements = false; + items.push(returns); + }); + if (elements) items = $$(items); + return items; + }; +}; + +Element.extend = function(properties){ + for (var property in properties){ + HTMLElement.prototype[property] = properties[property]; + Element.prototype[property] = properties[property]; + Elements.prototype[property] = Elements.Multi(property); + } +}; + +Element.extend({ + + inject: function(el, where){ + el = $(el) || new Element(el); + switch (where){ + case "before": $(el.parentNode).insertBefore(this, el); break; + case "after": + if (!el.getNext()) $(el.parentNode).appendChild(this); + else $(el.parentNode).insertBefore(this, el.getNext()); + break; + case "inside": el.appendChild(this); + } + return this; + }, + + /* + Property: injectBefore + Inserts the Element before the passed element. + + Parameteres: + el - a string representing the element to be injected in (myElementId, or div), or an element reference. + If you pass div or another tag, the element will be created. + + Example: + >html: + >
+ >
+ >js: + >$('mySecondElement').injectBefore('myElement'); + >resulting html: + >
+ >
+ + */ + + injectBefore: function(el){ + return this.inject(el, 'before'); + }, + + /* + Property: injectAfter + Same as , but inserts the element after. + */ + + injectAfter: function(el){ + return this.inject(el, 'after'); + }, + + /* + Property: injectInside + Same as , but inserts the element inside. + */ + + injectInside: function(el){ + return this.inject(el, 'inside'); + }, + + /* + Property: adopt + Inserts the passed element inside the Element. Works as but in reverse. + + Parameteres: + el - a string representing the element to be injected in (myElementId, or div), or an element reference. + If you pass div or another tag, the element will be created. + */ + + adopt: function(el){ + this.appendChild($(el) || new Element(el)); + return this; + }, + + /* + Property: remove + Removes the Element from the DOM. + + Example: + >$('myElement').remove() //bye bye + */ + + remove: function(){ + this.parentNode.removeChild(this); + return this; + }, + + /* + Property: clone + Clones the Element and returns the cloned one. + + Returns: + the cloned element + + Example: + >var clone = $('myElement').clone().injectAfter('myElement'); + >//clones the Element and append the clone after the Element. + */ + + clone: function(contents){ + var el = this.cloneNode(contents !== false); + return $(el); + }, + + /* + Property: replaceWith + Replaces the Element with an element passed. + + Parameteres: + el - a string representing the element to be injected in (myElementId, or div), or an element reference. + If you pass div or another tag, the element will be created. + + Returns: + the passed in element + + Example: + >$('myOldElement').replaceWith($('myNewElement')); //$('myOldElement') is gone, and $('myNewElement') is in its place. + */ + + replaceWith: function(el){ + el = $(el) || new Element(el); + this.parentNode.replaceChild(el, this); + return el; + }, + + /* + Property: appendText + Appends text node to a DOM element. + + Arguments: + text - the text to append. + + Example: + >
hey
+ >$('myElement').appendText(' howdy'); //myElement innerHTML is now "hey howdy" + */ + + appendText: function(text){ + if (window.ie){ + switch(this.getTag()){ + case 'style': this.styleSheet.cssText = text; return this; + case 'script': this.setProperty('text', text); return this; + } + } + this.appendChild(document.createTextNode(text)); + return this; + }, + + /* + Property: hasClass + Tests the Element to see if it has the passed in className. + + Returns: + true - the Element has the class + false - it doesn't + + Arguments: + className - the class name to test. + + Example: + >
+ >$('myElement').hasClass('testClass'); //returns true + */ + + hasClass: function(className){ + return this.className.test('(?:^|\\s+)' + className + '(?:\\s+|$)'); + }, + + /* + Property: addClass + Adds the passed in class to the Element, if the element doesnt already have it. + + Arguments: + className - the class name to add + + Example: + >
+ >$('myElement').addClass('newClass'); //
+ */ + + addClass: function(className){ + if (!this.hasClass(className)) this.className = (this.className+' '+className).clean(); + return this; + }, + + /* + Property: removeClass + works like , but removes the class from the element. + */ + + removeClass: function(className){ + if (this.hasClass(className)) this.className = this.className.replace(className, '').clean(); + return this; + }, + + /* + Property: toggleClass + Adds or removes the passed in class name to the element, depending on if it's present or not. + + Arguments: + className - the class to add or remove + + Example: + >
+ >$('myElement').toggleClass('myClass'); + >
+ >$('myElement').toggleClass('myClass'); + >
+ */ + + toggleClass: function(className){ + return this.hasClass(className) ? this.removeClass(className) : this.addClass(className); + }, + + /* + Property: setStyle + Sets a css property to the Element. + + Arguments: + property - the property to set + value - the value to which to set it + + Example: + >$('myElement').setStyle('width', '300px'); //the width is now 300px + */ + + setStyle: function(property, value){ + if (property == 'opacity') this.setOpacity(parseFloat(value)); + else this.style[property.camelCase()] = (value.push) ? value.rgbToHex() : value; + return this; + }, + + /* + Property: setStyles + Applies a collection of styles to the Element. + + Arguments: + source - an object or string containing all the styles to apply + + Examples: + >$('myElement').setStyles({ + > border: '1px solid #000', + > width: '300px', + > height: '400px' + >}); + + OR + + >$('myElement').setStyle('border: 1px solid #000; width: 300px; height: 400px;'); + */ + + setStyles: function(source){ + switch ($type(source)){ + case 'object': + for (var property in source) this.setStyle(property, source[property]); + break; + case 'string': + if (window.ie) this.cssText = source; + else this.setAttribute('style', source); + } + return this; + }, + + /* + Property: setOpacity + Sets the opacity of the Element, and sets also visibility == "hidden" if opacity == 0, and visibility = "visible" if opacity == 1. + + Arguments: + opacity - Accepts numbers from 0 to 1. + + Example: + >$('myElement').setOpacity(0.5) //make it 50% transparent + */ + + setOpacity: function(opacity){ + if (opacity == 0){ + if(this.style.visibility != "hidden") this.style.visibility = "hidden"; + } else { + if(this.style.visibility != "visible") this.style.visibility = "visible"; + } + if (!this.currentStyle || !this.currentStyle.hasLayout) this.style.zoom = 1; + if (window.ie) this.style.filter = "alpha(opacity=" + opacity*100 + ")"; + this.style.opacity = this.opacity = opacity; + return this; + }, + + /* + Property: getStyle + Returns the style of the Element given the property passed in. + + Arguments: + property - the css style property you want to retrieve + + Example: + >$('myElement').getStyle('width'); //returns "400px" + >//but you can also use + >$('myElement').getStyle('width').toInt(); //returns "400" + + Returns: + the style as a string + */ + + getStyle: function(property){ + property = property.camelCase(); + var style = this.style[property] || false; + if (!$chk(style)){ + if (property == 'opacity') return $chk(this.opacity) ? this.opacity : 1; + if (['margin', 'padding'].test(property)){ + return [this.getStyle(property+'-top') || 0, this.getStyle(property+'-right') || 0, + this.getStyle(property+'-bottom') || 0, this.getStyle(property+'-left') || 0].join(' '); + } + if (document.defaultView) style = document.defaultView.getComputedStyle(this, null).getPropertyValue(property.hyphenate()); + else if (this.currentStyle) style = this.currentStyle[property]; + } + return (style && property.test('color', 'i') && style.test('rgb')) ? style.rgbToHex() : style; + }, + + /* + Property: addEvent + Attaches an event listener to a DOM element. + + Arguments: + type - the event to monitor ('click', 'load', etc) without the prefix 'on'. + fn - the function to execute + + Example: + >$('myElement').addEvent('click', function(){alert('clicked!')}); + */ + + addEvent: function(type, fn){ + this.events = this.events || {}; + this.events[type] = this.events[type] || {'keys': [], 'values': []}; + if (!this.events[type].keys.test(fn)){ + this.events[type].keys.push(fn); + if (this.addEventListener){ + this.addEventListener((type == 'mousewheel' && window.gecko) ? 'DOMMouseScroll' : type, fn, false); + } else { + fn = fn.bind(this); + this.attachEvent('on'+type, fn); + this.events[type].values.push(fn); + } + } + return this; + }, + + addEvents: function(source){ + if (source){ + for (var type in source) this.addEvent(type, source[type]); + } + return this; + }, + + /* + Property: removeEvent + Works as Element.addEvent, but instead removes the previously added event listener. + */ + + removeEvent: function(type, fn){ + if (this.events && this.events[type]){ + var pos = this.events[type].keys.indexOf(fn); + if (pos == -1) return this; + var key = this.events[type].keys.splice(pos,1)[0]; + if (this.removeEventListener){ + this.removeEventListener((type == 'mousewheel' && window.gecko) ? 'DOMMouseScroll' : type, key, false); + } else { + this.detachEvent('on'+type, this.events[type].values.splice(pos,1)[0]); + } + } + return this; + }, + + /* + Property: removeEvents + removes all events of a certain type from an element. if no argument is passed in, removes all events. + */ + + removeEvents: function(type){ + if (this.events){ + if (type){ + if (this.events[type]){ + this.events[type].keys.each(function(fn){ + this.removeEvent(type, fn); + }, this); + this.events[type] = null; + } + } else { + for (var evType in this.events) this.removeEvents(evType); + this.events = null; + } + } + return this; + }, + + /* + Property: fireEvent + executes all events of the specified type present in the element. + */ + + fireEvent: function(type, args){ + if (this.events && this.events[type]){ + args = args || []; + if ($type(args) != 'array') args = [args]; + this.events[type].keys.each(function(fn){ + fn.apply(this, args); + }, this); + } + }, + + getBrother: function(what){ + var el = this[what+'Sibling']; + while ($type(el) == 'whitespace') el = el[what+'Sibling']; + return $(el); + }, + + /* + Property: getPrevious + Returns the previousSibling of the Element, excluding text nodes. + + Example: + >$('myElement').getPrevious(); //get the previous DOM element from myElement + + Returns: + the sibling element or undefined if none found. + */ + + getPrevious: function(){ + return this.getBrother('previous'); + }, + + /* + Property: getNext + Works as Element.getPrevious, but tries to find the nextSibling. + */ + + getNext: function(){ + return this.getBrother('next'); + }, + + /* + Property: getFirst + Works as , but tries to find the firstChild. + */ + + getFirst: function(){ + var el = this.firstChild; + while ($type(el) == 'whitespace') el = el.nextSibling; + return $(el); + }, + + /* + Property: getLast + Works as , but tries to find the lastChild. + */ + + getLast: function(){ + var el = this.lastChild; + while ($type(el) == 'whitespace') el = el.previousSibling; + return $(el); + }, + + /* + Property: getParent + returns the $(element.parentNode) + */ + + getParent: function(){ + return $(this.parentNode); + }, + + /* + Property: getChildren + returns all the $(element.childNodes), excluding text nodes. Returns as . + */ + + getChildren: function(){ + return $$(this.childNodes); + }, + + /* + Property: setProperty + Sets an attribute for the Element. + + Arguments: + property - the property to assign the value passed in + value - the value to assign to the property passed in + + Example: + >$('myImage').setProperty('src', 'whatever.gif'); //myImage now points to whatever.gif for its source + */ + + setProperty: function(property, value){ + switch (property){ + case 'class': this.className = value; break; + case 'style': this.setStyles(value); break; + case 'name': if (window.ie6){ + var el = $(document.createElement('<'+this.getTag()+' name="'+value+'" />')); + $each(this.attributes, function(attribute){ + if (attribute.name != 'name') el.setProperty(attribute.name, attribute.value); + }); + if (this.parentNode) this.replaceWith(el); + return el; + } + default: this.setAttribute(property, value); + } + return this; + }, + + /* + Property: setProperties + Sets numerous attributes for the Element. + + Arguments: + source - an object with key/value pairs. + + Example: + >$('myElement').setProperties({ + > src: 'whatever.gif', + > alt: 'whatever dude' + >}); + >whatever dude + */ + + setProperties: function(source){ + for (var property in source) this.setProperty(property, source[property]); + return this; + }, + + /* + Property: setHTML + Sets the innerHTML of the Element. + + Arguments: + html - the new innerHTML for the element. + + Example: + >$('myElement').setHTML(newHTML) //the innerHTML of myElement is now = newHTML + */ + + setHTML: function(html){ + this.innerHTML = html; + return this; + }, + + /* + Property: getProperty + Gets the an attribute of the Element. + + Arguments: + property - the attribute to retrieve + + Example: + >$('myImage').getProperty('src') // returns whatever.gif + + Returns: + the value, or an empty string + */ + + getProperty: function(property){ + return (property == 'class') ? this.className : this.getAttribute(property); + }, + + /* + Property: getTag + Returns the tagName of the element in lower case. + + Example: + >$('myImage').getTag() // returns 'img' + + Returns: + The tag name in lower case + */ + + getTag: function(){ + return this.tagName.toLowerCase(); + }, + + getOffsets: function(){ + var el = this, offsetLeft = 0, offsetTop = 0; + do { + offsetLeft += el.offsetLeft || 0; + offsetTop += el.offsetTop || 0; + el = el.offsetParent; + } while (el); + return {'x': offsetLeft, 'y': offsetTop}; + }, + + /* + Property: scrollTo + scrolls the element to the specified coordinated (if the element has an overflow) + + Arguments: + x - the x coordinate + y - the y coordinate + + Example: + >$('myElement').scrollTo(0, 100) + */ + + scrollTo: function(x, y){ + this.scrollLeft = x; + this.scrollTop = y; + }, + + /* + Property: getSize + return an Object representing the size/scroll values of the element. + + Example: + (start code) + $('myElement').getSize(); + (end) + + Returns: + (start code) + { + 'scroll': {'x': 100, 'y': 100}, + 'size': {'x': 200, 'y': 400}, + 'scrollSize': {'x': 300, 'y': 500} + } + (end) + */ + + getSize: function(){ + return { + 'scroll': {'x': this.scrollLeft, 'y': this.scrollTop}, + 'size': {'x': this.offsetWidth, 'y': this.offsetHeight}, + 'scrollSize': {'x': this.scrollWidth, 'y': this.scrollHeight} + }; + }, + + /* + Property: getTop + Returns the distance from the top of the window to the Element. + */ + + getTop: function(){ + return this.getOffsets().y; + }, + + /* + Property: getLeft + Returns the distance from the left of the window to the Element. + */ + + getLeft: function(){ + return this.getOffsets().x; + }, + + /* + Property: getPosition + Returns an object with width, height, left, right, top, and bottom, representing the values of the Element + + Example: + (start code) + var myValues = $('myElement').getPosition(); + (end) + + Returns: + (start code) + { + width: 200, + height: 300, + left: 100, + top: 50, + right: 300, + bottom: 350 + } + (end) + */ + + getPosition: function(){ + var offs = this.getOffsets(); + var obj = { + 'width': this.offsetWidth, + 'height': this.offsetHeight, + 'left': offs.x, + 'top': offs.y + }; + obj.right = obj.left + obj.width; + obj.bottom = obj.top + obj.height; + return obj; + }, + + /* + Property: getValue + Returns the value of the Element, if its tag is textarea, select or input. no multiple select support. + */ + + getValue: function(){ + switch (this.getTag()){ + case 'select': if (this.selectedIndex != -1) return this.options[this.selectedIndex].value; break; + case 'input': if (!(this.checked && ['checkbox', 'radio'].test(this.type)) && !['hidden', 'text', 'password'].test(this.type)) break; + case 'textarea': return this.value; + } + return false; + } + +}); + +var Window = window; + +window.addEvent = document.addEvent = Element.prototype.addEvent; +window.removeEvent = document.removeEvent = Element.prototype.removeEvent; + +var Garbage = { + + elements: [], + + collect: function(element){ + Garbage.elements.push(element); + }, + + trash: function(){ + window.removeEvent('unload', Garbage.trash); + Garbage.elements.each(function(el){ + el.removeEvents(); + for (var p in Element.prototype) HTMLElement[p] = window[p] = document[p] = el[p] = null; + el.extend = null; + }); + } + +}; + +window.addEvent('unload', Garbage.trash); + +/* +Script: Event.js + Event class + +Author: + Valerio Proietti, , Michael Jackson, + +License: + MIT-style license. +*/ + +/* +Class: Event + Cross browser methods to manage events. + +Arguments: + event - the event + +Properties: + shift - true if the user pressed the shift + control - true if the user pressed the control + alt - true if the user pressed the alt + meta - true if the user pressed the meta key + code - the keycode of the key pressed + page.x - the x position of the mouse, relative to the full window + page.y - the y position of the mouse, relative to the full window + client.x - the x position of the mouse, relative to the viewport + client.y - the y position of the mouse, relative to the viewport + key - the key pressed as a lowercase string. key also returns 'enter', 'up', 'down', 'left', 'right', 'space', 'backspace', 'delete', 'esc'. Handy for these special keys. + target - the event target + relatedTarget - the event related target + +Example: + (start code) + $('myLink').onkeydown = function(event){ + var event = new Event(event); + //event is now the Event class. + alert(event.key); //returns the lowercase letter pressed + alert(event.shift); //returns true if the key pressed is shift + if (event.key == 's' && event.control) alert('document saved'); + }; + (end) +*/ + +var Event = new Class({ + + initialize: function(event){ + this.event = event || window.event; + this.type = this.event.type; + this.target = this.event.target || this.event.srcElement; + if (this.target.nodeType == 3) this.target = this.target.parentNode; // Safari + this.shift = this.event.shiftKey; + this.control = this.event.ctrlKey; + this.alt = this.event.altKey; + this.meta = this.event.metaKey; + if (['DOMMouseScroll', 'mousewheel'].test(this.type)){ + this.wheel = this.event.wheelDelta ? (this.event.wheelDelta / (window.opera ? -120 : 120)) : -(this.event.detail || 0) / 3; + } else if (this.type.test('key')){ + this.code = this.event.which || this.event.keyCode; + for (var name in Event.keys){ + if (Event.keys[name] == this.code) var special = name; + } + this.key = special || String.fromCharCode(this.code).toLowerCase(); + + } else if (this.type.test('mouse') || this.type == 'click'){ + this.page = { + 'x': this.event.pageX || this.event.clientX + document.documentElement.scrollLeft, + 'y': this.event.pageY || this.event.clientY + document.documentElement.scrollTop + }; + this.client = { + 'x': this.event.pageX ? this.event.pageX - window.pageXOffset : this.event.clientX, + 'y': this.event.pageY ? this.event.pageY - window.pageYOffset : this.event.clientY + }; + this.rightClick = (this.event.which == 3) || (this.event.button == 2); + switch (this.type){ + case 'mouseover': this.relatedTarget = this.event.relatedTarget || this.event.fromElement; break; + case 'mouseout': this.relatedTarget = this.event.relatedTarget || this.event.toElement; + } + } + }, + + /* + Property: stop + cross browser method to stop an event + */ + + stop: function() { + this.stopPropagation(); + this.preventDefault(); + return this; + }, + + /* + Property: stopPropagation + cross browser method to stop the propagation of an event + */ + + stopPropagation: function(){ + if (this.event.stopPropagation) this.event.stopPropagation(); + else this.event.cancelBubble = true; + return this; + }, + + /* + Property: preventDefault + cross browser method to prevent the default action of the event + */ + + preventDefault: function(){ + if (this.event.preventDefault) this.event.preventDefault(); + else this.event.returnValue = false; + return this; + } + +}); + +Event.keys = { + 'enter': 13, + 'up': 38, + 'down': 40, + 'left': 37, + 'right': 39, + 'esc': 27, + 'space': 32, + 'backspace': 8, + 'delete': 46 +}; + +Function.extend({ + + /* + Property: bindWithEvent + automatically passes mootools Event Class. + + Arguments: + bind - optional, the object that the "this" of the function will refer to. + + Returns: + a function with the parameter bind as its "this" and as a pre-passed argument event or window.event, depending on the browser. + + Example: + >function myFunction(event){ + > alert(event.clientx) //returns the coordinates of the mouse.. + >}; + >myElement.onclick = myFunction.bindWithEvent(myElement); + */ + + bindWithEvent: function(bind, args){ + return this.create({'bind': bind, 'arguments': args, 'event': Event}); + } + +}); + + +/* +Script: Common.js + Contains common implementations for custom classes. In Mootools is implemented in and . + +Author: + Valerio Proietti, + +License: + MIT-style license. +*/ + +/* +Class: Chain + An "Utility" Class. Its methods can be implemented with into any . + Currently implemented in and . In for example, is used to execute a list of function, one after another, once the effect is completed. + The functions will not be fired all togheter, but one every completion, to create custom complex animations. + +Example: + (start code) + var myFx = new Fx.Style('element', 'opacity'); + + myFx.start(1,0).chain(function(){ + myFx.start(0,1); + }).chain(function(){ + myFx.start(1,0); + }).chain(function(){ + myFx.start(0,1); + }); + //the element will appear and disappear three times + (end) +*/ + +var Chain = new Class({ + + /* + Property: chain + adds a function to the Chain instance stack. + + Arguments: + fn - the function to append. + */ + + chain: function(fn){ + this.chains = this.chains || []; + this.chains.push(fn); + return this; + }, + + /* + Property: callChain + Executes the first function of the Chain instance stack, then removes it. The first function will then become the second. + */ + + callChain: function(){ + if (this.chains && this.chains.length) this.chains.splice(0, 1)[0].delay(10, this); + }, + + /* + Property: clearChain + Clears the stack of a Chain instance. + */ + + clearChain: function(){ + this.chains = []; + } + +}); + +/* +Class: Events + An "Utility" Class. Its methods can be implemented with into any . + In Class, for example, is used to give the possibility add any number of functions to the Effects events, like onComplete, onStart, onCancel + +Example: + (start code) + var myFx = new Fx.Style('element', 'opacity').addEvent('onComplete', function(){ + alert('the effect is completed'); + }).addEvent('onComplete', function(){ + alert('I told you the effect is completed'); + }); + + myFx.start(0,1); + //upon completion it will display the 2 alerts, in order. + (end) +*/ + +var Events = new Class({ + + /* + Property: addEvent + adds an event to the stack of events of the Class instance. + */ + + addEvent: function(type, fn){ + if (fn != Class.empty){ + this.events = this.events || {}; + this.events[type] = this.events[type] || []; + if (!this.events[type].test(fn)) this.events[type].push(fn); + } + return this; + }, + + /* + Property: fireEvent + fires all events of the specified type in the Class instance. + */ + + fireEvent: function(type, args, delay){ + if (this.events && this.events[type]){ + this.events[type].each(function(fn){ + fn.create({'bind': this, 'delay': delay, 'arguments': args})(); + }, this); + } + return this; + }, + + /* + Property: removeEvent + removes an event from the stack of events of the Class instance. + */ + + removeEvent: function(type, fn){ + if (this.events && this.events[type]) this.events[type].remove(fn); + return this; + } + +}); + +/* +Class: Options + An "Utility" Class. Its methods can be implemented with into any . + Used to automate the options settings, also adding Class when the option begins with on. +*/ + +var Options = new Class({ + + /* + Property: setOptions + sets this.options + + Arguments: + defaults - the default set of options + options - the user entered options. can be empty too. + + Note: + if your Class has implemented, every option beginning with on, followed by a capital letter (onComplete) becomes an Class instance event. + */ + + setOptions: function(defaults, options){ + this.options = Object.extend(defaults, options); + if (this.addEvent){ + for (var option in this.options){ + if (($type(this.options[option]) == 'function') && option.test('^on[A-Z]')) this.addEvent(option, this.options[option]); + } + } + return this; + } + +}); + +/* +Script: Dom.js + Css Query related function and extensions + +Author: + Valerio Proietti, + +License: + MIT-style license. +*/ + +/* Section: Utility Functions */ + +/* +Function: $E + Selects a single (i.e. the first found) Element based on the selector passed in and an optional filter element. + +Arguments: + selector - the css selector to match + filter - optional; a DOM element to limit the scope of the selector match; defaults to document. + +Example: + >$E('a', 'myElement') //find the first anchor tag inside the DOM element with id 'myElement' + +Returns: + a DOM element - the first element that matches the selector +*/ + +function $E(selector, filter){ + return ($(filter) || document).getElement(selector); +}; + +/* +Function: $ES + Returns a collection of Elements that match the selector passed in limited to the scope of the optional filter. + See Also: for an alternate syntax. + +Returns: + an array of dom elements that match the selector within the filter + +Arguments: + selector - css selector to match + filter - optional; a DOM element to limit the scope of the selector match; defaults to document. + +Examples: + >$ES("a") //gets all the anchor tags; synonymous with $$("a") + >$ES('a','myElement') //get all the anchor tags within $('myElement') +*/ + +function $ES(selector, filter){ + return ($(filter) || document).getElementsBySelector(selector); +}; + +/* +Class: Element + Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. +*/ + +Element.extend({ + + /* + Property: getElements + Gets all the elements within an element that match the given (single) selector. + + Arguments: + selector - the css selector to match + + Example: + >$('myElement').getElements('a'); // get all anchors within myElement + + Credits: + Say thanks to Christophe Beyls for the new regular expression that rules getElements, a big step forward in terms of speed. + */ + + getElements: function(selector){ + var filters = []; + selector.clean().split(' ').each(function(sel, i){ + var param = sel.match('^(\\w*|\\*)(?:#([\\w_-]+)|\\.([\\w_-]+))?(?:\\[["\']?(\\w+)["\']?(?:([\\*\\^\\$]?=)["\']?(\\w*)["\']?)?\\])?$'); + //PARAM ARRAY: 0 = full string: 1 = tag; 2 = id; 3 = class; 4 = attribute; 5 = operator; 6 = value; + if (!param) return; + param[1] = param[1] || '*'; + if (i == 0){ + if (param[2]){ + var el = this.getElementById(param[2]); + if (!el || ((param[1] != '*') && (Element.prototype.getTag.call(el) != param[1]))) return; + filters = [el]; + } else { + filters = $A(this.getElementsByTagName(param[1])); + } + } else { + filters = Elements.prototype.filterByTagName.call(filters, param[1]); + if (param[2]) filters = Elements.prototype.filterById.call(filters, param[2]); + } + if (param[3]) filters = Elements.prototype.filterByClassName.call(filters, param[3]); + if (param[4]) filters = Elements.prototype.filterByAttribute.call(filters, param[4], param[6], param[5]); + }, this); + return $$(filters); + }, + + /* + Property: getElementById + Targets an element with the specified id found inside the Element. Does not overwrite document.getElementById. + + Arguments: + id - the id of the element to find. + */ + + getElementById: function(id){ + var el = document.getElementById(id); + if (!el) return false; + for (var parent = el.parentNode; parent != this; parent = parent.parentNode){ + if (!parent) return false; + } + return el; + }, + + /* + Property: getElement + Same as , but returns only the first. Alternate syntax for <$E>, where filter is the Element. + */ + + getElement: function(selector){ + return this.getElementsBySelector(selector)[0]; + }, + + /* + Property: getElementsBySelector + Same as , but allows for comma separated selectors, as in css. Alternate syntax for <$$>, where filter is the Element. + + */ + + getElementsBySelector: function(selector){ + var els = []; + selector.split(',').each(function(sel){ + els.extend(this.getElements(sel)); + }, this); + return $$(els); + } + +}); + +document.extend = Object.extend; + +/* Section: document related functions */ + +document.extend({ + /* + Function: document.getElementsByClassName + Returns all the elements that match a specific class name. + Here for compatibility purposes. can also be written: document.getElements('.className'), or $$('.className') + */ + + getElementsByClassName: function(className){ + return document.getElements('.'+className); + }, + getElement: Element.prototype.getElement, + getElements: Element.prototype.getElements, + getElementsBySelector: Element.prototype.getElementsBySelector + +}); + +/* +Class: Elements + Methods for dom queries arrays, as <$$>. +*/ + +Elements.extend({ + + //internal methods + + filterById: function(id, tag){ + var found = []; + this.each(function(el){ + if (el.id == id) found.push(el); + }); + return found; + }, + + filterByClassName: function(className){ + var found = []; + this.each(function(el){ + if (Element.prototype.hasClass.call(el, className)) found.push(el); + }); + return found; + }, + + filterByTagName: function(tagName){ + var found = []; + this.each(function(el){ + found.extend(el.getElementsByTagName(tagName)); + }); + return found; + }, + + filterByAttribute: function(name, value, operator){ + var found = []; + this.each(function(el){ + var att = el.getAttribute(name); + if (!att) return found; + if (!operator) return found.push(el); + + switch (operator){ + case '*=': if (att.test(value)) found.push(el); break; + case '=': if (att == value) found.push(el); break; + case '^=': if (att.test('^'+value)) found.push(el); break; + case '$=': if (att.test(value+'$')) found.push(el); + } + return found; + }); + return found; + } + +}); + +/* +Script: Hash.js + Contains the class Hash. + +Author: + Christophe Beyls + +License: + MIT-style license. +*/ + +/* +Class: Hash + It wraps an object that it uses internally as a map. The user must use put(), get(), and remove() to add/change, retrieve and remove values, it must not access the internal object directly. With this implementation, null values are not allowed. + +Example: + (start code) + var hash = new Hash({a: 'hi', b: 'world', c: 'howdy'}); + hash.remove('b'); // b is removed. + hash.set('c', 'hello'); + hash.get('c'); // returns 'hello' + hash.length // returns 2 (a and b) + (end) +*/ + +var Hash = new Class({ + + length: 0, + + initialize: function(obj) { + this.obj = {}; + for (var property in obj) { + this.obj[property] = obj[property]; + this.length++; + } + }, + + get: function(key) { + return this.obj[key]; + }, + + set: function(key, value) { + if (value == null) return false; + if (this.obj[key] == undefined) this.length++; + this.obj[key] = value; + return this; + }, + + remove: function(key) { + if (this.obj[key] == undefined) return false; + var obj = {}; + this.length--; + for (var property in this.obj){ + if (property != key) obj[property] = this.obj[property]; + } + this.obj = obj; + return this; + }, + + each: function(fn, bind) { + for (var property in this.obj) fn.call(bind || this, property, this.obj[property]); + }, + + extend: function(obj){ + this.initialize(Object.extend(this.obj, obj)); + return this; + }, + + empty: function() { + return (this.length == 0); + }, + + keys: function() { + var keys = []; + for (var property in this.obj) keys.push(property); + return keys; + }, + + values: function() { + var values = []; + for (var property in this.obj) values.push(this.obj[property]); + return values; + } + +}); + +/* +Function: $H + Shortcut to create an Hash from an Object. +*/ + +function $H(obj) { + return new Hash(obj); +}; + +/* +Script: Color.js + Contains the Color class. + +Author: + Michael Jackson + +License: + MIT-style license. +*/ + +/* +Class: Color + Creates a new Color Object, which is an array with some color specific methods. + +Example: + (start code) + var black = new Color('#000'); + var purple = new Color([255,0,255]); + // mix black with white and purple, each time at 10% of the new color + var darkpurple = black.mix('#fff', purple, 10); + $('myDiv').setStyle('background-color', darkpurple); + (end) +*/ + +var Color = new Class({ + + initialize: function(color){ + if (color.mix && color.invert) return color; + var rgb = (color.push) ? color : color.hexToRgb(true); + return Object.extend(rgb, Color.prototype); + }, + + mix: function(){ + var colors = $A(arguments); + var alpha = 50; + if ($type(colors[colors.length-1]) == 'number') alpha = colors.pop(); + var rgb = this.copy(); + colors.each(function(color){ + color = new Color(color); + for (var i = 0; i < 3; i++) rgb[i] = Math.round((rgb[i] / 100 * (100 - alpha)) + (color[i] / 100 * alpha)); + }); + return new Color(rgb); + }, + + invert: function(){ + var rgb = []; + for (var i = 0; i < 3; i++) rgb.push(255 - this[i]); + return new Color(rgb); + } + +}); + +function $C(color){ + return new Color(color); +}; + +/* +Script: Window.Base.js + Contains Window.onDomReady and Window.disableImageCache + +License: + MIT-style license. +*/ + +/* +Class: Window + Cross browser methods to get the window size, onDomReady method. +*/ + +window.extend = Object.extend; + +window.extend({ + + /* + Function: window.disableImageCache + Disables background image chache for internex explorer, to prevent flickering. + To be called if you have effects with background images, and they flicker. + + Example: + Window.disableImageCache(); + */ + + disableImageCache: function(){ + if (this.ie6) try {document.execCommand("BackgroundImageCache", false, true);} catch (e){}; + }, + + addEvent: function(type, fn){ + if (type == 'domready'){ + if (this.loaded) fn(); + else if (!this.events || !this.events.domready){ + var domReady = function(){ + if (this.loaded) return; + this.loaded = true; + if (this.timer) this.timer = $clear(this.timer); + Element.prototype.fireEvent.call(this, 'domready'); + this.events.domready = null; + }.bind(this); + if (document.readyState && this.khtml){ //safari and konqueror + this.timer = function(){ + if (['loaded','complete'].test(document.readyState)) domReady(); + }.periodical(50); + } + else if (document.readyState && this.ie){ //ie + document.write(" + + + + +

My 1st demo

+ + +
+
+
+

Popup completion

+

+ popup stlye completion + popup stlye completion + popup stlye completion + popup stlye completion + popup stlye completion + popup stlye completion + popup stlye completion + popup stlye completion + popup stlye completion +

+ +
+
+

Emacs style completion

+

emacs stlye completion

+ + + +
+
+

Edit part

+

edit part

+ + + +
+
+ + diff --git a/emacs/nxhtml/nxhtml/html-chklnk.el b/emacs/nxhtml/nxhtml/html-chklnk.el new file mode 100644 index 0000000..6fdbb49 --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-chklnk.el @@ -0,0 +1,168 @@ +;;; html-chklnk.el --- Check links in local HTML sites +;; +;; Author: Lennart Borgman (lennart O borgman A gmail O com) +;; Created: Wed Mar 15 14:46:17 2006 +(defconst html-chklnk:version "0.2") ;; Version: +;; Last-Updated: Tue Apr 10 04:12:32 2007 (7200 +0200) +;; Keywords: +;; Compatibility: +;; +;; Features that might be required by this library: +;; +;; None +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile (add-to-list 'load-path default-directory load-path)) +(eval-when-compile + (when (> emacs-major-version 22) + (let* ((load-path load-path) + (this-file (or load-file-name + (when (boundp 'bytecomp-filename) bytecomp-filename) + buffer-file-name)) + (this-dir (file-name-directory this-file))) + (add-to-list 'load-path (expand-file-name "../../lisp" this-dir)) + (require 'w32shell nil t)))) + + +(eval-when-compile (require 'html-site nil t)) +(require 'compile) + +;;;###autoload +(defgroup html-chklnk nil + "Customization group for html-chklnk." + :group 'nxhtml) + +(defcustom html-chklnk-dir + (file-name-as-directory + (expand-file-name + "html-chklnk" + (file-name-directory + (if load-file-name load-file-name buffer-file-name)))) + + "Directory where the tools needed are located. +" + :type 'directory + :group 'html-chklnk) + +(defun html-chklnk-check-site-links (start-file) + "Check local file web site links. +Currently only internal links are checked." + (interactive + (progn + (html-site-current-ensure-site-defined) + (if (y-or-n-p "Start from a given file and check links from there? ") + (let* ((default-start (if (html-site-current-contains buffer-file-name) + buffer-file-name + (car (directory-files (html-site-current-site-dir) + nil + "\\.html?$")))) + (start-file + (read-file-name "Start checking from file: " + (html-site-current-site-dir) + nil + nil + default-start))) + (unless (html-site-dir-contains (html-site-current-site-dir) start-file) + (error "File %s is not in the site %s" start-file html-site-current)) + (list start-file)) + (list nil)))) + (let* ((default-directory html-chklnk-dir) + (compile-cmd (concat "perl link_checker.pl " + "--site=" + ;;(html-chklnk-convert-file-name + (html-site-current-site-dir) + ;;) + (if start-file + (concat " --start=" + ;;(html-chklnk-convert-file-name + start-file + ;;) + ) + ""))) + (compilation-buffer-name-function + '(lambda (dummy) (concat "** Checking links in site " + html-site-current " **"))) + (compilation-scroll-output t) + (compilation-error-regexp-alist-alist + '( + (html-chklnk + "^\\(.*\\)\\s-+at line \\([0-9]+\\):" + 1 ;; file + 2 ;; line + ))) + (compilation-error-regexp-alist '(html-chklnk)) + ;;(shell-file-name "cmd") + ;;(explicit-shell-file-name "cmd") + ;;(shell (concat exec-directory "cmdproxy.exe")) + ;;(old-w32shell nil) + ) + ;; There are trouble with perl paths +;; (when (featurep 'w32shell) +;; (when w32shell-current-shell-path +;; (setq old-w32shell w32shell-current-shell-path) +;; (w32shell-set-shell "cmd"))) + ;;(message "uses-cygwin=%s" uses-cygwin)(sit-for 8) + + (if (fboundp 'w32shell-save-shell) + (w32shell-save-shell + "cmd" + (compile compile-cmd)) + (compile compile-cmd)) + +;; (when old-w32shell +;; (cond ((string= old-w32shell w32shell-cygwin-bin) +;; (w32shell-set-shell "cygwin")) +;; ((string= old-w32shell w32shell-msys-bin) +;; (w32shell-set-shell "msys")))) + )) + +(defun html-chklnk-convert-file-name (filename) + (let ((uses-cygwin (and (featurep 'w32shell) + (string= w32shell-current-shell-path + w32shell-cygwin-bin))) + (case-fold-search t) + ) + (save-match-data + (if (and uses-cygwin + (string-match "^\\([a-z]\\):" filename)) + (concat "/cygdrive/" (match-string 1 filename) + (substring filename 2)) + filename)))) + + + + +(provide 'html-chklnk) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; html-chklnk.el ends here diff --git a/emacs/nxhtml/nxhtml/html-chklnk/PerlLib/HTML/LinkWalker.pm b/emacs/nxhtml/nxhtml/html-chklnk/PerlLib/HTML/LinkWalker.pm new file mode 100644 index 0000000..14b0ccb --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-chklnk/PerlLib/HTML/LinkWalker.pm @@ -0,0 +1,774 @@ +### File: LinkWalker.pm +### Author: Lennart Borgman +### All rights reserved + +########################################################## +### UserAgent module +########################################################## +package LWP::WalkerUA; +require LWP::UserAgent; +@ISA = qw(LWP::UserAgent); + +### Mirror to another file (why???) +sub mirror +{ + my($self, $url, $file, $mirr_tmp) = @_; + die "no mirr_tmp" unless defined $mirr_tmp; + + LWP::Debug::trace('()'); + my $request = new HTTP::Request('GET', $url); + + if (-e $file) { + my($mtime) = (stat($file))[9]; + if($mtime) { + $request->header('If-Modified-Since' => + HTTP::Date::time2str($mtime)); + } + } + my $tmpfile = "$file-$$"; + + my $response = $self->request($request, $tmpfile); + if ($response->is_success) { + + my $file_length = (stat($tmpfile))[7]; + my($content_length) = $response->header('Content-length'); + + if (defined $content_length and $file_length < $content_length) { + unlink($tmpfile); + die "Transfer truncated: " . + "only $file_length out of $content_length bytes received\n"; + } elsif (defined $content_length and $file_length > $content_length) { + unlink($tmpfile); + die "Content-length mismatch: " . + "expected $content_length bytes, got $file_length\n"; + } else { + # OK + if (-e $mirr_tmp) { + # Some dosish systems fail to rename if the target exists + chmod 0777, $mirr_tmp; + unlink $mirr_tmp; + } + rename($tmpfile, $mirr_tmp) or + die "Cannot rename '$tmpfile' to '$mirr_tmp': $!\n"; + + if (my $lm = $response->last_modified) { + # make sure the file has the same last modification time + utime $lm, $lm, $mirr_tmp; + } + } + } else { + unlink($tmpfile); + } + return $response; +} + + +########################################################## +### Parser module +########################################################## +package HTML::WalkerParser; +require HTML::ParserTagEnd; +@ISA = qw(HTML::ParserTagEnd); +use strict; +use vars qw(%LINK_ELEMENT); + +# Elements that might contain links and the name of the link attribute +%LINK_ELEMENT = +( + body => 'background', + base => 'href', + a => 'href', + img => [qw(src lowsrc usemap)], # 'lowsrc' is a Netscape invention + form => 'action', + input => 'src', +'link' => 'href', # need quoting since link is a perl builtin + frame => 'src', + applet => [qw(codebase code)], + area => 'href', + iframe => 'src', # Netscape 2.0 extention + embed => 'src', # used in Netscape 2.0 for Shockwave and things like that +); + +my %LINKATTRIBS = ( + "href" => 1, + "src" => 1, + "action" => 1, + "background" => 1, + "usemap" => 1, + "code" => 1, + "codebase" => 1, + "lowsrc" => 1, + ); +my %MAYBECONT = ( + a => 'href', + area => 'href', + form => 'action', + frame => 'src', + iframe => 'src', + ); + +sub maybecont($$) { + my $tag = shift; + my $att = shift; + return unless exists $MAYBECONT{$tag}; + return ($MAYBECONT{$tag} eq $att); +} + +sub new { + my($class, $parsed_fh) = @_; + my $self = $class->SUPER::new; + $self->{parsed_fh} = $parsed_fh; + $self; +} + + + + + + + +########################################################## +### Walker module +########################################################## +package HTML::LinkWalker; +use strict; + +use IO::File; +use File::Copy qw(); +use File::Path qw(); +use PathSubs qw(); +use HTML::Entities; +use FindBin qw(); + + +########################################################## +### Globals +########################################################## +my $ua; +my $m_ua_personality = "LinkWalker/0.9"; +my %m_is_outside; +my %m_is_container; +my $m_bOnlyCont; +my @m_sLinkRoots; +my $m_subReport; +my $m_subAction; +my $m_subMirrorAction; + + +############################# +### Collecting info +############################# +my %m_CheckedLinks; +my %m_MissedLinks; + +sub tell_bad_link($$$$$) { + my $what = shift; + my $file = shift; + my $lnum = shift; + my $link = shift; + my $line = shift; + $file = "START" unless defined $file; + $lnum = "(start)" unless defined $lnum; + my $longMsg = "<<$what>>"; + my $shortMsg = $what; + if (defined $link) { + my @lines = split("\\s+", $line); + my $disp_line = join("\n\t\t ", @lines); + $longMsg .= ",\n\t\tlink=$link\n\t\t$disp_line"; + } + my @msg = ($shortMsg, $longMsg); + $m_CheckedLinks{$file}->{ERR}->{$lnum} = \@msg; + &$m_subReport("\t* Error * " . $what . "\n"); +} # tell_bad_link + + +############################# +### Helpers +############################# + +sub get_contenttype($) { + my $response = shift; + my @rh = $response->header("Content-Type"); + for my $r (@rh) { + my $c = $r; + if ((my $iPos = index($r, ";")) > -1) { + $c = substr($r, 0, $iPos); + } + return $c; + } +} +sub is_linked_contenttype($) { + my $response = shift; + return (get_contenttype($response) eq "text/html"); +} + +sub ending_is_container($) { + my $link_addr = shift; + $link_addr =~ s!#.*$!!; + $link_addr =~ s!\?.*$!!; + return (($link_addr =~ m!\.s?html?$!i) ? 1 : 0); +} + +my $m_sMirrorRoot; +my $m_bMirror = 1; + +sub mk_mirror_name($) { + my $orig_name = shift; + $orig_name =~ tr!\\!/!; + my $mirr_name = $orig_name; + my ($orig_host) = ($orig_name =~ m!(^https?://[^/]*)!i); + if (defined $orig_host) { + my $host = $orig_host; + $host =~ tr!:!_!; + $host =~ tr!/!_!; + $mirr_name =~ s!^$orig_host!$host!; + if (substr($mirr_name, -1) eq "/") { $mirr_name .= "default.html"; } + } else { + die "Can't find host in $orig_name\n"; + } + my $mirr_full = sMirrorRoot() . $mirr_name; + if (!$m_bMirror) { + my $sExt = $mirr_name; $sExt =~ s!.*\.([^\.]*$)!$1!; + $mirr_full = sMirrorRoot() . "temp.$sExt"; + } + my $mirr_fold = $mirr_full; + $mirr_fold =~ s![^/]*$!!; + File::Path::mkpath($mirr_fold, 0, 0777); + return $mirr_full; +} + +############################# +### Checks +############################# +sub is_outside($) { + my $uq_link_addr = shift; + if (!exists $m_is_outside{$uq_link_addr}) { + $m_is_outside{$uq_link_addr} = test_is_outside($uq_link_addr, \@m_sLinkRoots); + } + return $m_is_outside{$uq_link_addr}; +} +sub set_is_container($$) { + my $uq_link_addr = shift; + return if exists $m_is_container{$uq_link_addr}; + $m_is_container{$uq_link_addr} = shift; +} +sub is_outside_container($) { + my $uq_link_addr = shift; + if (exists $m_is_container{$uq_link_addr}) { + if ($m_is_container{$uq_link_addr}) { + return is_outside($uq_link_addr); + } + } +} +sub test_is_outside($$) { + my $uq_link_addr = shift; + my $link_roots = shift; + if (defined $link_roots) { + my $in_roots; + for my $link_root (@$link_roots) { + if (substr($uq_link_addr, 0, length($link_root)) eq $link_root) { + return 0; + } + } + return 1; + } +} # is_outside + + + +########################################################## +### Parsing +########################################################## + + +### Parser subs +sub HTML::WalkerParser::declaration { + my($self, $decl) = @_; + return unless defined $self->{parsed_fh}; + my $fh = $self->{parsed_fh}; + print $fh ""; +} +my $m_start_cb; +sub HTML::WalkerParser::start { + my($self, $tag, $attr, $ended) = @_; + &$m_start_cb($tag, $attr); + return unless defined $self->{parsed_fh}; + my $t = "<$tag"; + for my $k (keys %$attr) { + my $encoded = encode_entities($$attr{$k}); + $t .= qq( $k="$encoded"); + } + if ($ended) { + $t .= " />"; + } else { + $t .= ">"; + } + my $fh = $self->{parsed_fh}; + print $fh $t; +} +sub HTML::WalkerParser::end { + my ($self, $tag) = @_; + return unless defined $self->{parsed_fh}; + my $fh = $self->{parsed_fh}; + print $fh ""; +} +sub HTML::WalkerParser::text { + my ($self, $txt) = @_; + return unless defined $self->{parsed_fh}; + my $fh = $self->{parsed_fh}; + print $fh $txt; +} +sub HTML::WalkerParser::comment { + my($self, $comment) = @_; + return unless defined $self->{parsed_fh}; + my $fh = $self->{parsed_fh}; + print $fh ""; +} + + + + +### Main parsing routine + +sub parse_file($$$$$$$$$) { + my ($file_name, $parsed_fh, $uq_link_addr, $link_roots, + $ref_links, $ref_anchs, $ref_lines, $ref_tagname, $ref_attname) = @_; + my $fh; + if (-d $file_name) { + $file_name = PathSubs::uniq_dir($file_name) . "default.html"; + $uq_link_addr .= "/" unless substr($uq_link_addr, -1) eq "/"; + $uq_link_addr .= "default.html"; + &$m_subReport("dir => $file_name\n"); + } + $fh = new IO::File($file_name); + die "Can't read $file_name: $!\n" unless defined $fh; + my $base_href; + my $n; + my $line; + my $uq_link_fold = $uq_link_addr; $uq_link_fold =~ s![^/]*$!!; + + my $start_cb = + sub { + my ($tag, $attr_hash) = @_; + for my $k (keys %$attr_hash) { + if (($k eq "id") || ($k eq "name")) { + my $v = $$attr_hash{$k}; + $$ref_anchs{$v} = $n; + $$ref_lines{$n} = $line; + } elsif (exists $LINKATTRIBS{$k}) { + my $v = $$attr_hash{$k}; + next if $v =~ m!^javascript:!; + next if $v =~ m!^ftp://!; + next if $v =~ m!^mailto://!; + if ($tag eq "base") { $base_href = $v if $k eq "href"; next; } + my $v_abs; my $v_rel; + my $v_is_abs = PathSubs::is_abs_path($v); + if ($v_is_abs) { + $v_abs = $v; + $v_rel = PathSubs::mk_relative_link($uq_link_addr, $v_abs); + } else { + $v_rel = $v; + if (defined $base_href) { + $v_abs = PathSubs::mk_abs_link($base_href, $v); + } else { + if (substr($v_rel, 0, 1) ne "#") { + $v_abs = $uq_link_fold . $v_rel; + } else { + $v_abs = $uq_link_addr . $v_rel; + } + $v_abs = PathSubs::resolve_dotdot($v_abs); + } + } + next if exists $m_CheckedLinks{$v_abs}; + if (is_outside($v_abs)) { + if (!$v_is_abs) { + if (ending_is_container($v_abs)) { + $m_CheckedLinks{$v_abs} = {}; + tell_bad_link("Outside relative link ($v_rel)", + $uq_link_addr, $n, $v, $line); + } + } + ### Skip outside absolute links + ### Could be things like banners etc... + next; + } + $$ref_links{$v_rel} = $n; + $$ref_lines{$n} = $line; + if (substr($v_rel, 0, 1) ne "#") { + my $v_rel_name = $v_rel; + $v_rel_name =~ s!#.*$!!; + $v_rel_name =~ s!\?.*$!!; + $$ref_tagname{$v_rel_name} = $tag; + $$ref_attname{$v_rel_name} = $k; + } + if ($v_is_abs && ($v_rel ne $v)) { $$attr_hash{$k} = $v_rel; } + } + } + }; # $start_cb + + $m_start_cb = $start_cb; + my $p = HTML::WalkerParser->new($parsed_fh); + while ($line = <$fh>) { + $n++; + $p->parse($line); + } + $fh->close(); +} # parse_file + + + +########################################################## +### Do the walk... +########################################################## +sub walk_link($$;$$$$) { + die "$#_" unless ($#_ == 1 || $#_ == 5); + my $link_fold = shift; + my $link_file = shift; + my $parent_url = shift; + my $parent_lnum = shift; + my $parent_link = shift; + my $parent_line = shift; + + my $link_addr = $link_fold . $link_file; + my $uq_link_addr; + my $is_file = ($link_addr !~ m!^https?://!i); + if ($is_file) { + $uq_link_addr = PathSubs::uniq_file($link_addr); + } else { + $uq_link_addr = PathSubs::resolve_dotdot($link_addr); + } + return if exists $m_CheckedLinks{$uq_link_addr}; + return if exists $m_MissedLinks{$uq_link_addr}; + $m_CheckedLinks{$uq_link_addr} = {}; + my $link_is_container = ending_is_container($uq_link_addr); + if ($link_is_container) { + set_is_container($uq_link_addr, 1); + return if is_outside($uq_link_addr); + } else { + return if $m_bOnlyCont; + } + my $response; + my $contenttype; + my $bDoRewrite; + my $file_name; + if ($is_file) { + if (!-r $uq_link_addr) { + tell_bad_link("Can't read file ($uq_link_addr)", + $parent_url, $parent_lnum, $parent_link, $parent_line); + $m_MissedLinks{$uq_link_addr} = 1; + return; + } + $file_name = $uq_link_addr; + } else { + $file_name = mk_mirror_name($uq_link_addr); + if (!defined $ua) { + $ua = new LWP::UserAgent; + $ua->agent($m_ua_personality); + #$ua->delay(0.1); + } + if ($m_bMirror) { + $response = $ua->mirror($uq_link_addr, $file_name); + &$m_subMirrorAction($uq_link_addr, $file_name, $response); + } else { + my $request = new HTTP::Request('GET', $uq_link_addr); + $response = $ua->request($request, $file_name); + } + #dump_response($response); exit; + if ($response->code != 304) { + if (!$response->is_success) { + tell_bad_link($response->status_line . " ($uq_link_addr)", + $parent_url, $parent_lnum, $parent_link, $parent_line); + $m_MissedLinks{$uq_link_addr} = 1; + return; + } + $bDoRewrite = $m_bMirror; + $contenttype = get_contenttype($response); + $link_is_container = is_linked_contenttype($response); + } + if ($uq_link_addr ne $response->base) { + if ($m_bMirror) { + my $base_file = mk_mirror_name($response->base); + if (!File::Copy::copy($file_name, $base_file)) { + die "Can't copy($file_name, $base_file): $!\n"; + } + if (my $lm = $response->last_modified) { utime $lm, $lm, $base_file; } + $file_name = $base_file; + } + $uq_link_addr = $response->base; + } + } + ### Test again, could be new info from net! + if ($link_is_container) { + set_is_container($uq_link_addr, 1); + return if is_outside($uq_link_addr); + } else { + return if $m_bOnlyCont; + return; + } + &$m_subReport("$uq_link_addr ..."); + + my %links; + my %anchs; + my %lines; + my %tagname; + my %attname; + my $parsed_fh; + my $parsed_file; + my $file_to_parse = $file_name; + if ($bDoRewrite) { + $parsed_file = $file_to_parse . "-p$$"; + &$m_subReport(" < $parsed_file"); + die "Can't create $parsed_file: $!\n" unless defined $parsed_fh; + print $parsed_fh "\n"; + } + &$m_subReport("\n"); + parse_file($file_to_parse, $parsed_fh, $uq_link_addr, + \@m_sLinkRoots, + \%links, \%anchs, \%lines, \%tagname, \%attname); + if (defined $parsed_fh) { + $parsed_fh->close(); + if (-e $file_name) { unlink $file_name or die "Can't unlink $file_name: $!"; } + rename($parsed_file, $file_name) or die "Can't rename($parsed_file, $file_name): $!\n"; + if (my $lm = $response->last_modified) { utime $lm, $lm, $file_name; } + } + ### Now we know... + if ($link_is_container) { return if is_outside($uq_link_addr); } + + $m_CheckedLinks{$uq_link_addr}->{ANC} = \%anchs; + my $file_dir; + if ($is_file) { + $file_dir = $uq_link_addr; + $file_dir =~ s![^/]*$!!; + #chdir $file_dir; + } + my $container_folder = $uq_link_addr; $container_folder =~ s![^/]*$!!; + &$m_subAction($uq_link_addr, $file_name, $contenttype); + for my $link (sort keys %links) { + # Next line is for onclick lines in prepared docs + next if ($link eq "#"); + my $lnum = $links{$link}; + my $line = $lines{$lnum}; + if ($link eq "") { + tell_bad_link("Empty link", $uq_link_addr, $lnum, $link, $line); + next; + } + if ($link =~ m!(.*)\?!) { $link = $1; } + my $anchor; + if ($link =~ m!(.*)#(.*)!) { $link = $1; $anchor = $2; } + if ($link eq "") { + if (!exists $anchs{$anchor}) { + tell_bad_link("Anchor not found ($anchor)", $uq_link_addr, $lnum, $link, $line); + } + next; + } + my $sub_fold; + my $sub_file; + my $uq_sublink; + if ($link =~ m!^https?://!i) { + $sub_fold = ""; + $sub_file = $link; + $uq_sublink = $link; + } else { + $sub_file = $link; + if ($is_file) { + $sub_fold = $file_dir; + $uq_sublink = PathSubs::uniq_file($sub_fold . $sub_file); + } else { + $sub_fold = $container_folder; + $uq_sublink = $sub_fold . $sub_file; + } + } + next if (exists $m_CheckedLinks{$uq_sublink}); + if (defined $anchor) { + $m_CheckedLinks{$uq_link_addr}->{EXTANC}->{$uq_sublink} = + { ANC=> $anchor, LINE=>$line, LNUM=>$lnum}; + } + if ($m_bOnlyCont) { + die "link=$link\tattr=$tagname{$link}\n" unless exists $tagname{$link}; + next unless maybecont($tagname{$link}, $attname{$link}); + } + if (is_outside($uq_link_addr)) { + if (maybecont($tagname{$link}, $attname{$link}) ) { + next; + } + } + walk_link($sub_fold, $sub_file, $uq_link_addr, $lnum, $link, $line); + } +} # walk_link + + + + +############################################ +### Some more checks! +############################################ +sub check_external_anchors() { + &$m_subReport("\nChecking external anchors...\n"); + for my $f (sort keys %m_CheckedLinks) { + my $fnode = $m_CheckedLinks{$f}; + if (exists ${$fnode}{"EXTANC"}) { + my $extanc_hash = ${$fnode}{"EXTANC"}; + for my $fx (keys %$extanc_hash) { + next unless (exists $m_CheckedLinks{$fx}); + my $ea_hash = ${$extanc_hash}{$fx}; + my $ea = ${$ea_hash}{ANC}; + my $fxnode = $m_CheckedLinks{$fx}; + my $fx_anc_hash = ${$fxnode}{"ANC"}; + if (!exists ${$fx_anc_hash}{$ea}) { + my $line = ${$ea_hash}{LINE}; + my $lnum = ${$ea_hash}{LNUM}; + &$m_subReport("From $f\n"); + tell_bad_link("Ext anchor not found ($fx#$ea)", + $f, $lnum, "$fx#$ea", $line); + } + } + } + } +} # check_external_anchors + + + +############################# +### Reporting +############################# +sub report_errors($$) { + my $bSum = shift; + my $bDet = shift; + my $errors_reported; + my $errors_found; + for my $f (sort keys %m_CheckedLinks) { + my $fnode = $m_CheckedLinks{$f}; + if (exists ${$fnode}{ERR}) { + $errors_found = 1; + last unless $bSum; + if (!defined $errors_reported) { + $errors_reported = 1; + &$m_subReport("\n\n*********** Summary ERRORS and WARNINGS **********\n"); + } + &$m_subReport("$f\n"); + my $err_hash = ${$fnode}{ERR}; + for my $e (sort keys %$err_hash) { + my $refE = ${$err_hash}{$e}; + &$m_subReport("\t" . ${$refE}[0] . "\n"); + } + } + } + undef $errors_reported; + if ($bDet) { + for my $f (sort keys %m_CheckedLinks) { + my $fnode = $m_CheckedLinks{$f}; + if (exists ${$fnode}{ERR}) { + if (!defined $errors_reported) { + $errors_reported = 1; + &$m_subReport("\n\n*********** Detailed ERRORS and WARNINGS **********\n"); + } + &$m_subReport("$f\n"); + my $err_hash = ${$fnode}{ERR}; + for my $e (sort keys %$err_hash) { + my $refE = ${$err_hash}{$e}; + &$m_subReport("\tat line $e: " . ${$refE}[1] . "\n"); + } + } + } + } + if ($errors_found) { + die "\n*** There where errors ***\n"; + } else { + &$m_subReport("No errors found\n"); + } +} # report_errors + +sub dump_response($) { + my $response = shift; + &$m_subReport( $response->code . " " . $response->message . "\n"); + &$m_subReport( "****************************************\n"); + #&$m_subReport( $response->request . "\n"); + #&$m_subReport( "****************************************\n"); + #&$m_subReport( $response->previous . "\n"); + #&$m_subReport( "****************************************\n"); + &$m_subReport( " i=" . $response->is_info . + ", s=" . $response->is_success . + ", r=" . $response->is_redirect . + ", e=" . $response->is_error . "\n"); + &$m_subReport( "****************************************\n"); + &$m_subReport( "content: " . $response->content . "\n"); + &$m_subReport( "****************************************\n"); + &$m_subReport( "base: " . $response->base . "\n"); + &$m_subReport( "****************************************\n"); + &$m_subReport( $response->as_string); + &$m_subReport( "****************************************\n"); + &$m_subReport( $response->current_age . "\n"); + &$m_subReport( "****************************************\n"); + my @rh = $response->header("Content-Type"); + for my $r (@rh) { &$m_subReport( "ct: $r\n"); } + &$m_subReport( "****************************************\n"); +} # dump_response + + +############################# +### Parameters +############################# +sub sMirrorRoot() { + my $val = shift; + $m_sMirrorRoot = PathSubs::get_temp_path() . "LinkWalker/" unless defined $m_sMirrorRoot; + my $old = $m_sMirrorRoot; + $m_sMirrorRoot = PathSubs::uniq_dir($val) if defined $val; + return $old; +} +sub bMirror(;$) { + my $val = shift; + my $old = $m_bMirror; + $m_bMirror = $val if defined $val; + $old; +} + +sub subReporter(;$) { + my $val = shift; + my $old = $m_subReport; + $m_subReport = $val if defined $val; + $old +} +sub subAction(;$) { + my $val = shift; + my $old = $m_subAction; + $m_subAction = $val if defined $val; + $old +} +sub bOnlyCont(;$) { + my $val = shift; + my $old = $m_bOnlyCont; + $m_bOnlyCont = $val if defined $val; + $old +} +sub ua_personality(;$) { + my $val = shift; + my $old = $m_ua_personality; + $m_ua_personality = $val if defined $val; + $old +} + +sub clear_roots() { @m_sLinkRoots = (); } +sub get_roots() { return \@m_sLinkRoots; } +sub add_root($) { push @m_sLinkRoots, shift; } +sub add_files_root($) { + my $file = shift; + my $default_root; + my ($host) = ($file =~ m!(^https?://[^/]*)!i); + if (defined $host) { + $default_root = $file; + } else { + die "Can't find $file\n" unless -e $file; + $default_root = PathSubs::uniq_file($file); + } + $default_root =~ s![^/]*$!!; + add_root($default_root); +} + +### Default actions +sub default_sub {} +$m_subReport = \&default_sub; +$m_subAction = \&default_sub; +$m_subMirrorAction = \&default_sub; + +1; diff --git a/emacs/nxhtml/nxhtml/html-chklnk/PerlLib/HTML/ParserTagEnd.pm b/emacs/nxhtml/nxhtml/html-chklnk/PerlLib/HTML/ParserTagEnd.pm new file mode 100644 index 0000000..32407d6 --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-chklnk/PerlLib/HTML/ParserTagEnd.pm @@ -0,0 +1,448 @@ +package HTML::ParserTagEnd; + +# Author address: +### Modified for , Lennart + +use strict; +use HTML::Entities (); + +use vars qw($VERSION); +$VERSION = "2.23"; # $Date: 1999/06/09 10:27:16 $ + + +sub new +{ + my $class = shift; + my $self = bless { '_buf' => '', + '_strict_comment' => 0, + }, $class; + $self; +} + + +# A little note about the observed Netscape behaviour: +# +# It parse in the depreceated 'literal' mode, i.e. no tags are +# recognized until a is found. +# +# is parsed like
, i.e. tags are recognized.  +# are presentend in smaller font than 
+#
+# Netscape does not parse this comment correctly (it terminates the comment
+# too early):
+#
+#     more comment -->
+#
+# Netscape ignores '' within the 
+    
+    
+  
+  
+
+
+    
+      
+        
+
+      
+    
+ + + + + + + + +
+ + + + + +
+ + + + + + + +
%%TOC%%
+
+   +
+
+
+ + diff --git a/emacs/nxhtml/nxhtml/html-toc/html-toc/html-toc-template.css b/emacs/nxhtml/nxhtml/html-toc/html-toc/html-toc-template.css new file mode 100644 index 0000000..a6ffabb --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-toc/html-toc/html-toc-template.css @@ -0,0 +1,141 @@ +/* Main structures >>>>>>>>>>>>>>> */ +.html-wtoc-maintop { + font-size: 1px; + font-size: 1em; + margin-top: 0em; + margin-bottom: 0em; +/* background-color:green; */ +} +.html-wtoc-main { +} + +td.html-wtoc-vdivline { + //background-color: #8be; + width: 0px; +} + +.html-wtoc-search-form { + margin-bottom: 0.1em; +} +.html-wtoc-search { + font-size: 0.8em; + color: green; +} +.html-wtoc-search a { + color: green; +} +/* <<<<<<<<<<<<<<<<<<< */ + + + + +/* Table of content >>>>>>>>>>>>>> */ + +#html-wtoc-id-hidetoc { + height: 20px; + border-bottom: 2px inset #ddf; + border-color: #dff; +} + +#html-wtoc-id-tocdiv { + width: 2.5em; + //background-color: #eff; +} +#html-wtoc-id-logo { + width: 100%; + height: 120px; + padding: 0em; + margin: 0em; + border: 0em; +} +#html-wtoc-id-toc { +} +#html-wtoc-id-tocwidth { + width: 18em; + height: 0em; + padding: 0em; + margin: 0em; + border: 0em; + line-height: 0em; +/* background-color: red; */ +} +#html-wtoc-id-toccol { + width: 18em; +} + +.html-wtoc-contcol { + background-color: #dFEfff; + background-color: #dFEfff; + background-color: #cd950c; + background-color: #eead0e; +} +/* <<<<<<<<<<<<<<<<<<< */ + + + + +/* Buttons etc >>>>>>>>>>>>>>> */ +.html-wtoc-button { + font-size: 0.75em; + font-size: 8pt; + color: #5A5D00; + background-color: #9cf; + background-color: #bcee68; + background-color: #a2cd5a; + padding: 0.2em; + Border-Width: 2px; + Border-Style: outset; + text-align: center; + border-color: #ddf; +} +a.html-wtoc-button { + text-decoration: none; + color: #5A5D00; +} +a.html-wtoc-button:hover { + text-decoration:none; + background-color: #6af; + color:#340; +} + +a.html-wtoc-buttonimg img { + width: 16px; + height: 16px; + padding: 4px; + border: 8px; +} +a.html-wtoc-buttonimg { + border:2px; + margin:2px; + margin-left:2px; + margin-right:2px; +} +a.html-wtoc-buttonimg { + font-size:1px; +} +a.html-wtoc-buttonimg:hover { + margin: 6px; + margin-left:0px; + margin-right:0px; + border-color: #ddf; + border-width: 2px; + border-style: outset; + background-color: #595C00; + background-color: #bef; + background-color: #b9ffb9; +} + +/* <<<<<<<<<<<<<<<<<<< */ + + +#nxhtml-link { + font-size: 0.7em; + text-align: center; + padding-top: 2em; + padding: 1em; +} + +.copyright { + color : #872; +} + diff --git a/emacs/nxhtml/nxhtml/html-toc/html-toc/html-toc.css b/emacs/nxhtml/nxhtml/html-toc/html-toc/html-toc.css new file mode 100644 index 0000000..a12cb65 --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-toc/html-toc/html-toc.css @@ -0,0 +1,84 @@ +body { + margin: 0; +} +td { + font-size: 1em; +} + +/* Added by html-wtoc.pl >>>>>>>>>>>>> */ +.html-wtoc-mark { +/* background-color: #9cf; */ +/* background-color: #bcee68; */ +/* background-color: #a2cd5a; */ + width: 20px; + padding: 0; + border: 0; + text-align: center; +} +.html-wtoc-contline { + width: 100%; +} + +.html-wtoc-margin { + width: 0.6em; +} +.html-wtoc-contents { + font-size: 0.9em; + padding: 1em; + background-color: #9cf; + background-color: #a2cd5a; + background-color: #efffcf; + background-color: #ffffdf; + -moz-border-radius-topleft: 2em; +} +.html-wtoc-contents td { +/* background-color: #9cf; */ +/* background-color: #bcee68; */ +/* background-color: #a2cd5a; */ +} +.html-wtoc-contents-a { + text-decoration: none; + color: #595C00; +/* background-color: #9cf; */ +/* background-color: #bcee68; */ +/* background-color: #a2cd5a; */ + border: 1px #9cf solid; + border: 1px #a2cd5a solid; + border: 1px #ffffc0 solid; + padding-left: 0.25em; + padding-right: 0; + margin: 1px; + display: block; +} +.html-wtoc-contents a:hover { + text-decoration: none; + background-color: #b9ffb9; + border: 1px #6b8e23 solid; +} +.html-wtoc-currcont { + background-color: #738600; + color: #ffff2f; + background-color: #535600; + border: 1px #6b8e23 inset; + padding-left: 0.25em; + padding-right: 0; + margin: 1px; + display: block; +} +a.html-wtoc-currcont { + text-decoration: none; +} +a.html-wtoc-currcont:hover { + background-color: #738600; + background-color: #536600; + background-color: #434620; +} +/* <<<<<<<<<<<<<<<<<<< */ + + + + + + + + diff --git a/emacs/nxhtml/nxhtml/html-toc/html-toc/html-toc.js b/emacs/nxhtml/nxhtml/html-toc/html-toc/html-toc.js new file mode 100644 index 0000000..7f22db7 --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-toc/html-toc/html-toc.js @@ -0,0 +1,361 @@ + +// © Copyright 2006 Lennart Borgman, http://www.OurComments.org/. All rights reserved. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth +// Floor, Boston, MA 02110-1301, USA. + + +var HTML_WTOC_NS_sCurrTocId; + + +HTML_WTOC_NS = { + + ///////////////////////////// + //// Basic event functions + ///////////////////////////// + + getEventObject : function (ev) { + var o; + if (window.event) + o = window.event.srcElement; + else if (null != ev) + o = ( ev.target ); + return o; + }, + getEvent : function (ev) { + if (window.event) { + return window.event; + } else if (null != ev) { + return ev; + } + }, + + eventStopPropagation : function (e) { + if (e.stopPropagation) + e.stopPropagation(); + else + e.cancelBubble=true; + }, + + eventPreventDefault : function (e) { + if (e.preventDefault) + e.preventDefault(); + else + e.returnValue=false; + }, + + ///////////////////////////// + //// TOC hide + ///////////////////////////// + + show_content : function (on) { + var toc = document.getElementById("html-wtoc-id-toccol").style; + var tdv = document.getElementById("html-wtoc-id-tocdiv").style; + var shw = document.getElementById("html-wtoc-id-showtoc").style; + var hid = document.getElementById("html-wtoc-id-hidetoc").style; + if (on) { + toc.display = ""; + tdv.display = ""; + shw.display = "none"; + hid.display = ""; + HTML_WTOC_NS.focus_page_link(0); + } else { + toc.display = "none"; + tdv.display = "none"; + shw.display = ""; + hid.display = "none"; + } + }, + + + + + + ///////////////////////////// + //// Open-Close + ///////////////////////////// + onblur_action : function(ev) { + HTML_WTOC_NS_sCurrTocId = null; + }, + onfocus_action : function(ev) { + var o = HTML_WTOC_NS.getEventObject(ev); + if (!o) return; + + HTML_WTOC_NS_sCurrTocId = o.id; + }, + onclick_action : function(ev) { + var o = HTML_WTOC_NS.getEventObject(ev); + var e = HTML_WTOC_NS.getEvent(ev); + if (13 == e.keyCode) return true; + if (!o) return true; + if ("IMG" == o.tagName) o = o.parentNode; + var iId = HTML_WTOC_NS.getIdnumFromId(o.id); + var sChildId = "toc_child_"+iId; + var sOldCurrTocId = HTML_WTOC_NS_sCurrTocId; + HTML_WTOC_NS.toggle_open(sChildId, o); + HTML_WTOC_NS_sCurrTocId = sOldCurrTocId; + return false; + }, + + toggle_open : function (id, parent) { + var child = document.getElementById(id).style; + var sInner = parent.innerHTML; + var re = new RegExp("[^/]*\.gif", "i"); + if ("none" == child.display) { + child.display = ""; + parent.innerHTML = sInner.replace(re, "down.gif")+""; + } else { + child.display = "none"; + parent.innerHTML = sInner.replace(re, "right.gif")+""; + } + }, + + + + ///////////////////////////// + //// Load + ///////////////////////////// + + onload_actions : function (iPageNum) { + document.body.onkeydown = HTML_WTOC_NS.onkeydown_action; + document.body.onmouseover = HTML_WTOC_NS.onmouseover_action; + var aATags = document.getElementsByTagName("a"); + for(var i = 0; i < aATags.length; i++) { + var o = aATags[i]; + if (null != HTML_WTOC_NS.getIdnumFromId(o.id)) { + o.onfocus = HTML_WTOC_NS.onfocus_action; + o.onblur = HTML_WTOC_NS.onblur_action; + if (o.id.substr(0, 12) == "opener_text_") { + o.onclick = HTML_WTOC_NS.onclick_action; + o.title = "Open/Close"; + } else if (o.id.substr(0, 7) == "opener_") { + o.onclick = HTML_WTOC_NS.onclick_action; + o.className = "html-wtoc-mark"; + o.title = "Open/Close"; + } + } + } + HTML_WTOC_NS.focus_page_link(iPageNum); + }, + focus_page_link : function (iPageNum) { + // Element might be hidden + try { + document.getElementById("toc_link_"+iPageNum).focus(); + } catch (exc) { + } + }, + + + + + + + + ///////////////////// + //// Mouse + ///////////////////// + + onmouseover_action : function (ev) { + if (null == HTML_WTOC_NS_sCurrTocId) return true; + var o = HTML_WTOC_NS.getEventObject(ev); + var iId = HTML_WTOC_NS.getIdnumFromId(o.id); + if (null == iId) return true; + o.focus(); + }, + + + + ///////////////////// + //// Key + ///////////////////// + + onkeydown_action: function (ev) { + var keyDown = 40; + var keyUp = 38; + var keyLeft = 37; + var keyRight = 39; + var keyReturn = 13; + var keyF2 = 113; + var keyInsert = 45; + // Opera + var keyOperaDown = 57386; + var keyOperaUp = 57385; + var keyOperaLeft = 57387; + var keyOperaRight = 57388; + var keyOperaF2 = 57346; + var keyOperaInsert = 57394; + + var SwitchKey = keyInsert; + var SwitchKeyOpera = keyOperaInsert; + + var bUp; + var e = HTML_WTOC_NS.getEvent(ev); + if (null == HTML_WTOC_NS_sCurrTocId) { + switch (e.keyCode) { + case SwitchKey: + case SwitchKeyOpera: + HTML_WTOC_NS.focus_page_link(0); + HTML_WTOC_NS.eventStopPropagation(e); + HTML_WTOC_NS.eventPreventDefault(e); + return false; + } + return true; + } + switch (e.keyCode) { + case keyLeft: + case keyOperaLeft: + case keyRight: + case keyOperaRight: + HTML_WTOC_NS.handle_leftright_keys(e); + HTML_WTOC_NS.eventStopPropagation(e); + HTML_WTOC_NS.eventPreventDefault(e); + return false; + case keyDown: + case keyOperaDown: + bUp = false; + break; + case keyUp: + case keyOperaUp: + bUp = true; + break; + case SwitchKey: + case SwitchKeyOpera: + if (null != HTML_WTOC_NS_sCurrTocId) { + var o = document.getElementById(HTML_WTOC_NS_sCurrTocId); + if (o) o.blur(); + HTML_WTOC_NS_sCurrTocId = null; + } + HTML_WTOC_NS.eventStopPropagation(e); + HTML_WTOC_NS.eventPreventDefault(e); + return false; + default: + //alert(e.keyCode); + return true; + } + var oOpener; + oOpener = HTML_WTOC_NS.getNextVisOpener(HTML_WTOC_NS_sCurrTocId, bUp); + oOpener.focus(); + HTML_WTOC_NS.eventStopPropagation(e); + HTML_WTOC_NS.eventPreventDefault(e); + return false; + }, + + handle_leftright_keys: function (e) { + var keyLeft = 37; + var keyRight = 39; + var keyOperaLeft = 57387; + var keyOperaRight = 57388; + var iId = HTML_WTOC_NS.getIdnumFromId(HTML_WTOC_NS_sCurrTocId); + if (null == iId) return; + var sId = "opener_" + iId; + var oOpener = document.getElementById(sId); + var sId = HTML_WTOC_NS_sCurrTocId; // It will be cleared before getNextVis + + var bOpenAction; + var bOpened; + var bUp; + var oChild = document.getElementById("toc_child_"+iId); + if (null == oChild) { + } else { + bOpened = (oChild.style.display != "none"); + } + switch (e.keyCode) { + case keyLeft: + case keyOperaLeft: + bUp = true; + bOpenAction = (null != bOpened) && (bOpened); + break; + case keyRight: + case keyOperaRight: + bUp = false; + bOpenAction = (null != bOpened) && (!bOpened); + break; + default: + alert("bad key handling..."); + } + if (bOpenAction) { + oOpener.click(); + HTML_WTOC_NS_sCurrTocId = sId; + } else { + var oPrev = HTML_WTOC_NS.getNextVisOpener(sId, bUp); + oPrev.focus(); + } + }, + + + + + + + ////////////////////// + //// Util + ////////////////////// + getNameFromId: function (sId) { + var re = new RegExp("(.*?_)(\\d+)", "i"); + if (!re.test(sId)) return null; + var iId = sId.replace(re, "$1"); + return iId; + }, + getIdnumFromId: function (sId) { + var re = new RegExp("(.*?_)(\\d+)", "i"); + if (!re.test(sId)) return null; + var iId = sId.replace(re, "$2"); + return iId; + }, + + + getNextVisOpener: function (sId, bUp, bTrace) { + if (bTrace) alert("getNextVisOpener("+sId+","+bUp+")"); + var iId = HTML_WTOC_NS.getIdnumFromId(sId); + if (null == iId) { + alert("getNextVisOpener err iId==null"); + return; + } + var sIdName = HTML_WTOC_NS.getNameFromId(sId); + if (null == sIdName) { + alert("getNextVisOpener err sIdName==null"); + return; + } + var oOpener; + var iLoop = -2; + while (oOpener == null) { + if (bTrace) alert(iId); + if (iLoop++ > iMaxChildNum) { alert("Child num error"); return; } + if (!bUp) { + iId++; + } else { + iId--; + } + if (iId > iMaxChildNum) { iId = 0; } + if (iId < 0) { iId = iMaxChildNum; } + var s = sIdName+iId; + oOpener = document.getElementById(s); + if (oOpener != null) { + if (bTrace) alert(oOpener.offsetLeft); + if (oOpener.style.display == "none") { // All + oOpener = null; + } else if (oOpener.offsetLeft < 0) { // IE + oOpener = null; + } else if (0 == oOpener.scrollWidth) { // Opera + oOpener = null; + } + } + } + return oOpener; + } + + + +}; //HTML_WTOC_NS diff --git a/emacs/nxhtml/nxhtml/html-toc/html-toc/img/blank12.gif b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/blank12.gif new file mode 100644 index 0000000..0869f9f Binary files /dev/null and b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/blank12.gif differ diff --git a/emacs/nxhtml/nxhtml/html-toc/html-toc/img/down.gif b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/down.gif new file mode 100644 index 0000000..30d6ecf Binary files /dev/null and b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/down.gif differ diff --git a/emacs/nxhtml/nxhtml/html-toc/html-toc/img/freeCont.gif b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/freeCont.gif new file mode 100644 index 0000000..1c94b60 Binary files /dev/null and b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/freeCont.gif differ diff --git a/emacs/nxhtml/nxhtml/html-toc/html-toc/img/gnu-m-x-160.png b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/gnu-m-x-160.png new file mode 100644 index 0000000..5254ef1 Binary files /dev/null and b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/gnu-m-x-160.png differ diff --git a/emacs/nxhtml/nxhtml/html-toc/html-toc/img/gnu-m-x-160.xcf b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/gnu-m-x-160.xcf new file mode 100644 index 0000000..f2ce5ce Binary files /dev/null and b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/gnu-m-x-160.xcf differ diff --git a/emacs/nxhtml/nxhtml/html-toc/html-toc/img/hideCont.gif b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/hideCont.gif new file mode 100644 index 0000000..9908895 Binary files /dev/null and b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/hideCont.gif differ diff --git a/emacs/nxhtml/nxhtml/html-toc/html-toc/img/nailCont.gif b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/nailCont.gif new file mode 100644 index 0000000..4c1bca4 Binary files /dev/null and b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/nailCont.gif differ diff --git a/emacs/nxhtml/nxhtml/html-toc/html-toc/img/nosearch.gif b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/nosearch.gif new file mode 100644 index 0000000..e824f5b Binary files /dev/null and b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/nosearch.gif differ diff --git a/emacs/nxhtml/nxhtml/html-toc/html-toc/img/right.gif b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/right.gif new file mode 100644 index 0000000..2400cf1 Binary files /dev/null and b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/right.gif differ diff --git a/emacs/nxhtml/nxhtml/html-toc/html-toc/img/search.gif b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/search.gif new file mode 100644 index 0000000..9f58dfd Binary files /dev/null and b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/search.gif differ diff --git a/emacs/nxhtml/nxhtml/html-toc/html-toc/img/showCont.gif b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/showCont.gif new file mode 100644 index 0000000..7bd2e7d Binary files /dev/null and b/emacs/nxhtml/nxhtml/html-toc/html-toc/img/showCont.gif differ diff --git a/emacs/nxhtml/nxhtml/html-upl.el b/emacs/nxhtml/nxhtml/html-upl.el new file mode 100644 index 0000000..1ce2e98 --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-upl.el @@ -0,0 +1,329 @@ +;;; html-upl.el --- Uploading of web sites +;; +;; Author: Lennart Borgman (lennart O borgman A gmail O com) +;; Created: Mon Mar 06 19:09:19 2006 +(defconst html-upl:version "0.3") ;; Version: +;; Last-Updated: 2008-03-22T01:23:01+0100 Sat +;; Keywords: +;; Compatibility: +;; +;; Features that might be required by this library: +;; +;; `cl', `html-site', `html-upl', `mail-prsvr', `mm-util', `timer', +;; `url-c', `url-parse', `url-vars'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: +(eval-when-compile (add-to-list 'load-path default-directory load-path)) +(eval-when-compile (require 'html-site nil t)) + +;;;###autoload +(defgroup html-upl nil + "Customization group for html-upl." + :group 'nxhtml) + +(defcustom html-upl-dir + (file-name-as-directory + (expand-file-name + "html-upl" + (file-name-directory + (if load-file-name load-file-name buffer-file-name)))) + + "Directory where the tools needed are located. +The tools for html-upl includes: + +- ftpsync.pl +" + :type 'directory + :group 'html-upl) + +(defun html-upl-browse-remote () + (interactive) + (let ((url (html-site-local-to-web html-site-current + ;;buffer-file-name + (html-site-buffer-or-dired-file-name) + nil))) + (browse-url url))) +(defun html-upl-browse-remote-with-toc () + (interactive) + (let ((url (html-site-local-to-web html-site-current + ;;buffer-file-name + (html-site-buffer-or-dired-file-name) + t))) + (browse-url url))) +(defun html-upl-browse-remote-frames () + (interactive) + (let ((url (html-site-local-to-web (html-site-current-frames-file) + ;;buffer-file-name + (html-site-buffer-or-dired-file-name) + nil))) + (browse-url url))) + +;;;###autoload +(defun html-upl-upload-site-with-toc () + (interactive) + (html-upl-upload-site1 t)) + +;;;###autoload +(defun html-upl-upload-site () + (interactive) + (html-upl-upload-site1 nil)) +(defun html-upl-upload-site1(with-toc) + (html-site-current-ensure-site-defined) + (html-upl-ensure-site-has-host) + (let ((local-dir (if with-toc + (html-site-current-merge-dir) + (html-site-current-site-dir))) + (ftp-host (html-site-current-ftp-host)) + (ftp-user (html-site-current-ftp-user)) + (ftp-pw (html-site-current-ftp-password)) + (ftp-dir (if with-toc + (html-site-current-ftp-wtoc-dir) + (html-site-current-ftp-dir))) + (ftpsync-pl (expand-file-name "ftpsync.pl" html-upl-dir)) + ) + (unless (< 0 (length ftp-host)) + (error "Ftp host not defined")) + (unless (< 0 (length ftp-user)) + (error "Ftp user not defined")) + (unless (< 0 (length ftp-dir)) + (if with-toc + (error "Ftp remote directory for pages with TOC not defined") + (error "Ftp remote directory not defined"))) + (unless (< 0 (length ftp-pw)) + (setq ftp-pw (html-site-get-ftp-pw))) + (let* ( + (buffer (noshell-procbuf-setup "subprocess for upload")) + (remote-url (concat "ftp://" ftp-user ":" ftp-pw "@" ftp-host ftp-dir)) + (opt (list + "-v" + "-p" + local-dir + remote-url))) + (apply 'noshell-procbuf-run + buffer + "perl" "-w" + ftpsync-pl + opt + )))) + +(defun html-upl-ensure-site-has-host () + (let ((host (html-site-current-ftp-host))) + (unless (and host (< 0 (length host))) + (error "Site %s has no ftp host defined" html-site-current)))) + +;;;###autoload +(defun html-upl-remote-dired (dirname) + "Start dired for remote directory or its parent/ancestor." + (interactive (list + (read-directory-name "Local directory: " nil nil t))) + (html-site-current-ensure-file-in-site dirname) + (html-upl-ensure-site-has-host) + (let* ((local-dir dirname) + (remote-dir (html-site-current-local-to-remote local-dir nil)) + to-parent + res + msg) + (while (not res) + (condition-case err + (progn + (dired remote-dir) + (setq res t)) + (error ;;(lwarn 't :warning "err=%s" err) + (setq msg (error-message-string err)))) + ;; It does not look like we always get an error. Check where we are: + (when res + (unless (string= default-directory remote-dir) + (setq res nil) + (setq msg ""))) + (unless res + ;; 450 Requested file action not taken File unavailable (e.g. file busy). + ;; 550 Requested action not taken File unavailable (e.g. file not found, no access). + (if (or (string= msg "") + (save-match-data (string-match " \\(?:550\\|450\\) " msg))) + (progn + (if (not to-parent) + (setq to-parent (concat + (file-name-nondirectory remote-dir) + "/..")) + (setq to-parent (concat + (file-name-nondirectory remote-dir) + "/" + to-parent "/.."))) + ;;(setq local-dir (directory-file-name (file-name-directory (directory-file-name local-dir)))) + ;;(html-site-current-ensure-file-in-site local-dir) + ;;(setq remote-dir (html-site-current-local-to-remote local-dir nil)) + (setq remote-dir (directory-file-name (file-name-directory remote-dir))) + ) + (setq res msg)))) + (if (stringp res) + (error "%s" msg) + (when to-parent + (message "Remote dir not found, showing ancestor %s" to-parent))))) + +;;;###autoload +(defun html-upl-upload-file (filename) + "Upload a single file in a site. +For the definition of a site see `html-site-current'." + (interactive (list + (let ((use-dialog-box nil) + (f (file-relative-name + ;;(if (derived-mode-p 'dired-mode) (dired-get-file-for-visit) buffer-file-name) + (html-site-buffer-or-dired-file-name) + ))) + (read-file-name "File: " nil nil t f)) + )) + (html-site-current-ensure-file-in-site filename) + (html-upl-ensure-site-has-host) + (let* ((buffer (get-file-buffer filename)) + (remote-file (html-site-current-local-to-remote filename nil)) + (remote-buffer (get-file-buffer remote-file)) + (local-file filename)) + (when (or (not buffer-file-name) + (not (buffer-modified-p buffer)) + (and + (y-or-n-p (format "Buffer %s is modified. Save buffer and copy? " + (buffer-name buffer))) + (with-current-buffer buffer + (save-buffer) + (not (buffer-modified-p))))) + (when (= ?~ (string-to-char local-file)) + (setq local-file (expand-file-name local-file))) + (when (and (fboundp 'w32-short-file-name) + (string-match " " local-file)) + (setq local-file (w32-short-file-name local-file))) + (copy-file local-file + ;;(html-site-current-local-to-remote filename nil) + remote-file + 0) + (when remote-buffer + (with-current-buffer remote-buffer + (revert-buffer nil t t))) + (message "Upload ready") + ))) + +;;;###autoload +(defun html-upl-edit-remote-file () + (interactive) + (html-upl-edit-remote-file1 nil)) + +;;;###autoload +(defun html-upl-edit-remote-file-with-toc () + (interactive) + (html-upl-edit-remote-file1 t)) + +(defun html-upl-edit-remote-file1(with-toc) + (html-site-current-ensure-buffer-in-site) + (html-upl-ensure-site-has-host) + (let* ((remote-root (concat "/ftp:" + (html-site-current-ftp-user) + "@" (html-site-current-ftp-host) + ":" + (if with-toc + (html-site-current-ftp-wtoc-dir) + (html-site-current-ftp-dir)))) +;; (remote-file (html-site-path-in-mirror (html-site-current-site-dir) +;; buffer-file-name +;; remote-root)) + (remote-file (html-site-current-local-to-remote buffer-file-name nil)) + ) + (find-file remote-file))) + +;;;###autoload +(defun html-upl-ediff-file (filename) + "Run ediff on local and remote file. +FILENAME could be either the remote or the local file." + ;;(interactive "fFile (local or remote): ") + (interactive (list + (or (html-site-buffer-or-dired-file-name) + (read-file-name "File: ")))) + (html-upl-ensure-site-has-host) + (let* ((is-local (html-site-file-is-local filename)) + remote-name + local-name) + (if is-local + (progn + (html-site-current-ensure-file-in-site filename) + (setq remote-name (html-site-current-local-to-remote filename nil)) + (setq local-name filename)) + (setq local-name (html-site-current-remote-to-local filename nil)) + (html-site-current-ensure-file-in-site local-name) + (setq remote-name filename)) + (let ((local-buf (find-file local-name)) + (remote-buf (find-file remote-name))) + (ediff-buffers local-buf remote-buf)))) + +;;(defun html-site-buffer-or-dired-file-name () +;; (defun html-upl-ediff-buffer () +;; "Run ediff on local and remote buffer file. +;; The current buffer must contain either the local or the remote file." +;; (interactive) +;; (html-upl-ediff-file (buffer-file-name))) + +(provide 'html-upl) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; html-upl.el ends here + +;; (defun html-site-local-to-remote-path (local-file protocol with-toc) +;; (let ((remote-dir (if (eq protocol 'ftp) +;; (if with-toc +;; (html-site-current-ftp-wtoc-dir) +;; (html-site-current-ftp-dir)) +;; (if with-toc +;; (html-site-current-web-wtoc-dir) +;; (html-site-current-web-dir))))) +;; (html-site-path-in-mirror +;; (html-site-current-site-dir) local-file remote-dir))) + +;; (defun html-site-local-to-web (local-file with-toc) +;; (let ((web-file (html-site-local-to-remote-path local-file 'http with-toc)) +;; (web-host (html-site-current-web-host))) +;; (save-match-data +;; (unless (string-match "^https?://" web-host) +;; (setq web-host (concat "http://" web-host)))) +;; (when (string= "/" (substring web-host -1)) +;; (setq web-host (substring web-host 0 -1))) +;; (concat web-host web-file) +;; )) +;; +;;; Use tramp-tramp-file-p instead: +;; (defun html-upl-file-name-is-local (file-name) +;; "Return nil unless FILE-NAME is a Tramp file name." +;; (save-match-data +;; (not (string-match "^/[a-z]+:" file-name)))) + +;; (defun html-upl-remote-to-local (remote-file) +;; (let ((remote-site-dir (html-site-current-web-dir))) +;; (unless (html-site-dir-contains remote-site-dir remote-file) +;; (error ""))) +;; ) + diff --git a/emacs/nxhtml/nxhtml/html-upl/COPYING b/emacs/nxhtml/nxhtml/html-upl/COPYING new file mode 100644 index 0000000..5b6e7c6 --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-upl/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/emacs/nxhtml/nxhtml/html-upl/Changes b/emacs/nxhtml/nxhtml/html-upl/Changes new file mode 100644 index 0000000..0bfd93c --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-upl/Changes @@ -0,0 +1,115 @@ + +1.26 => 1.27 (2004-08-23) +========================= + + * Proposed and partially provided by Samuel Marshall + * enhanced timezone handling, should be perfect now + * new option -c, like -i but then asks interactively to let do it + * if FTP user/password are set to ?, they are asked for interactively + + +1.25 => 1.26 (2004-03-31) +========================= + + * fixed "dangerous" algorithm of synchronization direction + + +1.24 => 1.25 (2004-03-20) +========================= + + * fixed some 1.24 bugs + * clock offset computation now more resistant against very slow connections + * clock offset computation disabled for GET mode, so mirroring of foreign + stuff is now possible again + * default localdir of . disabled, therefore + * using . as localdir parameter does not cause a parsing error any more + * replaced damn indentation tabs in sourcecode by appropriate number of + spaces, so code is readable independent of tab settings + * enabled handling of ftpdir / + * handling of relative ftpdir corrected + + +1.23 => 1.24 (2003-10-11) +========================= + + By Michiel Steltman + + * handle files with blanks etc in names + * clock offset remote-local to reduce unnecessary transfers + * error handling + + +1.22 => 1.23 (2003-09-28) +========================= + + * New parameter timeout + + +1.21 => 1.22 (2003-03-24) +========================= + + * Now cuts of / at directory spec's end, to avoid pwd() being different + from target of cwd() (which lead to unneccesarry abortions) + + +1.20 => 1.21 (2003-03-24) +========================= + + * version information in sourcefile and output of -h command + + +1.11 => 1.20 (2003-03-22) +========================= + + * generally, most foreseeable problems are beeing checked, in particular: + + - unability to connect to FTP server + - unability to login into FTP server + - unability to change to local or remote base directory + - unability to change to remote subdirectory + - unability to create local or remote subdirectory + - unability to remove local or remote subdirectory + - unability to put or get a file within 3 trials + + All these errors (except the last one) leads to immediate abortion. + + +1.10 => 1.11 (2002-05-10) +========================= + + * Some optical corrections concerning output + + * Files are now automatically re-transferred until the size on both ends + matches + + * -? now corrrectly recognized + + +1.00 => 1.10 (2001-10-28) +========================= + + * config file support + This is mportant to avoid putting ftp passwords in the process list! + + * much more informative standard and verbose/debug output, including kind + of a advance information + + * better FTP-URL parsing supporting such without user/password + + * much better default values, e.g. ftp://ftp:anonymous@localhost/., ... + + * softlinks are now detected (locally and remote) and treated somewhat + correctly, i.e. they are ignored correctly ;-)) + + + +=> 1.00 (2001-10-26) +==================== + +* 1.0 created 2001-10-20 23:10 by Christoph Lechleitner + +Quite good for a 5 hour hack, isn't it? +O.K., I have already written similar programs for local file systems +in Pascal for DOS, Win3x and OS/2, and in VisualBasic for Win95b. + + diff --git a/emacs/nxhtml/nxhtml/html-upl/README b/emacs/nxhtml/nxhtml/html-upl/README new file mode 100644 index 0000000..3f9f505 --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-upl/README @@ -0,0 +1,111 @@ +# README file for ftpsync.pl + + +Contents: +========= + +- Overview +- Why use ftpsync.pl instead of mirror, sitecopy, ...? +- Requirements/Restrictions +- Bug reports, Contact +- License +- Updates + + +Overview: +--------- + +ftpsync.pl synchronizes a local directory tree and a remote FTP directory tree. + +It was initally written to automize web publishing, but might be useful for +some other purposes, like mirroring not-too-large public sites, data +replication, and more. + +Call "ftpsync.pl -h" to get a short parameter explanation. + + +Why use ftpsync.pl instead of mirror, sitecopy, ...? +---------------------------------------------------- + +Yes, there are similar projects, so some comments on them: + +Compared to mirror, ftpsync.pl is capable of PUTing, not only GETing stuff +(Don't blame me if mirror is able to PUT, I could'nt find a way). + +Compared to sitecopy, ftpsync.pl has no problems, if the remote site has been +changed since its last run by other tools and activites. Unless network +problems or bugs occur, ftpsync.pl does a reliable synchronization. + +Compared to both, ftpsync.pl is very lightweight ;-)) + + +Requirements / Restrictions: +---------------------------- + +- Perl 5.6+ + ftpsync.pl was initially developed on Perl 5.6.0-81 on SuSE Linux 7.2, + older Perl 5.x version might work. Test reports welcome at ftpsync@ibcl.at! + +- File::Find, IO::Handle + IMHO parts of the basic perl package. + +- Net::FTP + Part of the perl-libnet package. + +- UNIX like operating systems on local system + Porting to DOS based systems should be easily done by changing the + directory separator. + +- Perhaps, the script does not work with all FTP servers + It is beeing tested only against UNIX based FTP servers. + + +Bug-Reports, Contact: +--------------------- + +Besides ftpsync.sourceforge.net, ftpsync@ibcl.at is a good target for comments +of any kind. + + +License: +-------- + +FTPSync.pl is GNU/GPL software and eMail ware. + + +FTPSync.pl as GNU/GPL software: +------------------------------- + +FTPSync.pl (ftpsync.pl) is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +See attached file COPYING. + + +FTPSync.pl as eMail ware: +------------------------- + +FTPSync.pl is also eMail-Ware, which means that the initial author +(Christoph Lechleitner) would like to get an eMail (to ftpsync@ibcl.at), +- if anyone uses the script on production level, +- if anyone distributes or advertises it in any way, +- if anyone starts to (try to) improve it. + + +Updates +------- + +The software and updates should be available from +http://ftpsync.sourceforge.net/ +http://www.ibcl.at/ossw/FTPSync diff --git a/emacs/nxhtml/nxhtml/html-upl/TODO b/emacs/nxhtml/nxhtml/html-upl/TODO new file mode 100644 index 0000000..923583d --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-upl/TODO @@ -0,0 +1,2 @@ + +Nothing as of now. diff --git a/emacs/nxhtml/nxhtml/html-upl/ftpsync.pl b/emacs/nxhtml/nxhtml/html-upl/ftpsync.pl new file mode 100644 index 0000000..729d964 --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-upl/ftpsync.pl @@ -0,0 +1,700 @@ +#!/usr/bin/perl +# +# ftpsync.pl +# +# See attached README file for any details, or call +# ftpsync.pl -h +# for quick start. +# +# LICENSE +# +# FTPSync.pl (ftpsync) is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# FTPSync.pl (ftpsync) is also eMail-Ware, which means that the initial author +# (Christoph Lechleitner) would like to get an eMail at ftpsync@ibcl.at, if +# - if anyone uses the script on production level, +# - if anyone distributes or advertises it in any way, +# - if anyone starts to (try to) improve it. +# +# +################################################################################ + +# +# Options etc. +# +#print "Starting imports.\n"; # For major problem debugging +printf STDERR "argv=@ARGV\n"; + +use File::Find; +use File::Listing; +use Net::FTP; +use strict; +# flushing ... +use IO::Handle; +STDOUT->autoflush(1); +STDERR->autoflush(1); + +sub dosync(); +sub print_syntax(); +sub print_options(); +sub buildremotetree(); +sub buildlocaltree(); +sub listremotedirs(); +sub parseRemoteURL(); + +# Option Variables +#print "Defining variables.\n"; # For major problem debugging +# meta +my $returncode=0; +my $configfile=$ENV{"HOME"}."/.ftpsync"; +# basics +my $localdir=""; +my $remoteURL=""; +my $syncdirection=""; +my $ftpuser="ftp"; +my $ftppasswd="anonymous"; +my $ftpserver="localhost"; +my $ftpdir=""; +my $ftptimeout=120; +my $syncoff=0; +# verbosity +my $doverbose=1; +my $dodebug=0; +my $doquiet=0; +my $doinfoonly=0; +my $infotext=""; +my $docheckfirst=0; + +# Read command line options/parameters +#print "Reading command line options.\n"; # For major problem debugging +my $curopt; +my @cloptions=(); +for $curopt (@ARGV) { + if ($curopt =~ /^cfg=/) { + $configfile=$'; + if (! -r $configfile) { print "Config file does not exist: ".$configfile."\n"; $returncode+=1; } + } else { + push @cloptions, $curopt; + } +} + +# Read Config File, if given +my @cfgfoptions=(); +if ($configfile ne "") { + if (-r $configfile) { + #print "Reading config file.\n"; # For major problem debugging + open (CONFIGFILE,"<$configfile"); + while () { + $_ =~ s/([ \n\r]*$|\.\.|#.*$)//gs; + if ($_ eq "") { next; } + if ( ($_ =~ /[^=]+=[^=]+/) || ($_ =~ /^-[a-zA-Z]+$/) ) { push @cfgfoptions, $_; } + } + close (CONFIGFILE); + } # else { print "Config file does not exist.\n"; } # For major problem debugging +} # else { print "No config file to read.\n"; } # For major problem debugging + +# Parse Options/Parameters +print "Parsing all options.\n"; # For major problem debugging +my $noofopts=0; +for $curopt (@cfgfoptions, @cloptions) { + if ($curopt =~ /^-[a-zA-Z]/) { + my $i; + for ($i=1; $i0) { $ftptimeout =$fvalue; } } + } + else { + if ($localdir eq "") { + $localdir = $curopt; + if ( $syncdirection eq "" ) + { $syncdirection="put"; } + } else { + print "ERROR: Unknown parameter: \"".$curopt."\"\n"; $returncode+=1 + } + } +} +if ($noofopts == 0) { print_syntax(); exit 0; } + +if($ftpuser eq "?") { print "User: "; $ftpuser=; chomp($ftpuser); } +if($ftppasswd eq "?") { print "Password: "; $ftppasswd=; chomp($ftppasswd); } + +if ($dodebug) { print_options(); } +# check options +if ( ($localdir eq "") || (! -d $localdir) ) +{ print "ERROR: Local directory does not exist: ".$localdir."\n"; $returncode+=1; } +#if ($localdir eq "") { print "ERROR: No localdir given.\n"; $returncode+=1; } +#if ( ($remoteURL eq "") { print "ERROR: No remoteURL given.\n"; $returncode+=1; } +if ($ftpserver eq "") { print "ERROR: No FTP server given.\n"; $returncode+=1; } +if ($ftpdir eq "") { print "ERROR: No FTP directory given.\n"; $returncode+=1; } +if ($ftpuser eq "") { print "ERROR: No FTP user given.\n"; $returncode+=1; } +if ($ftppasswd eq "") { print "ERROR: No FTP password given.\n"; $returncode+=1; } +if ($returncode > 0) { die "Aborting due to missing or wrong options! Call ftpsync -? for more information.\n"; } + + +#print "Exiting.\n"; exit 0; + +if ($dodebug) { print "\nFind out if ftp server is online & accessible.\n"; } +my $doftpdebug=($doverbose > 2); +my $ftpc = Net::FTP->new($ftpserver,Debug=>$doftpdebug,Timeout=>$ftptimeout) || die "Could not connect to $ftpserver\n"; +if ($dodebug) { print "Logging in as $ftpuser with password $ftppasswd.\n" } +$ftpc->login($ftpuser,$ftppasswd) || die "Could not login to $ftpserver as $ftpuser\n"; +my $ftpdefdir=$ftpc->pwd(); +if ($dodebug) { print "Remote directory is now ".$ftpdefdir."\n"; } +if ($ftpdir !~ /^\//) # insert remote login directory into relative ftpdir specification +{ if ($ftpdefdir eq "/") + { $ftpdir = $ftpdefdir . $ftpdir; } + else + { $ftpdir = $ftpdefdir . "/" . $ftpdir; } + if (!$doquiet) + { print "Absolute remote directory is $ftpdir\n"; } +} +if (substr($ftpdir, -1) eq "/") { + if (!$doquiet) + { print " Remote directory ends in /, removing this\n"; } + chop($ftpdir); +} +if ($dodebug) { print "Changing to remote directory $ftpdir.\n" } +$ftpc->binary() + or die "Cannot set binary mode :\n\t" . $ftpc->message; +$ftpc->cwd($ftpdir) + or die "Cannot cwd to $ftpdir :\n\t" . $ftpc->message; +if ($ftpc->pwd() ne $ftpdir) { + my $pwd = $ftpc->pwd(); + die "Could not change to remote base directory $ftpdir (at $pwd)\n"; } +if ($dodebug) { print "Remote directory is now ".$ftpc->pwd()."\n"; } + +if (! $doquiet) { print "\nDetermine s offset.\n"; } +if ($syncdirection eq "put") { clocksync($ftpc,"syncfile"); } + +# local & remote tree vars +#chdir $localdir; +my $ldl=length($localdir) + 1; +#my $ldl=length($localdir); +my %localfiledates=(); +my %localfilesizes=(); +my %localdirs=(); +my %locallinks=(); + +my %remotefilesizes=(); +my %remotefiledates=(); +my %remotedirs=(); +my %remotelinks=(); +my $curremotesubdir=""; + +# Build local & remote tree +if (! $doquiet) { print "\nBuilding local file tree.\n"; } +buildlocaltree(); +if (! $doquiet) { print "\nBuilding remote file tree.\n"; } +buildremotetree(); +listremotedirs(); +#if ($dodebug) { print "Quitting FTP connection.\n" } +#$ftpc->quit(); + +#print "Exiting.\n"; exit 0; + +# Work ... +if ($doinfoonly) { $docheckfirst=0; } +if ($docheckfirst) +{ print "Simulating synchronization.\n"; + $doinfoonly=1; + dosync(); + $doinfoonly=0; + print "\nOK to really update files? (y/n) [n] "; + my $yn=; + if ($yn =~ /^y/i) + { print "OK, going to do it.\n"; + } + else + { print "OK, exiting without actions.\n"; + exit 1; + } +} +if ($doinfoonly) { print "\nSimulating synchronization.\n"; } +elsif (! $doquiet) { print "\nStarting synchronization.\n"; } +dosync(); + +if (!$doquiet) { print "Done.\n"; } + +if ($dodebug) { print "Quitting FTP connection.\n" } +$ftpc->quit(); + +exit 0; + + + +# +# Subs +# + +sub buildlocaltree() { + find (\¬icelocalfile, $localdir."/"); + sub noticelocalfile { + if ($ldl > length($File::Find::name)) { return; } + #printf "name=%s, length(name)=%d, ldl=$ldl\n", $File::Find::name, length($File::Find::name); + my $relfilename=substr($File::Find::name,$ldl); + if (length($relfilename) == 0) { return; } + if (-d $_) { + if ($dodebug) { print "Directory: ".$File::Find::name."\n"; } + elsif (! $doquiet) { print ":"; } + $localdirs{$relfilename}="$relfilename"; + } + elsif (-f $_) { + #my @curfilestat=lstat $File::Find::name; + my @curfilestat=lstat $_; + my $curfilesize=$curfilestat[7]; + my $curfilemdt=$curfilestat[9]; + if ($dodebug) { print "File: ".$File::Find::name."\n"; + print "Modified ".$curfilemdt."\nSize ".$curfilesize." bytes\n"; } + elsif (! $doquiet) { print "."; } + $localfiledates{$relfilename}=$curfilemdt; + $localfilesizes{$relfilename}=$curfilesize; + } + elsif (-l $_) { + if ($dodebug) { print "Link: ".$File::Find::name."\n"; } + elsif (! $doquiet) { print ","; } + $locallinks{$relfilename}="$relfilename"; + } else { + #print "u ".$File::Find::name."\n"; + if (! $doquiet) { print "Ignoring file of unknown type: ".$File::Find::name."\n"; } + } + #if (! ($doquiet || $dodebug)) { print "\n"; } + #print "File mode is ".@curfilestat[2]."\n"; + } + if ($dodebug) { + print "Local dirs (relative to ".$localdir."/):\n"; + my $curlocaldir=""; + foreach $curlocaldir (keys(%localdirs)) + { print $curlocaldir."/\n"; } + print "Local files (relative to ".$localdir."/):\n"; + my $curlocalfile=""; + foreach $curlocalfile (keys(%localfiledates)) + { print $curlocalfile."\n"; } + } +} + + +sub buildremotetree() { + my @currecursedirs=(); + #$ftpc->ls() + # or die $ftpc->message . "\nCannot ls remote dir " . $ftpc->pwd(); + my @rfl = $ftpc->dir(); + # or @rfl=(); # we have to survive empty remote directories !!! + my $currf=""; + my $curyear = (gmtime(time))[5] + 1900; + my %monthtonr=(); + $monthtonr{"Jan"}=1; $monthtonr{"Feb"}=2; $monthtonr{"Mar"}=3; $monthtonr{"Apr"}=4; $monthtonr{"May"}=5; $monthtonr{"Jun"}=6; + $monthtonr{"Jul"}=7; $monthtonr{"Aug"}=8; $monthtonr{"Sep"}=9; $monthtonr{"Oct"}=10; $monthtonr{"Nov"}=11; $monthtonr{"Dec"}=12; + if ($dodebug) { print "Remote pwd is ".$ftpc->pwd()."\nDIRing.\n"; } + my $curlsline; + foreach $curlsline (parse_dir(\@rfl)) { + my ($cfname,$cftype,$cfsize,$cftime,$mode)=@$curlsline; + #if ($dodebug) { print "Analysing remote file/dir ".$currf."\n" }; + if ( $cftype ) { + if ($cfname eq ".") { next; } + if ($cfname eq "..") { next; } + if (substr($cftype,0,1) eq 'l') { # link, rest of string = linkto + my $curnrl; + if ($curremotesubdir eq "") { $curnrl = $cfname; } + else { $curnrl = $curremotesubdir."/".$cfname; } + $remotelinks{$curnrl}=$cfname; + if ($dodebug) { print "Link: ".$curnrl." -> ".$cfname."\n"; } + } + elsif ($cftype eq 'd') { + my $curnewrsd; + if ($curremotesubdir eq "") { $curnewrsd = $cfname; } + else { $curnewrsd = $curremotesubdir."/".$cfname; } + $remotedirs{$curnewrsd}=$curnewrsd; + if ($dodebug) { print "Directory: ".$curnewrsd."\n"; } + elsif (! $doquiet) { print ":"; } + push @currecursedirs, $cfname; + } + elsif ($cftype eq 'f') { #plain file + my $curnewrf; + if ($curremotesubdir eq "") { $curnewrf = $cfname; } + else { $curnewrf = $curremotesubdir."/".$cfname; } + #$remotefiledates{$curnewrf}=$cftime; + $remotefiledates{$curnewrf}=$ftpc->mdtm($cfname)+$syncoff; + if ($remotefiledates{$curnewrf} le 0) { die "Timeout detecting modification time of $curnewrf\n"; } + $remotefilesizes{$curnewrf}=$cfsize; + if ($remotefilesizes{$curnewrf} lt 0) { die "Timeout detecting size of $curnewrf\n"; } + if ($dodebug) { print "File: ".$curnewrf."\n"; } + elsif (! $doquiet) { print "."; } + } + elsif (! $doquiet) { print "Unkown file: $curlsline\n"; } + } + elsif ($dodebug) { print "Ignoring.\n"; } + } + #recurse + my $currecurseddir; + foreach $currecurseddir (@currecursedirs) + { my $oldcurremotesubdir; + $oldcurremotesubdir=$curremotesubdir; + if ($curremotesubdir eq "") { $curremotesubdir = $currecurseddir; } + else { $curremotesubdir .= "/".$currecurseddir; } + my $curcwddir=""; + if ($ftpdir eq "/") + { $curcwddir=$ftpdir.$curremotesubdir; } + else + { $curcwddir=$ftpdir."/".$curremotesubdir; } + if ($dodebug) { print "Change dir: ".$curcwddir."\n"; } + $ftpc->cwd($curcwddir) + or die "Cannot cwd to $curcwddir :\n\t" . $ftpc->message ; + if ($ftpc->pwd() ne $curcwddir) { + die "Could not cwd to $curcwddir :\n\t" . $ftpc->message ; } + if (! $doquiet) { print "\n"; } + buildremotetree(); + $ftpc->cdup(); + $curremotesubdir = $oldcurremotesubdir; + } +} + + +# Synchronize clocks. +sub clocksync { + my $conn = shift @_; + my $fn = shift @_; + my $fndidexist=1; + + if(! -f $fn) { + open(SF, ">$fn") or die "Cannot create $fn for time sync option"; + close(SF); + $fndidexist=0; + } + -z $fn or + die "File $fn for time sync must be empty."; + my $putsyncok=1; + $conn->put($fn) or $putsyncok=0; + if (!$putsyncok) + { unlink($fn); # cleanup! + die "Cannot send timesync file $fn"; + } + + my $now_here1 = time(); + my $now_there = $conn->mdtm($fn) or + die "Cannot get write time of timesync file $fn"; + my $now_here2 = time(); + + if ($now_here2 < $now_there) # remote is in the future + { $syncoff=($now_there - $now_here1); + $syncoff -= $syncoff % 60; + $syncoff = 0-$syncoff; + } + else + #if ($now_here1 > $now_there) # remote is the past # or equal + { $syncoff=($now_here2 - $now_there); + $syncoff -= $syncoff % 60; + } + + $conn->delete($fn); + + my $hrs = int(abs($syncoff)/3600); + my $mins = int(abs($syncoff)/60) - $hrs*60; + my $secs = abs($syncoff) - $hrs*3600 - $mins*60; + if (! $doquiet) { + printf("Clock sync offset: %d:%02d:%02d\n", $hrs, $mins, $secs); + } + unlink ($fn) unless $fndidexist; +} + + +sub dosync() +{ + chdir $localdir || die "Could not change to local base directory $localdir\n"; + if ($syncdirection eq "put") { + # create dirs missing at the target + if ($doinfoonly) { print "\nWould create new remote directories.\n"; } + elsif (! $doquiet) { print "\nCreating new remote directories.\n"; } + my $curlocaldir; + foreach $curlocaldir (sort { return length($a) <=> length($b); } keys(%localdirs)) + { if (! exists $remotedirs{$curlocaldir}) + { if ($doinfoonly) { print $curlocaldir."\n"; next; } + if ($doverbose) { print $curlocaldir."\n"; } + elsif (! $doquiet) { print "d"; } + if ($ftpc->mkdir($curlocaldir) ne $curlocaldir) { die "Could not create remote subdirectory $curlocaldir\n"; } + } + } + # copy files missing or too old at the target, synchronize timestamp _after_ copying + if ($doinfoonly) { print "\nWould copy new(er) local files.\n"; } + elsif (! $doquiet) { print "\nCopying new(er) local files.\n"; } + my $curlocalfile; + foreach $curlocalfile (sort { return length($b) <=> length($a); } keys(%localfiledates)) + { my $dorefresh=0; + if (! exists $remotefiledates{$curlocalfile}) { + $dorefresh=1; + $infotext="New: ".$curlocalfile." (".$localfilesizes{$curlocalfile}." bytes)\n"; + if ($doinfoonly) { print $infotext; next; } + elsif ($doverbose) { print $infotext; } + elsif (! $doquiet) { print "n"; } + } + elsif ($remotefiledates{$curlocalfile} < $localfiledates{$curlocalfile}) { + $dorefresh=1; + $infotext="Newer: ".$curlocalfile." (".$localfilesizes{$curlocalfile}." bytes, ".$localfiledates{$curlocalfile}." versus ".$remotefiledates{$curlocalfile}.")\n"; + if ($doinfoonly) { print $infotext; next; } + if ($doverbose) { print $infotext; } + elsif (! $doquiet) { print "u"; } + } + elsif ($remotefilesizes{$curlocalfile} != $localfilesizes{$curlocalfile}) { + $dorefresh=1; + $infotext="Changed (different sized): ".$curlocalfile." (".$localfilesizes{$curlocalfile}." versus ".$remotefilesizes{$curlocalfile}." bytes)\n"; + if ($doinfoonly) { print $infotext; next; } + if ($doverbose) { print $infotext; } + elsif (! $doquiet) { print "u"; } + } + if (! $dorefresh) { next; } + if ($dodebug) { print "Really PUTting file ".$curlocalfile."\n"; } + if ($ftpc->put($curlocalfile, $curlocalfile) ne $curlocalfile) + { print STDERR "Could not put localfile $curlocalfile\n"; } + my $retries = 3; + while ( ($ftpc->size($curlocalfile) != (lstat $curlocalfile)[7]) and ($retries-- > 0) ) + { if (! $doquiet) { print "Re-Transfering $curlocalfile\n"; } + if ($ftpc->put($curlocalfile, $curlocalfile) ne $curlocalfile) + { print STDERR "Could not re-put localfile $curlocalfile\n"; } + } + my $newremotemdt=$ftpc->mdtm($curlocalfile)+$syncoff; + utime ($newremotemdt, $newremotemdt, $curlocalfile); + } + # delete files too much at the target + if ($doinfoonly) { print "\nWould delete obsolete remote files.\n"; } + elsif (! $doquiet) { print "\nDeleting obsolete remote files.\n"; } + my $curremotefile; + foreach $curremotefile (keys(%remotefiledates)) + { if (not exists $localfiledates{$curremotefile}) + { if ($doinfoonly) { print $curremotefile."\n"; next; } + if ($doverbose) { print $curremotefile."\n"; } + elsif (! $doquiet) { print "r"; } + if ($ftpc->delete($curremotefile) ne 1) { die "Could not delete remote file $curremotefile\n"; } + } + } + # delete dirs too much at the target + if ($doinfoonly) { print "\nWould delete obsolete remote directories.\n"; } + elsif (! $doquiet) { print "\nDeleting obsolete remote directories.\n"; } + my $curremotedir; + foreach $curremotedir (sort { return length($b) <=> length($a); } keys(%remotedirs)) + { if (! exists $localdirs{$curremotedir}) + { if ($doinfoonly) { print $curremotedir."\n"; next; } + if ($doverbose) { print $curremotedir."\n"; } + elsif (! $doquiet) { print "R"; } + if ($ftpc->rmdir($curremotedir) ne 1) { die "Could not remove remote subdirectory $curremotedir\n"; } + } + } + } else { # $syncdirection eq "GET" + # create dirs missing at the target + if ($doinfoonly) { print "\nWould create new local directories.\n"; } + elsif (! $doquiet) { print "\nCreating new local directories.\n"; } + my $curremotedir; + foreach $curremotedir (sort { return length($a) <=> length($b); } keys(%remotedirs)) + { if (! exists $localdirs{$curremotedir}) + { if ($doinfoonly) { print $curremotedir."\n"; next; } + if ($doverbose) { print $curremotedir."\n"; } + elsif (! $doquiet) { print "d"; } + mkdir($curremotedir) || die "Could not create local subdirectory $curremotedir\n"; + } + } + # copy files missing or too old at the target, synchronize timestamp _after_ copying + if ($doinfoonly) { print "\nWould copy new(er) remote files.\n"; } + elsif (! $doquiet) { print "\nCopying new(er) remote files.\n"; } + my $curremotefile; + foreach $curremotefile (sort { return length($b) <=> length($a); } keys(%remotefiledates)) + { my $dorefresh=0; + if (! exists $localfiledates{$curremotefile}) { + $dorefresh=1; + $infotext="New: ".$curremotefile." (".$remotefilesizes{$curremotefile}." bytes)\n"; + if ($doinfoonly) { print $infotext; next; } + if ($doverbose) { print $infotext; } + elsif (! $doquiet) { print "n"; } + } + elsif ($remotefiledates{$curremotefile} > $localfiledates{$curremotefile}) { + $dorefresh=1; + $infotext="Newer: ".$curremotefile." (".$remotefilesizes{$curremotefile}." bytes, ".$remotefiledates{$curremotefile}." versus ".$localfiledates{$curremotefile}.")\n"; + if ($doinfoonly) { print $infotext; next; } + if ($doverbose) { print $infotext; } + elsif (! $doquiet) { print "u"; } + } + elsif ($remotefilesizes{$curremotefile} != $localfilesizes{$curremotefile}) { + $dorefresh=1; + $infotext="Changed (different sized): ".$curremotefile." (".$remotefilesizes{$curremotefile}." bytes)\n"; + if ($doinfoonly) { print $infotext; next; } + if ($doverbose) { print $infotext; } + elsif (! $doquiet) { print "c"; } + } + if (! $dorefresh) { next; } + if ($dodebug) { print "Really GETting file ".$curremotefile."\n"; } + my $rc=$ftpc->get($curremotefile, $curremotefile); + if ( ($rc eq undef) or ($rc ne $curremotefile) ) + { print STDERR "Could not get file ".$curremotefile."\n"; } + my $retries=3; + while ( ($ftpc->size($curremotefile) != (lstat $curremotefile)[7]) and ($retries-- > 0) ) + { if (! $doquiet) { print "Re-Transfering $curremotefile\n"; } + if ( ($rc eq undef) or ($rc ne $curremotefile) ) + { print STDERR "Could not get file ".$curremotefile."\n"; } + } + my $newlocalmdt=$remotefiledates{$curremotefile}; + utime ($newlocalmdt, $newlocalmdt, $curremotefile); + } + # delete files too much at the target + if ($doinfoonly) { print "\nWould delete obsolete local files.\n"; } + elsif (! $doquiet) { print "\nDeleting obsolete local files.\n"; } + my $curlocalfile; + foreach $curlocalfile (sort { return length($b) <=> length($a); } keys(%localfiledates)) + { if (not exists $remotefiledates{$curlocalfile}) + { if ($doinfoonly) { print $curlocalfile."\n"; next; } + if ($doverbose) { print $curlocalfile."\n"; } + elsif (! $doquiet) { print "r"; } + if (unlink($curlocalfile) ne 1) { die "Could not remove local file $curlocalfile\n"; } + } + } + # delete dirs too much at the target + if ($doinfoonly) { print "\nWould delete obsolete local directories.\n"; } + elsif (! $doquiet) { print "\nDeleting obsolete local directories.\n"; } + my $curlocaldir; + foreach $curlocaldir (keys(%localdirs)) + { if (! exists $remotedirs{$curlocaldir}) + { if ($doinfoonly) { print $curlocaldir."\n"; next; } + if ($doverbose) { print $curlocaldir."\n"; } + elsif (! $doquiet) { print "d"; } + rmdir($curlocaldir) || die "Could not remove local subdirectory $curlocaldir\n"; + } + } + } +} + + +sub listremotedirs() { + if ($dodebug) { + print "Remote dirs (relative to ".$ftpdir."):\n"; + my $curremotedir=""; + foreach $curremotedir (keys(%remotedirs)) + { print $curremotedir."/\n"; } + print "Remote files (relative to ".$ftpdir."):\n"; + my $curremotefile=""; + foreach $curremotefile (keys(%remotefiledates)) + { print $curremotefile."\n"; } + print "Remote links (relative to ".$ftpdir."):\n"; + my $curremotelink=""; + foreach $curremotelink (keys(%remotelinks)) + { print $curremotelink." -> ".$remotelinks{$curremotelink}."\n"; } + } +} +sub parseRemoteURL() { + if ($remoteURL =~ /^ftp:\/\/(([^@\/\\\:]+)(:([^@\/\\\:]+))?@)?([a-zA-Z01-9\.]+)\/(.*)/) { + #print "DEBUG: parsing ".$remoteURL."\n"; + #print "match 1 = ".$1."\n"; + #print "match 2 = ".$2."\n"; + #print "match 3 = ".$3."\n"; + #print "match 4 = ".$4."\n"; + #print "match 5 = ".$5."\n"; + #print "match 6 = ".$6."\n"; + #print "match 7 = ".$7."\n"; + if (length($2) > 0) { $ftpuser=$2; } + if (length($4) > 0) { $ftppasswd=$4; } + $ftpserver=$5; + $ftpdir=$6; + #if ($ftpdir eq "") { $ftpdir="/"; } + } +} + + +sub print_syntax() { + print "\n"; + print "FTPSync.pl 1.27 (2004-08-23)\n"; + print "\n"; + print " ftpsync [ options ] [ localdir remoteURL ]\n"; + print " ftpsync [ options ] [ remoteURL localdir ]\n"; + print " options = [-dgpqv] [ cfg|ftpuser|ftppasswd|ftpserver|ftpdir=value ... ] \n"; + print " localdir local directory, defaults to \".\".\n"; + print " ftpURL full FTP URL, scheme\n"; + print ' ftp://[ftpuser[:ftppasswd]@]ftpserver/ftpdir'."\n"; + print " ftpdir is relative, so double / for absolute paths as well as /\n"; + print " -c | -C like -i, but then prompts whether to actually do work\n"; + print " -d | -D turns debug output (including verbose output) on\n"; + print " -g | -G forces sync direction to GET (remote to local)\n"; + print " -h | -H turns debugging on\n"; + print " -i | -I forces info mode, only telling what would be done\n"; + print " -p | -P forces sync direction to PUT (local to remote)\n"; + print " -q | -Q turnes quiet operation on\n"; + print " -v | -V turnes verbose output on\n"; + print " cfg= read parameters and options from file defined by value.\n"; + print " ftpserver= defines the FTP server, defaults to \"localhost\".\n"; + print " ftpdir= defines the FTP directory, defaults to \".\" (/wo '\"') \n"; + print " ftpuser= defines the FTP user, defaults to \"ftp\".\n"; + print " ftppasswd= defines the FTP password, defaults to \"anonymous\".\n"; + print "\n"; + print " Later mentioned options and parameters overwrite those mentioned earlier.\n"; + print " Command line options and parameters overwrite those in the config file.\n"; + print " Don't use '\"', although mentioned default values might motiviate you to.\n"; + print "\n"; +} + + +sub print_options() { + print "\nPrinting options:\n"; + # meta + print "returncode = ", $returncode , "\n"; + print "configfile = ", $configfile , "\n"; + # basiscs + print "syncdirection = ", $syncdirection , "\n"; + print "localdir = ", $localdir , "\n"; + # FTP stuff + print "remoteURL = ", $remoteURL , "\n"; + print "ftpuser = ", $ftpuser , "\n"; + print "ftppasswd = ", $ftppasswd , "\n"; + print "ftpserver = ", $ftpserver , "\n"; + print "ftpdir = ", $ftpdir , "\n"; + # verbsityosity + print "doverbose = ", $doverbose , "\n"; + print "dodebug = ", $dodebug , "\n"; + print "doquiet = ", $doquiet , "\n"; + # + print "doinfoonly = ", $doinfoonly , "\n"; + print "\n"; +} diff --git a/emacs/nxhtml/nxhtml/html-wtoc.el b/emacs/nxhtml/nxhtml/html-wtoc.el new file mode 100644 index 0000000..94533da --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-wtoc.el @@ -0,0 +1,200 @@ +;;; html-wtoc.el --- Creating pages with site TOC +;; +;; Author: Lennart Borgman (lennart O borgman A gmail O com) +;; Created: Sat Feb 11 00:06:14 2006 +(defconst html-wtoc:version "0.2") ;; Version: +;; Last-Updated: Sun Nov 04 21:49:34 2007 (3600 +0100) +;; Keywords: +;; Compatibility: +;; +;; Features that might be required by this library: +;; +;; None +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile (add-to-list 'load-path default-directory load-path)) +(eval-when-compile (require 'html-site nil t)) + +;;;###autoload +(defgroup html-wtoc nil + "Customization group for html-wtoc." + :group 'nxhtml) + +(defcustom html-wtoc-dir + (file-name-as-directory + (expand-file-name + "html-wtoc" + (file-name-directory + (if load-file-name load-file-name buffer-file-name)))) + + "Directory where the tools needed are located. +The tools for html-wtoc includes: + +- html-wtoc.pl +- html-wtoc.js +- html-wtoc.css +- html-wtoc-template.htm +- html-wtoc-template.js +- html-wtoc-template.css +- img/ + +" + :type 'directory + :group 'html-wtoc) + +;; (defun html-wtoc-get-parsed-html-toc () +;; (save-excursion +;; (let ((toc-file (html-toc-file))) +;; (unless (file-exists-p toc-file) +;; (html-toc-write-toc-file)) +;; (with-current-buffer (find-file-noselect toc-file) +;; (goto-char (point-min)) +;; (let ((toc-begin (search-forward html-toc-mark-begin nil t)) +;; (toc-middle (search-forward html-toc-mark-middle nil t)) +;; toc-parsed) +;; (unless (and toc-begin toc-middle) +;; (error "Can't find table of contents in %s" toc-file)) +;; (setq toc-parsed (html-toc-parse-toc +;; (buffer-substring-no-properties +;; toc-begin toc-middle)))))))) + +;; (defun html-wtoc-get-atags (parsed-ul level) +;; (assert (eq 'ul (car parsed-ul))) +;; (let (atags) +;; (dolist (l parsed-ul) +;; (when (and (listp l) +;; (eq 'li (car l))) +;; (dolist (ll l) +;; (when (listp ll) +;; (when (eq 'a (car ll)) +;; (setq atags +;; (cons +;; (list level +;; (caddr ll) +;; (cdaadr ll)) +;; atags))) +;; (when (eq 'ul (car ll)) +;; (let ((subs (html-wtoc-get-atags ll (1+ level)))) +;; (dolist (s subs) +;; (setq atags (cons s atags))))))))) +;; (reverse atags))) + +;; (defcustom html-wtoc-pages-default-name "html-wtoc-pages.txt" +;; "Default file name sans directory for list of pages file. +;; This file is located in the same directory as `html-toc-file'." +;; :type 'string) + +;; (defun html-wtoc-pages-file () +;; (expand-file-name html-wtoc-pages-default-name +;; (file-name-directory (html-toc-file)))) + +(defun html-wtoc-browse-page-with-toc () + (interactive) + (unless buffer-file-name + (error "This buffer is not visiting a file")) + (html-site-current-ensure-site-defined) + (let ((merge-dir (html-site-current-merge-dir)) + merged-file + (in-site (html-site-dir-contains + (html-site-current-site-dir) + buffer-file-name))) + (unless merge-dir + (error "There is no output dir for pages with TOC defined for the site %s" + html-site-current)) + (unless in-site + (error "This buffer's file is not in %s" (html-site-current-site-dir))) + (setq merged-file + (expand-file-name + (file-relative-name buffer-file-name + (html-site-current-site-dir)) + (html-site-current-merge-dir))) + (unless (file-exists-p merged-file) + (error "The file %s does not yet exist.\nPlease do use `html-wtoc-write-merged' to create it." + merged-file)) + (browse-url-of-file merged-file))) + + +(defun html-wtoc-write-pages-with-toc (allow-overwrite) + "Merge the TOC with the pages. + +If an entry with the name MERGE-NAME exists in `html-wtoc-merges' +then this is chosen. Otherwise a new entry is created and added +to `html-wtoc-merges'. The entry has all necessary information to +do the merge. + +If `html-move-site-directory' has a non-nil value then the list +of completions when prompting for MERGE-NAME contains only those +merge names from `html-wtoc-merges' where the site directory has +the same value. Otherwise the completion list contains all merge +names and `html-move-site-directory' will be set to the chosen +merge's site directory. + +The merging of the pages and the table of contents is done in a +subprocess using a Perl script named html-wtoc.pl the directory +`html-wtoc-dir'. +" + (interactive (list (y-or-n-p "Allow overwrite? "))) + (html-site-current-ensure-site-defined) + (let ((pag-file (html-site-current-page-list)) + (out-dir (html-site-current-merge-dir)) + (tpl-file (html-site-current-merge-template)) + (html-wtoc-pl (expand-file-name "html-wtoc.pl" html-wtoc-dir)) + ) + (unless (< 0 (length pag-file)) + (error "Page list file not defined for site %s" html-site-current)) + (unless (file-exists-p pag-file) + (error "Can't find page file for site %s.\nHave you done M-x html-toc-create-pages-file?" + html-site-current)) + (unless (< 0 (length tpl-file)) + ;;(error "Template file not defined for site %s.\nPlease use customize to add this in `html-site-list'." html-site-current) + (setq tpl-file (expand-file-name "html-wtoc-template.html" html-wtoc-dir)) + ) + (let ( + (buffer (noshell-procbuf-setup "*Merging pages and TOC*")) + (opt (list + (concat "pages=" pag-file) + (concat "outroot=" out-dir) + (concat "template=" tpl-file)))) + (when allow-overwrite + (setq opt (cons "update=1" opt))) + (apply 'noshell-procbuf-run + buffer + "perl" "-w" + html-wtoc-pl "merge" + opt + )))) + +(provide 'html-wtoc) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; html-wtoc.el ends here diff --git a/emacs/nxhtml/nxhtml/html-wtoc/PerlLib/PathSubs.pm b/emacs/nxhtml/nxhtml/html-wtoc/PerlLib/PathSubs.pm new file mode 100644 index 0000000..e95b8d5 --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-wtoc/PerlLib/PathSubs.pm @@ -0,0 +1,207 @@ +# Copyright 2006 Lennart Borgman, http://OurComments.org/. All rights +# reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. + +package PathSubs; + +##################################################### +### This package contains general path handling +### routines and some win32 specific dito. +### The latter should ev be moved to a new module! +##################################################### +use strict; + +use File::Spec; + +### Absolute path names + +sub is_abs_path ($) { + my $path = shift; + return 0 if $path eq ""; + return 1 if File::Spec->file_name_is_absolute($path); + #return 1 if substr($path, 1, 1) eq ":"; # MSWin32 + #return 1 if substr($path, 0, 1) eq "/"; + return 1 if $path =~ /^https?:/i; + return 1 if $path =~ /^file:/i; + return 1 if $path =~ /^javascript:/i; + return 1 if $path =~ /^mailto:/i; +} +sub is_abs_netpath($) { + my $path = shift; + return 1 if $path =~ /^https?:/i; + # New + return 1 if $path =~ /^ftp:/i; + return 1 if $path =~ /^mailto:/i; +} + + +sub uniq_file($) { + my $fname = shift; + $fname =~ s!^\s+|\s+$!!g; + return "" if ($fname eq ""); + $fname = File::Spec->rel2abs($fname); + if (!File::Spec->file_name_is_absolute($fname)) { + die "File name is not absolute: $fname"; + } + #print STDERR "uniq_file($fname)\n"; + $fname =~ tr!\\!/!; + if (-e $fname) { + #print STDERR "exists $fname\n"; + ### There is an error in 522, compensate for this! + #die substr($fname, -1); + if (substr($fname, -1) eq "/") { chop $fname; } + #print STDERR "exists $fname\n"; + ### Translate .. + if (substr($fname, 1, 1) eq ":") { + my $ffname = Win32::GetFullPathName($fname); + ### Get case + my $lfname = Win32::GetLongPathName($ffname); + #print STDERR "lexists $lfname\n"; + $fname = $lfname if ($lfname ne ""); + } + } else { + #print STDERR "NOT exists $fname\n"; + if (substr($fname, -1) eq "/") { chop $fname; } + my $head = ""; + if (substr($fname, 0, 2) eq "//") { + $head = "//"; + $fname = substr($fname, 2); + } + my @fname = split("/", $fname); + my $tail = pop @fname; + $fname = uniq_dir($head . join("/", @fname)) . $tail; + } + if (substr($fname, 1, 1) eq ":") { + $fname = uc(substr($fname, 0, 1)) . substr($fname, 1); + #print STDERR "fname $fname\n"; + } + $fname =~ tr!\\!/!; + #print STDERR "fname ($fname)\n"; + return $fname; +} +sub uniq_dir($) { + my $dir = shift; + my $uq_dir = uniq_file($dir); + if (substr($uq_dir, -1) ne "/") { $uq_dir .= "/"; } + return $uq_dir; +} + + + +### Relative paths +sub _get_link_root($) { + my $lnk = shift; + if ($lnk =~ m!^(/|ftp://[^/]*|https?://[^/]*|[a-z]:/)!i) { + return $1; + } else { + return ""; + } +} + +sub resolve_dotdot($) { + my $orig_url = shift; + my $root = _get_link_root($orig_url); + return $orig_url if length($root) == length($orig_url); + my $url = substr($orig_url, length($root)); + if (substr($root, -1) eq "/") { + chop $root; + $url = "/$url"; + } + #die "$root\n$url"; + my $iPosSearch = 2; + #print "url=$url\n"; + while ((my $iPos = index($url, "/../", $iPosSearch)) > -1) { + my $sLeft = substr($url, 0, $iPos); + if (substr($sLeft, -2) eq "..") { + $iPosSearch += 3; + next; + } + my $sRight = substr($url, $iPos+3); + #print "url=$url\n"; + #print "iPos=$iPos\n"; + #print "sLeft=$sLeft\n"; + $sLeft =~ s!/[^/]*$!!; + #print "sLeft=$sLeft\n"; + #print "sRight=$sRight\n"; + $url = $sLeft . $sRight; + #print "\t***url=$url\n"; + #print "url=$url\n"; + } + if (index($url, "../") > -1) { + return $orig_url; + } + return $root . $url; +} + +sub mk_relative_link($$;$) { + my $from = shift; + my $to = shift; + my $norm = shift; + if ($norm) { + $from = uniq_file($from); + $to = uniq_file($to); + } + if (-e $from) { + $from = uniq_file($from); + } else { + $from = resolve_dotdot($from); + } + if (-e $to) { + $to = uniq_file($to); + } else { + $to = resolve_dotdot($to); + } + my $root_from = _get_link_root($from); + my $root_to = _get_link_root($to ); + if ($root_from ne $root_to) { + return $to; + } + my @from = split "/", $from; + my @to = split "/", $to; + while (@to) { + last if ($to[0] ne $from[0]); + shift @to; + shift @from; + } + if (@to == 1 && @from == 1) { + if (length($to[0]) > length($from[0])) { + if (substr($to[0], 0, length($from[0])+1) eq ($from[0] . "#")) { + return substr($to[0], length($from[0])); + } + } + } + my $rl; + for (1..$#from) { $rl .= "../"; } + $rl .= join("/", @to); + + return $rl; +} + + + +sub mk_absolute_link($$) { + my $from = shift; + my $rel_to = shift; + my $abs = $from; + $abs =~ s![^/]*$!!; + $abs .= $rel_to; + if (!is_abs_netpath($abs)) { $abs = uniq_file($abs); } + $abs; +} + + +1; diff --git a/emacs/nxhtml/nxhtml/html-wtoc/PerlLib/html_tags.pm b/emacs/nxhtml/nxhtml/html-wtoc/PerlLib/html_tags.pm new file mode 100644 index 0000000..ecdfd53 --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-wtoc/PerlLib/html_tags.pm @@ -0,0 +1,127 @@ +# Copyright 2006 Lennart Borgman, http://OurComments.org/. All rights +# reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. + + +package html_tags; +use strict; + +use vars qw($AUTOLOAD); + +sub _make_attributes { + my($self,$attr) = @_; + return () unless $attr && ref($attr) && ref($attr) eq 'HASH'; + my(@att); + foreach (keys %{$attr}) { + my($key) = $_; + $key=~s/^\-//; # get rid of initial - if present + #$key=~tr/a-z_/A-Z-/; # parameters are upper case, use dashes + $key=~tr/A-Z_/a-z-/; # parameters are lower case in XHTML + push(@att,defined($attr->{$_}) ? qq/$key="$attr->{$_}"/ : qq/$key/); + } + return @att; +} + +sub _tag { + my $tag_name = shift; + my $part = shift; + my($attr) = ''; + if (ref($_[0]) && ref($_[0]) eq 'HASH') { + my(@attr) = html_tags::_make_attributes( '',shift() ); + $attr = " @attr" if @attr; + } + #return "<$tag_name$attr />" unless @_; + return "<$tag_name$attr />" if $part == 1; + return "<$tag_name$attr>" if $part == 2; + my($tag,$untag) = ("<$tag_name$attr\n>",""); + my @result = map { "$tag$_$untag" } (ref($_[0]) eq 'ARRAY') ? @{$_[0]} : "@_"; + return $result[0] if $part == 1; + return "@result"; +} + +sub _mk_tag_sub($$) { + my $name = shift; + my $package = shift; + my $caller = caller; + my $sep = ($name =~ s/^\*//); + my $lc_name = lc $name; + my $code = + ($lc_name =~ m/^(?:br|hr|input|img)$/ ? + "sub $package\:\:$name(;\$\$) { return $caller\:\:_tag('$lc_name',1,\@_); }\n" + : + "sub $package\:\:$name(\$;\$) { return $caller\:\:_tag('$lc_name',0,\@_); }\n" + ); + if ($sep) { + if ($lc_name eq "html") { + $code .= "sub $package\:\:start_$name(\$;\$\$) + {return $caller\:\:_start_html(\@_);}\n"; + $code .= "sub $package\:\:end_$name {return $caller\:\:_end_html();}\n"; + } else { + $code .= "sub $package\:\:start_$name(;\$\$) + {return $caller\:\:_tag('$lc_name',1,\@_);}\n"; + $code .= "sub $package\:\:end_$name {'';}\n"; + } + } + $code; +} +sub _start_html { + my $title = shift; + my $head_tags = shift; + my $body_attr = shift; + # compensate for perl laziness... (will not detect undef sub) + $head_tags = $head_tags . _tag("title", 0, $title); + my $start = + _tag("html", 2) . + _tag("head", 0, $head_tags) . + _tag("body", 2, $body_attr); +} +sub _end_html { + return ''; +} + +sub header(@) { + my @lines = @_; + my $header; + my $type; + while (@lines) { + my $key = shift @lines; my $value = shift @lines; + $header .= "$key: $value\n"; + $type = $value if $key =~ m/content-type/i; + } + $header .= "Content-type: text/html\n" unless defined $type; + $header .= "\n"; +} +sub import { + shift; + my %exported; + $exported{$_}++ for (@_); + my $caller = caller; + my $to_eval = "package $caller;\n"; + for my $name (keys %exported) { + die "Will not redefine $caller\:\:$name" if $caller->can($name); + my $func; + if ($name eq "header") { + $func = "sub header { html_tags::header(); }"; + } + $func = _mk_tag_sub($name, $caller) unless defined $func; + $to_eval .= "$func\n"; + } + eval $to_eval; + die $@ if $@; +} + +1; diff --git a/emacs/nxhtml/nxhtml/html-wtoc/html-wtoc-template.css b/emacs/nxhtml/nxhtml/html-wtoc/html-wtoc-template.css new file mode 100644 index 0000000..a6ffabb --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-wtoc/html-wtoc-template.css @@ -0,0 +1,141 @@ +/* Main structures >>>>>>>>>>>>>>> */ +.html-wtoc-maintop { + font-size: 1px; + font-size: 1em; + margin-top: 0em; + margin-bottom: 0em; +/* background-color:green; */ +} +.html-wtoc-main { +} + +td.html-wtoc-vdivline { + //background-color: #8be; + width: 0px; +} + +.html-wtoc-search-form { + margin-bottom: 0.1em; +} +.html-wtoc-search { + font-size: 0.8em; + color: green; +} +.html-wtoc-search a { + color: green; +} +/* <<<<<<<<<<<<<<<<<<< */ + + + + +/* Table of content >>>>>>>>>>>>>> */ + +#html-wtoc-id-hidetoc { + height: 20px; + border-bottom: 2px inset #ddf; + border-color: #dff; +} + +#html-wtoc-id-tocdiv { + width: 2.5em; + //background-color: #eff; +} +#html-wtoc-id-logo { + width: 100%; + height: 120px; + padding: 0em; + margin: 0em; + border: 0em; +} +#html-wtoc-id-toc { +} +#html-wtoc-id-tocwidth { + width: 18em; + height: 0em; + padding: 0em; + margin: 0em; + border: 0em; + line-height: 0em; +/* background-color: red; */ +} +#html-wtoc-id-toccol { + width: 18em; +} + +.html-wtoc-contcol { + background-color: #dFEfff; + background-color: #dFEfff; + background-color: #cd950c; + background-color: #eead0e; +} +/* <<<<<<<<<<<<<<<<<<< */ + + + + +/* Buttons etc >>>>>>>>>>>>>>> */ +.html-wtoc-button { + font-size: 0.75em; + font-size: 8pt; + color: #5A5D00; + background-color: #9cf; + background-color: #bcee68; + background-color: #a2cd5a; + padding: 0.2em; + Border-Width: 2px; + Border-Style: outset; + text-align: center; + border-color: #ddf; +} +a.html-wtoc-button { + text-decoration: none; + color: #5A5D00; +} +a.html-wtoc-button:hover { + text-decoration:none; + background-color: #6af; + color:#340; +} + +a.html-wtoc-buttonimg img { + width: 16px; + height: 16px; + padding: 4px; + border: 8px; +} +a.html-wtoc-buttonimg { + border:2px; + margin:2px; + margin-left:2px; + margin-right:2px; +} +a.html-wtoc-buttonimg { + font-size:1px; +} +a.html-wtoc-buttonimg:hover { + margin: 6px; + margin-left:0px; + margin-right:0px; + border-color: #ddf; + border-width: 2px; + border-style: outset; + background-color: #595C00; + background-color: #bef; + background-color: #b9ffb9; +} + +/* <<<<<<<<<<<<<<<<<<< */ + + +#nxhtml-link { + font-size: 0.7em; + text-align: center; + padding-top: 2em; + padding: 1em; +} + +.copyright { + color : #872; +} + diff --git a/emacs/nxhtml/nxhtml/html-wtoc/html-wtoc-template.html b/emacs/nxhtml/nxhtml/html-wtoc/html-wtoc-template.html new file mode 100644 index 0000000..440ece7 --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-wtoc/html-wtoc-template.html @@ -0,0 +1,143 @@ + + + + + HEAD + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + +
+ + + + +
+ Show table of content + + + +
+ + + + + +
+ + + + + + + +
%%TOC%%
+
+
+
+
+ + + + + + +
    +

+ +   +

+ %%PAGE%% +

 

+ +
+
+
 
+
+ + diff --git a/emacs/nxhtml/nxhtml/html-wtoc/html-wtoc.css b/emacs/nxhtml/nxhtml/html-wtoc/html-wtoc.css new file mode 100644 index 0000000..a12cb65 --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-wtoc/html-wtoc.css @@ -0,0 +1,84 @@ +body { + margin: 0; +} +td { + font-size: 1em; +} + +/* Added by html-wtoc.pl >>>>>>>>>>>>> */ +.html-wtoc-mark { +/* background-color: #9cf; */ +/* background-color: #bcee68; */ +/* background-color: #a2cd5a; */ + width: 20px; + padding: 0; + border: 0; + text-align: center; +} +.html-wtoc-contline { + width: 100%; +} + +.html-wtoc-margin { + width: 0.6em; +} +.html-wtoc-contents { + font-size: 0.9em; + padding: 1em; + background-color: #9cf; + background-color: #a2cd5a; + background-color: #efffcf; + background-color: #ffffdf; + -moz-border-radius-topleft: 2em; +} +.html-wtoc-contents td { +/* background-color: #9cf; */ +/* background-color: #bcee68; */ +/* background-color: #a2cd5a; */ +} +.html-wtoc-contents-a { + text-decoration: none; + color: #595C00; +/* background-color: #9cf; */ +/* background-color: #bcee68; */ +/* background-color: #a2cd5a; */ + border: 1px #9cf solid; + border: 1px #a2cd5a solid; + border: 1px #ffffc0 solid; + padding-left: 0.25em; + padding-right: 0; + margin: 1px; + display: block; +} +.html-wtoc-contents a:hover { + text-decoration: none; + background-color: #b9ffb9; + border: 1px #6b8e23 solid; +} +.html-wtoc-currcont { + background-color: #738600; + color: #ffff2f; + background-color: #535600; + border: 1px #6b8e23 inset; + padding-left: 0.25em; + padding-right: 0; + margin: 1px; + display: block; +} +a.html-wtoc-currcont { + text-decoration: none; +} +a.html-wtoc-currcont:hover { + background-color: #738600; + background-color: #536600; + background-color: #434620; +} +/* <<<<<<<<<<<<<<<<<<< */ + + + + + + + + diff --git a/emacs/nxhtml/nxhtml/html-wtoc/html-wtoc.js b/emacs/nxhtml/nxhtml/html-wtoc/html-wtoc.js new file mode 100644 index 0000000..7f22db7 --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-wtoc/html-wtoc.js @@ -0,0 +1,361 @@ + +// © Copyright 2006 Lennart Borgman, http://www.OurComments.org/. All rights reserved. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth +// Floor, Boston, MA 02110-1301, USA. + + +var HTML_WTOC_NS_sCurrTocId; + + +HTML_WTOC_NS = { + + ///////////////////////////// + //// Basic event functions + ///////////////////////////// + + getEventObject : function (ev) { + var o; + if (window.event) + o = window.event.srcElement; + else if (null != ev) + o = ( ev.target ); + return o; + }, + getEvent : function (ev) { + if (window.event) { + return window.event; + } else if (null != ev) { + return ev; + } + }, + + eventStopPropagation : function (e) { + if (e.stopPropagation) + e.stopPropagation(); + else + e.cancelBubble=true; + }, + + eventPreventDefault : function (e) { + if (e.preventDefault) + e.preventDefault(); + else + e.returnValue=false; + }, + + ///////////////////////////// + //// TOC hide + ///////////////////////////// + + show_content : function (on) { + var toc = document.getElementById("html-wtoc-id-toccol").style; + var tdv = document.getElementById("html-wtoc-id-tocdiv").style; + var shw = document.getElementById("html-wtoc-id-showtoc").style; + var hid = document.getElementById("html-wtoc-id-hidetoc").style; + if (on) { + toc.display = ""; + tdv.display = ""; + shw.display = "none"; + hid.display = ""; + HTML_WTOC_NS.focus_page_link(0); + } else { + toc.display = "none"; + tdv.display = "none"; + shw.display = ""; + hid.display = "none"; + } + }, + + + + + + ///////////////////////////// + //// Open-Close + ///////////////////////////// + onblur_action : function(ev) { + HTML_WTOC_NS_sCurrTocId = null; + }, + onfocus_action : function(ev) { + var o = HTML_WTOC_NS.getEventObject(ev); + if (!o) return; + + HTML_WTOC_NS_sCurrTocId = o.id; + }, + onclick_action : function(ev) { + var o = HTML_WTOC_NS.getEventObject(ev); + var e = HTML_WTOC_NS.getEvent(ev); + if (13 == e.keyCode) return true; + if (!o) return true; + if ("IMG" == o.tagName) o = o.parentNode; + var iId = HTML_WTOC_NS.getIdnumFromId(o.id); + var sChildId = "toc_child_"+iId; + var sOldCurrTocId = HTML_WTOC_NS_sCurrTocId; + HTML_WTOC_NS.toggle_open(sChildId, o); + HTML_WTOC_NS_sCurrTocId = sOldCurrTocId; + return false; + }, + + toggle_open : function (id, parent) { + var child = document.getElementById(id).style; + var sInner = parent.innerHTML; + var re = new RegExp("[^/]*\.gif", "i"); + if ("none" == child.display) { + child.display = ""; + parent.innerHTML = sInner.replace(re, "down.gif")+""; + } else { + child.display = "none"; + parent.innerHTML = sInner.replace(re, "right.gif")+""; + } + }, + + + + ///////////////////////////// + //// Load + ///////////////////////////// + + onload_actions : function (iPageNum) { + document.body.onkeydown = HTML_WTOC_NS.onkeydown_action; + document.body.onmouseover = HTML_WTOC_NS.onmouseover_action; + var aATags = document.getElementsByTagName("a"); + for(var i = 0; i < aATags.length; i++) { + var o = aATags[i]; + if (null != HTML_WTOC_NS.getIdnumFromId(o.id)) { + o.onfocus = HTML_WTOC_NS.onfocus_action; + o.onblur = HTML_WTOC_NS.onblur_action; + if (o.id.substr(0, 12) == "opener_text_") { + o.onclick = HTML_WTOC_NS.onclick_action; + o.title = "Open/Close"; + } else if (o.id.substr(0, 7) == "opener_") { + o.onclick = HTML_WTOC_NS.onclick_action; + o.className = "html-wtoc-mark"; + o.title = "Open/Close"; + } + } + } + HTML_WTOC_NS.focus_page_link(iPageNum); + }, + focus_page_link : function (iPageNum) { + // Element might be hidden + try { + document.getElementById("toc_link_"+iPageNum).focus(); + } catch (exc) { + } + }, + + + + + + + + ///////////////////// + //// Mouse + ///////////////////// + + onmouseover_action : function (ev) { + if (null == HTML_WTOC_NS_sCurrTocId) return true; + var o = HTML_WTOC_NS.getEventObject(ev); + var iId = HTML_WTOC_NS.getIdnumFromId(o.id); + if (null == iId) return true; + o.focus(); + }, + + + + ///////////////////// + //// Key + ///////////////////// + + onkeydown_action: function (ev) { + var keyDown = 40; + var keyUp = 38; + var keyLeft = 37; + var keyRight = 39; + var keyReturn = 13; + var keyF2 = 113; + var keyInsert = 45; + // Opera + var keyOperaDown = 57386; + var keyOperaUp = 57385; + var keyOperaLeft = 57387; + var keyOperaRight = 57388; + var keyOperaF2 = 57346; + var keyOperaInsert = 57394; + + var SwitchKey = keyInsert; + var SwitchKeyOpera = keyOperaInsert; + + var bUp; + var e = HTML_WTOC_NS.getEvent(ev); + if (null == HTML_WTOC_NS_sCurrTocId) { + switch (e.keyCode) { + case SwitchKey: + case SwitchKeyOpera: + HTML_WTOC_NS.focus_page_link(0); + HTML_WTOC_NS.eventStopPropagation(e); + HTML_WTOC_NS.eventPreventDefault(e); + return false; + } + return true; + } + switch (e.keyCode) { + case keyLeft: + case keyOperaLeft: + case keyRight: + case keyOperaRight: + HTML_WTOC_NS.handle_leftright_keys(e); + HTML_WTOC_NS.eventStopPropagation(e); + HTML_WTOC_NS.eventPreventDefault(e); + return false; + case keyDown: + case keyOperaDown: + bUp = false; + break; + case keyUp: + case keyOperaUp: + bUp = true; + break; + case SwitchKey: + case SwitchKeyOpera: + if (null != HTML_WTOC_NS_sCurrTocId) { + var o = document.getElementById(HTML_WTOC_NS_sCurrTocId); + if (o) o.blur(); + HTML_WTOC_NS_sCurrTocId = null; + } + HTML_WTOC_NS.eventStopPropagation(e); + HTML_WTOC_NS.eventPreventDefault(e); + return false; + default: + //alert(e.keyCode); + return true; + } + var oOpener; + oOpener = HTML_WTOC_NS.getNextVisOpener(HTML_WTOC_NS_sCurrTocId, bUp); + oOpener.focus(); + HTML_WTOC_NS.eventStopPropagation(e); + HTML_WTOC_NS.eventPreventDefault(e); + return false; + }, + + handle_leftright_keys: function (e) { + var keyLeft = 37; + var keyRight = 39; + var keyOperaLeft = 57387; + var keyOperaRight = 57388; + var iId = HTML_WTOC_NS.getIdnumFromId(HTML_WTOC_NS_sCurrTocId); + if (null == iId) return; + var sId = "opener_" + iId; + var oOpener = document.getElementById(sId); + var sId = HTML_WTOC_NS_sCurrTocId; // It will be cleared before getNextVis + + var bOpenAction; + var bOpened; + var bUp; + var oChild = document.getElementById("toc_child_"+iId); + if (null == oChild) { + } else { + bOpened = (oChild.style.display != "none"); + } + switch (e.keyCode) { + case keyLeft: + case keyOperaLeft: + bUp = true; + bOpenAction = (null != bOpened) && (bOpened); + break; + case keyRight: + case keyOperaRight: + bUp = false; + bOpenAction = (null != bOpened) && (!bOpened); + break; + default: + alert("bad key handling..."); + } + if (bOpenAction) { + oOpener.click(); + HTML_WTOC_NS_sCurrTocId = sId; + } else { + var oPrev = HTML_WTOC_NS.getNextVisOpener(sId, bUp); + oPrev.focus(); + } + }, + + + + + + + ////////////////////// + //// Util + ////////////////////// + getNameFromId: function (sId) { + var re = new RegExp("(.*?_)(\\d+)", "i"); + if (!re.test(sId)) return null; + var iId = sId.replace(re, "$1"); + return iId; + }, + getIdnumFromId: function (sId) { + var re = new RegExp("(.*?_)(\\d+)", "i"); + if (!re.test(sId)) return null; + var iId = sId.replace(re, "$2"); + return iId; + }, + + + getNextVisOpener: function (sId, bUp, bTrace) { + if (bTrace) alert("getNextVisOpener("+sId+","+bUp+")"); + var iId = HTML_WTOC_NS.getIdnumFromId(sId); + if (null == iId) { + alert("getNextVisOpener err iId==null"); + return; + } + var sIdName = HTML_WTOC_NS.getNameFromId(sId); + if (null == sIdName) { + alert("getNextVisOpener err sIdName==null"); + return; + } + var oOpener; + var iLoop = -2; + while (oOpener == null) { + if (bTrace) alert(iId); + if (iLoop++ > iMaxChildNum) { alert("Child num error"); return; } + if (!bUp) { + iId++; + } else { + iId--; + } + if (iId > iMaxChildNum) { iId = 0; } + if (iId < 0) { iId = iMaxChildNum; } + var s = sIdName+iId; + oOpener = document.getElementById(s); + if (oOpener != null) { + if (bTrace) alert(oOpener.offsetLeft); + if (oOpener.style.display == "none") { // All + oOpener = null; + } else if (oOpener.offsetLeft < 0) { // IE + oOpener = null; + } else if (0 == oOpener.scrollWidth) { // Opera + oOpener = null; + } + } + } + return oOpener; + } + + + +}; //HTML_WTOC_NS diff --git a/emacs/nxhtml/nxhtml/html-wtoc/html-wtoc.pl b/emacs/nxhtml/nxhtml/html-wtoc/html-wtoc.pl new file mode 100644 index 0000000..56c0e21 --- /dev/null +++ b/emacs/nxhtml/nxhtml/html-wtoc/html-wtoc.pl @@ -0,0 +1,1395 @@ +#! perl + +# Copyright 2006, 2007 Lennart Borgman, http://OurComments.org/. All +# rights reserved. +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This file is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +use strict; +use File::Copy; +use File::Spec; +#use File::Path qw(); +use File::Path; +use File::Find qw(); +use FindBin; + +use lib "$FindBin::Bin/PerlLib"; +use PathSubs qw(); +use html_tags qw( +*html header +div +table Tr td +p hr br +a span img b +); + +### Script start parameters +my $m_param_action; +my $m_param_files = 1; +my $m_param_pnum = 0; +my $m_param_single = 0; +my $m_param_Template; +my $m_param_InPages; +my $m_param_OutRoot; +my @m_param_InRoot; +my $m_param_Overwrite; + +### Globals +my $m_iAlwaysOpenedLevel = 0; +my $m_sCommonIn; +my $m_sInPagesFolder; +my $m_sTemplateFolder; +my $m_sStartTemplate; +my $m_sBodyTemplate; +#my $m_sEndTemplate; +my $m_bBorders = 0; +my @pages; +my %page_num; +my %js_show_page; +my $m_TemplateTime; +my $m_InPagesTime; +my %m_linked_files; + +sub get_params(); +sub get_template(); +sub read_page_list($); +sub find_pages($$); +sub write_pages(); +sub send_page(); +sub find_template_files(); +sub find_linked_from_pages(); +sub copy_wtoc_files(); +sub copy_linked_files(); + +#push @pages, [$ind, $tit, $full_fil, $anc, $hrf, $trg, $tip]; +sub IND { 0 } +sub TIT { 1 } +sub FULL_FIL { 2 } +sub ANC { 3 } +sub HRF { 4 } +sub TRG { 5 } +sub TIP { 6 } + +########################################################## +### Main +########################################################## +print "\n"; +get_params(); +if ($m_param_action eq "FIND") { + find_pages(\@m_param_InRoot, $m_param_InPages); +} elsif($m_param_action eq "MERGE") { + get_template(); + read_page_list($m_param_InPages); + find_template_files(); + copy_wtoc_files(); + if ($m_param_files) { + write_pages(); + } else { + send_page(); + } + find_linked_from_pages(); + copy_linked_files(); +} elsif($m_param_action eq "TOC") { +} +exit; + +sub copy_if_newer_or_overwrite($$) { + my $in_file = shift; + my $out = shift; + my $out_file = $out; + if (-d $out) { + my ($in_v, $in_d, $in_f) = File::Spec->splitpath( $in_file ); + my ($out_v,$out_d,$out_f) = File::Spec->splitpath( $out, 1 ); + $out_file = File::Spec->catpath( $out_v, $out_d, $in_f ); + } + my $should_write = 1; + if (-e $out_file) { + if ($m_param_Overwrite) { + my $in_mdt = (stat $in_file)[9]; + my $outmdt = (stat $out_file)[9]; + if (($outmdt > $in_mdt)) { + $should_write = 0; + } + } else { + $should_write = 0; + } + } + if ($should_write) { + if (!File::Copy::syscopy($in_file, $out_file)) { + die "syscopy($in_file, $out_file): $!"; + } else { + print " $in_file => $out_file\n"; + } + } +} # copy_if_newer_or_overwrite + +sub copy_wtoc_files() { + print "\n**** Copy html-wtoc files\n"; + mkdir $m_param_OutRoot, 0777; + my $css_file = $FindBin::Bin . "/html-wtoc.css"; + copy_if_newer_or_overwrite($css_file, $m_param_OutRoot); + my $js_file = $FindBin::Bin . "/html-wtoc.js"; + copy_if_newer_or_overwrite($js_file, $m_param_OutRoot); + my $OutRootImg = $m_param_OutRoot . "img/"; + mkpath($OutRootImg); + my $imgsrc = $FindBin::Bin . "/img/"; + opendir(IMGDIR, $imgsrc) or die "Can't opendir $imgsrc: $!"; + while (my $imgfile = readdir(IMGDIR)) { + my $outimg = $OutRootImg . $imgfile; + $imgfile = $imgsrc . $imgfile; + #print STDERR ">>>$imgfile\n"; + if (-f $imgfile) { + copy_if_newer_or_overwrite($imgfile, $outimg); + } + } + closedir(IMGDIR); +} # copy_wtoc_files + +sub add_to_linked_files($$) { + my $from_file = shift; + my $to_file = shift; + if (exists $m_linked_files{$to_file}) { + my $old_from = $m_linked_files{$to_file}; + unless ($old_from eq $from_file) { + die "Both $from_file and $old_from should be copied to $to_file"; + } + } + $m_linked_files{$to_file} = $from_file; +} # add_to_linked_files + +sub copy_linked_files() { + print "\n**** Copy linked files\n"; + my %pages; + for my $pnum (0..$#pages) { + $pages{ full_in_name($pnum) } = 1; + } + for my $to_file (keys %m_linked_files) { + my $from_file = $m_linked_files{$to_file}; + unless (exists $pages{$from_file}) { + if (-e $from_file) { + mkpath4file($to_file); + copy_if_newer_or_overwrite($from_file, $to_file); + } + } + } +} # copy_linked_files + +sub find_linked_files($;$) { + my $in_file = shift; + my $out_file = shift; + $out_file = in2out($in_file) unless ($out_file); + my $whole = get_file($in_file); + while ($whole =~ m!(?:\s|^)(?:href|src)="(.*?)"!gis) { + my $l = $1; + next unless $l =~ m!\.(?:css|js|jpg|jpeg|gif|png)$!; + if (!File::Spec->file_name_is_absolute($l)) { + next if $l =~ m!^javascript:!; + next if $l =~ m!^http://!; + next if $l =~ m!^ftp://!; + next if $l =~ m!^mailto:!; + } + my $rel_l = $l; + my $full_in = $l; + if (File::Spec->file_name_is_absolute($l)) { + $rel_l = PathSubs::mk_relative_link($in_file, $l); + } else { + $full_in = PathSubs::mk_absolute_link($in_file, $l); + } + my $full_out = PathSubs::mk_absolute_link($out_file, $rel_l); + add_to_linked_files($full_in, $full_out); + } +} # find_linked_files + +sub find_template_files() { + print "\n**** Find files referenced in template file\n"; + my $in_file = $m_param_Template; + my $out_file = $m_param_OutRoot . "dummy.htm"; + find_linked_files($in_file, $out_file); +} +sub find_linked_from_pages() { + for my $pnum (0..$#pages) { + next unless defined $pages[$pnum][FULL_FIL]; + next unless $pages[$pnum][FULL_FIL] ne ""; + next if defined $pages[$pnum][TRG]; + find_linked_files( full_in_name($pnum) ); + } +} + +sub should_write_merged($$) { + my $pnum = shift; + my $out_file = shift; + my $should_write = 1; + if (-e $out_file) { + if ($m_param_Overwrite) { + my $srcmdt = page_src_time($pnum); + my $outmdt = (stat $out_file)[9]; + if (($outmdt > $srcmdt) + && ($outmdt > $m_TemplateTime) + && ($outmdt > $m_InPagesTime)) { + $should_write = 0; + } + } else { + $should_write = 0; + } + } + return $should_write; +} +sub write_pages() { + #print STDERR "*** param_OutRoot=$m_param_OutRoot\n"; + if ($m_param_single) { + my $out_file = $m_param_OutRoot . "single_$m_param_pnum.html"; + if (should_write_merged($m_param_pnum, $out_file)) { + my $page = create_single_page($m_param_pnum); + $page = shrink($page); + create_file_and_path($out_file, $page); + } + } else { + my $iPages = 0; + print "\n*** Creating pages:\n"; + for my $pnum (0..$#pages) { + next unless defined $pages[$pnum][FULL_FIL]; + next unless $pages[$pnum][FULL_FIL] ne ""; + next if defined $pages[$pnum][TRG]; + $iPages++; + my $out_file = full_out_name($pnum); + if (should_write_merged($pnum, $out_file)) { + my $page = create_page($pnum); + next unless $page; + print " Creating page $iPages: " . full_in_name($pnum) . "\n"; + $page = shrink($page); + print "\t=> $out_file\n"; + create_file_and_path($out_file, $page); + } + } + } +} # write_pages + +sub send_page() { + my $page = ($m_param_single ? + create_single_page($m_param_pnum) + : + create_page($m_param_pnum) ); + print $page; +} # send_page + +########################################################## +### Params +########################################################## +sub die_usage() { + my $sScript = $0; + $sScript =~ tr!\\!/!; + $sScript =~ s!.*/(.*)!$1!; + die qq(Usage: + Making preliminary file list: + $sScript find in="in-dir" pages="pages-file" [overwrite=1] + + Merging pages and table of contents: + $sScript merge pages="pages-file" outroot="out-dir" template="template-file" [overwrite=1] + + \n); +} +#use Getopt::Long; +sub get_params() { + $| = 1; + for my $arg (@ARGV) { print " "; print $arg; } print "\n\n"; + die_usage() unless $#ARGV > 0; + $m_param_action = $ARGV[0]; + $m_param_action =~ tr/a-z/A-Z/; + #push @m_param_InRoot, $FindBin::Bin . "/doc/"; + #$m_param_OutRoot = $FindBin::Bin . "/tmp/"; + #$m_param_Template = $FindBin::Bin . "/doc/home_template.htm"; + #$m_param_InPages = $FindBin::Bin . "/doc/toc_pages.txt"; + for (my $i = 1; $i <= $#ARGV; $i++) { + my ($k, $v) = ($ARGV[$i] =~ m!(.*?)=(.*)!); + $v =~ tr!\\!/!; + if ($k eq "in") { + $v = PathSubs::uniq_file($v); + $v .= "/" unless substr($v, -1) eq "/"; + push @m_param_InRoot, $v; + } elsif( $k eq "outroot") { + $v = PathSubs::uniq_dir($v); + $v .= "/" unless substr($v, -1) eq "/"; + $m_param_OutRoot = $v; + } elsif( $k eq "pages") { + $v = PathSubs::uniq_file($v); + $m_param_InPages = $v; + } elsif( $k eq "template") { + $v = PathSubs::uniq_file($v); + $m_param_Template = $v; + } elsif( $k eq "overwrite" ) { + $m_param_Overwrite = $v; + } elsif( $k eq "openedlevel" ) { + $m_iAlwaysOpenedLevel = $v * 1; + } else { + die "Unknown parameter: $ARGV[$i]\n"; + } + } + if($m_param_action eq "FIND") { + if ($#m_param_InRoot < 0) { die_usage(); } + if (! defined $m_param_InPages) { die_usage(); } + } elsif($m_param_action eq "MERGE") { + if (! defined $m_param_InPages) { die_usage(); } + if (! defined $m_param_OutRoot) { die_usage(); } + if (! defined $m_param_Template) { die_usage(); } + $m_sTemplateFolder = $m_param_Template; + $m_sTemplateFolder =~ s![^/]*$!!; + } else { + die_usage(); + } + + $m_sInPagesFolder = $m_param_InPages; + $m_sInPagesFolder =~ s![^/]*$!!; + print "Parameters:\n"; + print " " . $m_param_action . "\n"; + print " pages=" . $m_param_InPages . "\n"; + print " outroot=" . $m_param_OutRoot . "\n"; + print " template=" . $m_param_Template . "\n"; + if (defined $m_param_Overwrite) { + print " overwrite=" . $m_param_Overwrite . "\n"; + } + #if ($#m_param_InRoot == -1) { push @m_param_InRoot,$m_sInPagesFolder; } +} + +sub get_template() { + my $sTemplate = get_file($m_param_Template, 1); + $m_TemplateTime = (stat $m_param_Template)[9]; + $m_InPagesTime = (stat $m_param_InPages)[9]; + $sTemplate =~ s///gs; + if ( $sTemplate =~ m!(.*?)(.*)!si ) { + $m_sStartTemplate = $1; + $m_sBodyTemplate = $2; + #$m_sEndTemplate = $3; + } else { + die "Can't find body of template\n"; + } +} # get_template + +sub read_page_list($) { + my $sPagesFile = shift; + my @in_files; + open(P,$sPagesFile) or die "Can't open toc list file $sPagesFile: $!\n"; + while (my $sLine =

) { + chomp $sLine; + $sLine =~ s/^\s+|\s+$//g; + next if $sLine eq ""; + next if substr($sLine, 0, 1) eq ";"; + #print STDERR "$sLine\n"; + my ($ind, $tit, $ref, $tip, $trg, $ico) + = map { s/^\s+|\s+$//g; $_; } split("###", $sLine); + #warn "trg=$trg\n" if defined $trg; + my ($fil, $anc) = ("", ""); + my $hrf = ""; + my $full_fil = ""; + #$ref = "" unless defined $ref; + #print STDERR "ref=$ref\n"; + if (defined $ref) { + if (defined $trg) { undef $trg unless $trg ne ""; } + if ((defined $trg) || ($ref =~ m/https?:/i)) { + $hrf = $ref; + } else { + ($fil, $anc) = split('#', $ref); + if ($ind >= 0) { + if (File::Spec->file_name_is_absolute($fil)) { + $full_fil = $fil; + } else { + $full_fil = PathSubs::uniq_file($m_sInPagesFolder . $fil); + } + } + } + } + if ((!$tip) && ($full_fil ne "")) { + $tip = get_title($full_fil); + } + push @pages, [$ind, $tit, $full_fil, $anc, $hrf, $trg, $tip]; + push @in_files, $full_fil if !defined $trg; + } + close P; + $m_sCommonIn = get_common_root(\@in_files). "/"; +} # read_page_list + + + +sub get_common_root($) { + my $psRoots = shift; + my @sCommon; + for my $s (@$psRoots) { + my $full_s = PathSubs::uniq_file($s); + my @full_s = split("/", $full_s); + if ($#sCommon == -1) { + @sCommon = @full_s; + } else { + my $iMax = $#sCommon; if ($#full_s < $iMax) { $iMax = $#full_s; } + for (my $i = 0; $i <= $iMax; $i++) { + if ($sCommon[$i] ne $full_s[$i]) { + #print STDERR "$i: $sCommon[$i] != $full_s[$i]\n"; + @sCommon = @sCommon[0..$i-1]; + last; + } + } + } + } + my $sCommon = join("/", @sCommon); + return $sCommon; +} # get_common_root + + +sub find_pages($$) { + my $pasInRoot = shift; + my $sOutFile = shift; + if (!$m_param_Overwrite) { + die "Don't want to overwrite existing output file $sOutFile!\n" if -e $sOutFile; + } + my $root_level; + my $sList; + my $handle_file = + sub { + return unless m/.html?/i; + return if -d $_; + my $fname = PathSubs::uniq_file($_); + die "Can't read $fname\n" unless -r $_; + my $title = get_title($_); + my $level = $fname =~ tr!/!!; + $level -= $root_level; + my $rel_fname = PathSubs::mk_relative_link($sOutFile, $fname); + $sList .= "$level ### $title ### $rel_fname\n"; + }; + for my $sInRoot (@$pasInRoot) { + $sInRoot = PathSubs::uniq_file($sInRoot); + chop($sInRoot) if (substr($sInRoot, -1) eq "/"); + $root_level = $sInRoot =~ tr!/!!; + File::Find::find($handle_file, $sInRoot); + } + create_file($sOutFile, $sList); +} # find_pages + + +########################################################## +### File - page helpers +########################################################## + +sub file_name($) { + my $num = shift; + return $pages[$num][FULL_FIL]; +} +sub file_anchor($) { + my $num = shift; + return $pages[$num][ANC]; +} +sub file_href($) { + my $num = shift; + #die $pages[$num][HRF] if defined $pages[$num][HRF]; + return $pages[$num][HRF]; +} +sub file_target($) { + my $num = shift; + return $pages[$num][TRG]; +} +sub file_title($) { + my $num = shift; + return $pages[$num][TIT]; +} +sub file_tip($) { + my $num = shift; + return $pages[$num][TIP]; +} +sub full_in_name($) { + my $num = shift; + my $name = file_name($num); + return $name; +} +sub full_out_href($) { + my $num = shift; + my $anchor = file_anchor($num); + my $full_href = full_out_name($num); + warn "full_href is null" unless $full_href; + if ((defined $anchor) && ($anchor ne "")) { $full_href .= "#" . $anchor; } + return $full_href; +} +sub full_out_name($) { + my $num = shift; + my $in_name = file_name($num); + return unless $in_name; + my $anchor = file_anchor($num); + #$m_param_OutRoot . $name; + $anchor = ""; + my $name = substr($in_name, length($m_sCommonIn)); + if ($anchor) { + my $base; + my $ext; + for (my $i = length($name);$i>0;$i--) { + if (substr($name, $i, 1) eq ".") { + $base = substr($name, 0, $i-1); + $ext = substr($name, $i); + $name = $base . "_sharp_" . $anchor . $ext; + last; + } + } + } + $m_param_OutRoot . $name; +} +sub replace_name_link($) { + my $page = shift; + for my $k (keys %page_num) { + my $num = $page_num{$k}; + my $href = ($m_param_single ? "javascript:ShowPage($num)" : file_name($num)); + $page =~ s!%%$k%%!$href!gs; + } + return $page; +} + +########################################################## +### File name helpers +########################################################## +sub in2out($) { + my $in_name = shift; + die "in2out: File name is not abs: $in_name" unless File::Spec->file_name_is_absolute($in_name); + my $name = substr($in_name, length($m_sCommonIn)); + $m_param_OutRoot . $name; +} + +########################################################## +### File reading/writing +########################################################## + +sub mkpath4file($) { + my $file = shift; + my $path = $file; + $path =~ s|[^/]*$||; + File::Path::mkpath($path); +} +sub create_file($$) { + my ($out_file, $page) = @_; + if (!$m_param_Overwrite) { + if (-e $out_file) { die "Will not overwrite $out_file\n"; } + } + open(OUT, ">$out_file") or die "Can't create $out_file: $!"; + print OUT $page; + close OUT; + chmod 0111|((stat $out_file)[2]&07777), $out_file +} +sub create_file_and_path($$) { + my ($out_file, $page) = @_; + mkpath4file($out_file); + create_file($out_file, $page); +} + + +sub get_file($$) { + my ($file, $need) = @_; + if (open(FL, $file)) { + local $/; + my $whole = ; + close FL; + return $whole; + } else { + my $err = $!; + die "Can't open $file: $err\n" if $need; + return ""; + } +} + +sub get_title($) { + my $file = shift; + open(H, $file) or die "Can't open and get title from $file: $!"; + while (my $line = ) { + if ($line =~ m!(.*?)!i) { close H; return $1; } + } + close H; +} + + + +########################################################## +### Html parsing etc +########################################################## + +sub get_head_from_file($) { + my $fname = shift; + my $err; + my $head = get_head(get_file($fname, 1), \$err); + die "\n\n$fname\n\t" . $err if defined $err; + return $head; +} +# BUG: These actually requires parsing of the file, but it does not +# seem very important: +sub get_head($$) { + my $html = shift; + my $perr = shift; + return "" unless $html; + $html =~ s///g; + if ($html =~ m!(.*)!is) { + return $1; + } + $$perr = "Can't find -tag in $html\n"; +} +sub get_body($) { + my $html = shift; + return "" unless $html; + $html =~ s///gs; + if ($html =~ m!]*>(.*)!is) { + return $1; + } + die "Can't find -tag in $html\n"; +} + +sub shrink($) { + my $str = shift; + my $out_str = ""; + my @str = split("\n", $str); + my $in_pre = 0; + for my $s (@str) { + if ($s =~ m!

!i)  { $in_pre = 1; }
+        if ($s =~ m!
!i) { $in_pre = 0; } + $s =~ s!^(\s*)!! unless $in_pre; + $out_str .= $s . "\n"; + } + return $out_str; + $str =~ s!^(\s*)!!gm; + $str; +} + + +########################################################## +### Making what we see +########################################################## + +sub mk_search() { + return "" if ! $m_param_single; + return qq[ + + Sök + ]; +} +sub mk_main_table($$$$$) { + my $left = shift; + my $main = shift; + my $srch_table = shift; + my $sFile = shift; + my $pNum = shift; + my $search_tr = ""; + if ($m_param_single) { + $search_tr = + Tr( + td("  ") + . td({-valign=>'bottom', }, mk_search(), ) ) + } + my $cont_table = + table( + { -border=>"$m_bBorders", -cellpadding=>0, -cellspacing=>0, + -width=>"100%", + -id=>"html-wtoc-contents", + #-style=>"display:", + -summary=>"Table of contents", + }, + Tr( + #td("  ") + td({-class=>"html-wtoc-margin"}) + . td({-valign=>'top'}, $left) ) + . $search_tr + ) + ; + my $page = $m_sBodyTemplate; + $page = replace_template_links($m_sBodyTemplate, $sFile); + $page =~ s!%%TOC%%!$cont_table!; + $page =~ s!%%PAGE%%!$main!; + return $page; +} # mk_main_table + + +sub find_ind_level_prev($) { + my $lThis = shift; + for (my $i = $lThis - 1; $i > 0; $i--) { + my $ind_lev = $pages[$i][IND]; + if ($ind_lev < 50) { return $ind_lev; } + } + return undef; +} +sub find_ind_level_next($) { + my $lThis = shift; + #print "find_ind_level_next($lThis)"; + #print ", "; + #print file_title($lThis); + #print "\n"; + #for (my $i = $lThis; $i < $#pages; $i++) { + for (my $i = $lThis + 1; $i <= $#pages; $i++) { + my $ind_lev = $pages[$i][IND]; + if ($ind_lev < 50) { return $ind_lev; } + } + return undef; +} + + + + + + + + +sub mk_opener_elem($$$) { + my $iPi = shift; + my $sHref = shift; + my $bOpened = shift; + my $Aattrib = + { + -id =>"opener_$iPi", + }; + if ($sHref) { $$Aattrib{href} = $sHref; } + my $sImg; + my $sAlt; + if ($bOpened) { + $sImg = "down"; + $sAlt = "Close"; + } else { + $sImg = "right"; + $sAlt = "Open"; + } + return + a( + $Aattrib, + img({ + -src=>"img/$sImg.gif", + -alt=>$sAlt, + -border=>0, + -width=>12, + -height=>12, + }, + ), + ); +} # mk_opener_elem + +sub mk_content($) { + my $pnum = shift; + if (!$pages[$pnum]) { + return br(); + } + my $cont; + my @father; + my @child_trace; + my $this_indent = $pages[$pnum][IND]; + my $this_file = $pages[$pnum][FULL_FIL]; + if ($this_indent == -2) { + return ""; + } + my $this_href = full_out_name($pnum); + #my $anchor = file_anchor($pnum); + #if (defined $anchor) { $this_href .= "#" . $anchor; } + my @size; + $size[0] = "1em"; + $size[1] = "0.8em"; + $size[2] = "0.8em"; + + + + ### Open all main level nodes + my @opened; # rename to visible!!!!! + for my $pi (0..$#pages) { + my $indent = $pages[$pi][IND]; + if ($indent <= $m_iAlwaysOpenedLevel) { + $opened[$pi] = 1; + } else { + $opened[$pi] = 0; # more simple to handle + } + } + + + + ### Open ancestors and older sisters (if not a standalone node) + my $pnum_indent = $pages[$pnum][IND]; + my $high_open = $pnum_indent; + my $standalone_open = 10; + if ($high_open < $standalone_open) { ### Not a standalone node + for (my $pi = $pnum; $pi >= 0; $pi--) { + my $pi_indent = $pages[$pi][IND]; + if ($high_open >= $pi_indent) { + $opened[$pi] = 1; + $high_open = $pi_indent; + for (my $ps = $pi+1; $ps <= $#pages; $ps++) { + my $ps_indent = $pages[$ps][IND]; + last if $ps_indent < $pi_indent; + $opened[$ps] = 1 if $ps_indent == $pi_indent; + } + } + last if $pi_indent == 0; + } + } + + + + + ### Open direct childs and younger sisters + my $maybe_child = 1; + my $more_sisters = 1; + my $max_open_indent = $pnum_indent; + for my $pi ($pnum+1..$#pages) { + my $pi_indent = $pages[$pi][IND]; + if ($pi_indent <= $max_open_indent) { $maybe_child = 0; } + if ($pi_indent < $pnum_indent) { $more_sisters = 0; } + if ($pi_indent == $pnum_indent) { + if ($more_sisters) { $opened[$pi] = 1; } + $maybe_child = 0; + } elsif ($pi_indent == $pnum_indent+1) { + if ($maybe_child) { $opened[$pi] = 1; } + } + } + #exit if $pnum == 3; + + + + + ### Open all in the same file (necessary for non-JavaScript) + for my $pi (0..$#pages) { + my $file = $pages[$pi][FULL_FIL]; + #printf STDERR "file - open=(%s)\n", $file; + #if ($file eq $this_file) { + if ($file eq $this_file) { + $opened[$pi] = 1; + } + if ($file eq "") { + if ($pi < $#pages) { + if ($pages[$pi][IND] < $pages[$pi+1][IND]) { + $opened[$pi+1] = 1; + } + } + } + if ($pages[$pi][IND] > 10) { + $opened[$pi] = 0; + #print ">>>>>>>>\$opened[$pi] = 0;\n"; + } + #print STDERR "+++++++++\$opened[$pi] = $opened[$pi]\n"; + } + + + + + ### Make the actual contents + my $tooltip; + my $child_id; + for my $pi (0..$#pages) { +# if (!$pages[$pi][FULL_FIL] && !$pages[$pi][HRF]) { +# my $txt = file_title($pi); #$pages[$pi][TIT]; +# $txt = qq(


) if $txt eq "-"; +# $cont .= $txt; +# $cont .= br(); +# next; +# } + my $txt = file_title($pi); #$pages[$pi][TIT]; + if ($txt eq "-") { + $txt = qq(


); + $cont .= $txt; + $cont .= br(); + next; + } + #if ($pages[$pi][TRG]) { + # next; + #} + #next if ! defined $opened[$pi]; + #next if ! $opened[$pi]; + my $ind_lev = $pages[$pi][IND]; + next if $ind_lev > 50; + my $ind_lev_next = find_ind_level_next($pi); + #my $ind_lev_prev = find_ind_level_prev($pi); + + my $this_entry = ""; + + ### Child id from previous row + if (defined $child_id) { + my $display = ""; + if (!$opened[$pi]) { + $display = qq(style="display:none"); + } else { + } + $this_entry .= "\n

\n"; + undef $child_id; + } + my $opener_elem = ""; #qq( ); + my $childs_are_visible = ($pi == $pnum); + if ($pi < $#pages) { + if ($pages[$pi][IND] < $pages[$pi+1][IND]) { + if ($opened[$pi+1]) { $childs_are_visible = 1; } + } + } + #if ($pages[$pi][IND] < $m_iAlwaysOpenedLevel) { $childs_are_visible = 1; } + + my $file_href; + my $target; + my $href; + my $href_self; + my $target_attrib; + my $title = file_title($pi); + my $file_name = file_name($pi); + if ($title) { + $file_href = file_href($pi); # || ""; + $target = file_target($pi); + $href = + ($file_name ? + ($m_param_files ? + ($m_param_single ? "JavaScript:ShowPage($pi);" : + ($file_href ne ""? $file_href + : + PathSubs::mk_relative_link($this_href, full_out_href($pi)))) + : + ($m_param_single ? "JavaScript:ShowPage($pi)" : "?pnum=$pi") + ) + : + (File::Spec->splitpath($this_href))[2]); + if ($pi == $pnum) { + $href_self = $this_href; + if ($href_self =~ m!([^/\\]*$)!) { + $href_self = $1; + } + } + $target_attrib = (defined $target? qq(target="$target"): ""); + } else { + $href = ""; + $target_attrib = ""; + } + + if (defined $ind_lev_next && $ind_lev_next > $ind_lev) { + $child_id = "toc_child_$pi"; + #print " child_id=$child_id\n"; + push @child_trace, $child_id; + $opener_elem = mk_opener_elem($pi, + ($href? $href : $href_self), + $childs_are_visible); + } + $title =~ s/_/ /go; + my $indent = ($ind_lev ? " " x (($ind_lev-1) * 4) : ""); + my $size = $size[$ind_lev]; + $title = b($title) if $ind_lev == 0; + + my $Aattrib = + { + id=>"toc_link_$pi", + onclick=>"html_wtoc_nailing(this)", + }; + if (!$file_name) { + $Aattrib = + { + id=>"opener_text_$pi", + }; + } + if ($pi == $pnum) { + ### Current page + $$Aattrib{class} = "html-wtoc-currcont"; + $$Aattrib{title} = "You are here"; + $$Aattrib{href} = $href_self; + $this_entry .= + table({ + -cellspacing=>0, + -cellpadding=>0, + -class=>"html-wtoc-contline", + -border=>0, + -summary=>"Formatter", + }, + Tr({ + }, + td({ + }, + a( + $Aattrib, + $indent . $title . " " + ) + ) + . td({ + -class=>"html-wtoc-mark", + }, + $opener_elem + ) + ) + ); + + + + + } else { + ### Link to other page + if (file_title($pi)) { + $tooltip = $pages[$pi][TIP]; + if (!defined $tooltip) { $tooltip = "Go to the page $title"; } + $$Aattrib{class} = "html-wtoc-contents-a"; + my $a_or_span; + if (!defined $href) { + $a_or_span = span($Aattrib, $indent . $title); + } else { + $$Aattrib{title} = $tooltip; + $$Aattrib{href} = $href; + if (defined $target) { $$Aattrib{target} = $target; } + $a_or_span = a($Aattrib, $indent . $title); + } + $this_entry .= + table({ + -cellspacing=>0, + -cellpadding=>0, + -class=>"html-wtoc-contline", + -border=>0, + -summary=>"Formatter", + }, + Tr({ + }, + td({ + }, + $a_or_span + ) + . td({ + -class=>"html-wtoc-mark", + }, + $opener_elem + ) + ) + ); + } else { + $this_entry .= $indent . " " . $title; + #die $this_entry; + } + } + if ((!defined $ind_lev_next) || $ind_lev_next <= $ind_lev) { + my $ind_end = $ind_lev; + if (defined $ind_lev_next) { $ind_end = $ind_lev_next+1; } + for (my $i = $ind_end; $i <= $ind_lev; $i++) { + my $end_id = pop @child_trace; + if (defined $end_id) { + $this_entry .= "
"; # end childs' span + #print " end $end_id\n"; + } + } + } + $cont .= $this_entry; + $father[$ind_lev] = $pi; + } #for my $pi (0..$#pages) + + $cont = div({-class=>"html-wtoc-contents"}, $cont) . p(" "); + #$cont =~ s|<|\n<|gms; + #$cont =~ tr!\n\r! !; + $cont =~ s{ + (\ssrc=)"(.*?)" + } + { + my $s1 = $1; + my $src = $2; + if (!PathSubs::is_abs_path($src)) { + my $srcabs = PathSubs::mk_absolute_link(full_out_name(0), $src); + $src = PathSubs::mk_relative_link(full_out_name($pnum), $srcabs); + }; + "${s1}\"$src\""; + }egsmx; + $cont; +} # mk_content + +sub mk_main_window($) { + my $pnum = shift; + my $full_name = full_in_name($pnum); + return unless defined $full_name; + return get_body(get_file($full_name, 1)); +} + + + + + + + + +########################################################## +### The JavaScripts and styles we need +########################################################## + +sub mk_style($) { + return ""; + my $pnum = shift; + my $rel_link = + PathSubs::mk_relative_link(full_out_name($pnum), $m_param_OutRoot . "html-wtoc.css"); + return qq(\n); +} +sub mk_js($) { + my $pnum = shift; + return <<__HTML_END_JS_PNUM__; + +__HTML_END_JS_PNUM__ + return ""; + my $single_js = ""; + if ($m_param_single) { + $single_js = qq[if (!document.all) { navigate("0.html"); }]; + my $page_info = "var page_name = new Array;\n"; + for my $i (0..$#pages) { + my $page_name = file_title($i); #$pages[$i][TIT]; + $page_info .= qq[ page_name[$i] = "$page_name";\n]; + } + $single_js .= $page_info; + } + my $sch_link = + PathSubs::mk_relative_link(full_out_name($pnum), $m_param_OutRoot . "search.js"); + my $top_link = + PathSubs::mk_relative_link(full_out_name($pnum), $m_param_OutRoot . "html-wtoc.js"); + return <<__HTML_END_JS__; + + + +__HTML_END_JS__ +} + +########################################################## +### Page creation +########################################################## + +sub replace_template_links($$) { + my $template = shift; + my $sFile = shift; + $template =~ s{\ssrc="(.*?)"} + { + my $sSrc = $m_param_OutRoot . $1; + my $sRelSrc = PathSubs::mk_relative_link($sFile, $sSrc); + qq( src="$sRelSrc"); + }exg; + $template =~ s{\shref="(.*?)"} + { + my $sOld = $1; + if ((lc substr($sOld, 0, 11)) eq "javascript:") { + qq( href="$sOld"); + } elsif (PathSubs::is_abs_netpath($sOld)) { + qq( href="$sOld"); + } else { + my $sSrc = $m_param_OutRoot . $sOld; + my $sRelSrc = PathSubs::mk_relative_link($sFile, $sSrc); + qq( href="$sRelSrc"); + } + }exg; + return $template; +} # replace_template_links + +sub mk_start_of_page($) { + my $pnum = shift; + my $page = ""; + my $page_style = mk_style($pnum); + my $page_js = mk_js($pnum); + my $sFile = full_out_name($pnum); + my $head = ""; + $head .= $page_js; + $head .= $page_style; + $head .= get_head_from_file(full_in_name($pnum)); + $page .= header if !$m_param_files; + $page .= replace_template_links($m_sStartTemplate, $sFile); + $page =~ s!HEAD!$head!; + my $focus_pnum = $pnum; + my $ind_lev = $pages[$pnum][IND]; + if ($ind_lev > 50) { $focus_pnum = 0; } + $page =~ s!%%PNUM%%!$focus_pnum!; + return $page; +} # mk_start_of_page + +my %m_sCreatedPages; +sub page_src_time($) { + my $pnum = shift; + my $src_file = $pages[$pnum][FULL_FIL]; + return (stat $src_file)[9]; +} +sub create_page($) { + my $pnum = shift; + return unless $pages[$pnum][FULL_FIL]; + + my $out_name = full_out_name($pnum); + return if exists $m_sCreatedPages{$out_name}; + $m_sCreatedPages{$out_name} = 1; + + my $page = mk_start_of_page($pnum); + my $cont_win = mk_content($pnum); + my $main_win = mk_main_window($pnum); + $page .= mk_main_table( + $cont_win, + $main_win, + "", + $out_name, + $pnum, + ); + $page .= end_html; + $page = replace_name_link($page); + return $page; +} # create_page + + +__END__ + + + ########################################################## + ### Unused currently + ########################################################## + + sub build_ShowPage() { + for my $num (0..$#pages) { + $page_num{$pages[$num][FULL_FIL]} = $num; + my $fon = full_out_name($num); + if ($fon) { $js_show_page{$fon} = "ShowPage($num);"; } + } +} +build_ShowPage(); + + +sub mk_meta_enter_exit() { + return <<__HTML_EE__; + + +__HTML_EE__ +} + +########################################################## +### Single page +########################################################## + +sub mk_noscript() { + return <<__HTML_END_NOSCRIPT__; +