Beruflich Dokumente
Kultur Dokumente
;;
;; dokuwiki.el
;;
;; Letzte �nderung: Time-stamp: <2007-11-05 20:34:47 jv>
;; Version: 0.1
;;
;; Einlesen und Bearbeiten von DokuWiki-Eintr�gen per EMACS.
;;
;; ------------------------------------------------------------
;;
;; Vorgehen:
;;
;; Parameter der Wiki setzen (dokuwiki-username, dokuwiki-password,
;; dokuwiki-base-url). Dann mit dokuwiki-get-page die Seite anfordern.
;; Bestehende Seiten werden per Completion zur Verf�gung gestellt, um
;; eine neue Seite zu erstellen, einfach Namen (evtl. mit Namespace)
;; angeben. Dann befindet man sich in einem Buffer, der entweder leer
;; ist oder den Rohtext der Wikiseite enth�lt. Dank einer angepassten
;; Version des `simple-wiki-mode' (der dann `simple-dokuwiki-mode`
;; heisst) stehen in diesem Buffer diverse Befehle zur einfachen
;; Formatierung und Eingabe der Tags zur Verf�gung. Wichtige
;; Syntaxelemente wie Hervorhebung und Unterstreichen werden
;; angezeigt, �berschriften nach ihrer Priorit�t verschieden gro�
;; dargestellt. Nach dem Editieren der Seite schlie�lich C-c C-c
;; dr�cken, damit wird die Seite zur�ckgeschrieben. Fertig.
;;
;; Die Funktion `dokuwiki-new-blog' kreiiert einen eindeutigen Dateinamen
;; (Tag-Stunde-Monat-Jahr, also eindeutig pro Stunde) im Namespace "blog:".
;; Die neu erstellte Seite wird mit einer rudiment�ren Schablone gef�llt.
;;
;; ------------------------------------------------------------
;;
;; History:
;;
;; - 18.3.2007 (hoffentlich) longlines nun richtig gehandhabt
;; - 12.3.2007 aufger�umt
;; - 10.3.2007 Upload funktioniert nun auch; einige Namen von Funktionen und
Variablen vereinheitlicht
;; - 9.3.2007 Medien-Tags einf�gen, mit media-index
;; - 8.3.2007 Beim Speichern wird nun ein summary erfragt.
;;
;;
;; ------------------------------------------------------------
;; Bekannte Einschr�nkungen:
;;
;; - Das Syntax Highlighting ist sehr rudiment�r.
;;
;; - Die Auswahl der Seiten �ber Completion ist etwas umst�ndlich,
;; wenn es darum geht, in ein Namespace "hineinzuwechseln". Hier
;; schauen, wie find-file es mit den Verzeichnissen macht.
;;
;; - Fehler werden nur grob abgefangen.
;;
;; - Zur Zeit gibt es keine M�glichkeit, mehrere Wikis zu definieren und
;; dann die Zielwiki auszusuchen.
;;
;; - Eventuell sollte die Abh�ngigkeit vom `simple-wiki-mode'
;; aufgel�st werden, so schwer ist es ja auch nicht, einen eigenen
;; Major-Mode zu definieren.
;;
;; - Einige Vorgehensweisen sind recht unelegant, z.B. `dokuwiki-newpage-entered-p'
;;
;; Vorschl�ge f�r weitere Erg�nzungen:
;;
;; - Die Trennung von pagename und namespace wird nur ein einziges Mal
;; wirklich verwendet, n�mlich in `dokuwiki-new-blog'. Besser, dass
;; pagename wie eine Pfadangabe behandelt wird. Dann zwei drei
;; convenience-functions zur Verf�gung stellen, die etwa testen, ob
;; ein Doppelpunkt am Anfang oder am Ende steht, die einen Namen
;; "ranh�ngen" und dabei evtl. einen Doppelpunkt zwischenf�gen, etc.
;;
;; - Follow-link-at-point (siehe dazu oddmuse.el)
;;
(require 'cl)
(require 'simple-wiki)
(require 'skeleton)
;; ============================================================
;; Globale Variablen:
;;
(define-skeleton dokuwiki-new-blog-entry
"Begin a new blog entry."
"Blog heading: "
\n "====== " str " ======" \n \n _ \n \n
"~~DISCUSSION:off~~" \n
)
(define-skeleton dokuwiki-new-page
"Generic Template for new DokuWiki-Page."
"Page Heading: "
\n "====== " str " ======" \n \n _ \n \n
"~~DISCUSSION~~" \n
)
(define-skeleton dokuwiki-new-code-block
"Begin a new code block."
"Language: "
\n "<code " str ">" \n \n _ \n "</code>" \n
)
;; ============================================================
;; Eigenen Major-Mode definieren f�r Fontlock etc.
;;
(simple-wiki-define-major-mode
'dokuwiki
"DokuWiki"
"Simple mode to edit doku wiki pages."
;;
;; TODO:
;;
;; - Kommentare (/* ... */)
;; - Aufz�hlungen
;;
:camelcase 'none
;;
:smilies 'none
;;
:headlines '(("^=\\{6\\}\\([^\n=]+\\)=\\{6\\}\\([^=]\\|$\\)" . 1)
("^=\\{5\\}\\([^\n=]+\\)=\\{5\\}\\
([^=]\\|$\\)" . 1)
("^=\\{4\\}\\([^\n=]+\\)=\\{4\\}\\
([^=]\\|$\\)" . 1)
("^=\\{3\\}\\([^\n=]+\\)=\\{3\\}\\
([^=]\\|$\\)" . 1)
("^=\\{2\\}\\([^\n=]+\\)=\\{2\\}\\
([^=]\\|$\\)" . 1)
("^=\\([^\n=]+\\)=[^=]" . 1))
;;
:free-link 'none ;; '("\\[\\[\\([^|\n]+?\\)\\]\\]" . 1)
;;
:strong-strings '("**" . "**")
:strong-em-strings '("**//" . "//**")
;;
:em-strings '("//" . "//")
:em-patterns '(("\\(\\W\\|^\\)//\\([^/]\\|[^/]/\\)*//" . 0) ; emphasized
("\\(\\W\\|^\\)\\*\\*\\
([^*]\\|[^*]\\*\\)*\\*\\*" . 0) ; strong
("\\(\\W\\|^\\)\\*\\*//\\
([^\]\\|[^\]\\\)*//\\*\\*" . 0)) ; strong emph
;;
:keywords '(
("\\(\\W\\|^\\)''\\([^_\n]+?\\)''" 2 'simple-
wiki-teletype-face append)
("\\(\\W\\|^\\)FIXME:" . font-lock-warning-
face) ;; TODO: Bessere face definieren
;; __unterstrichen__
("\\(\\W\\|^\\)__\\([^_\n]+?\\)__" 2 'simple-
wiki-underline-face)
;; [[link|mit beschreibung]]
("\\[\\[\\([^\n]+?\\)\\(\\]\\]\\|\|\\([^\n]
+?\\)\\]\\]\\)"
(1 'font-lock-function-name-face)
(3 'font-lock-doc-face))
;;
;; tags wie <i> etc. (unn�tig, �bernommen aus
dem alten mode)
(simple-wiki-match-tag-i 0 'simple-wiki-
italic-face append)
(simple-wiki-match-tag-b 0 'simple-wiki-bold-
face append)
(simple-wiki-match-tag-u 0 'simple-wiki-
underline-face append)
(simple-wiki-match-tag-tt 0 'simple-wiki-
teletype-face append)
(simple-wiki-match-tag-em 0 'simple-wiki-emph-
face append)
(simple-wiki-match-tag-strong 0 'simple-wiki-
strong-face append)
("\\(</?\\)\\([A-Za-z]+\\)\\(\\([ ]+[a-zA-Z]
+\\)=\\(\".*\"\\)\\)*\\(/?>\\)?"
(1 'default t t)
(2 'font-lock-function-name-face t t)
(4 'font-lock-variable-name-face t t)
(5 'font-lock-string-face t t)
(6 'default t t))
;; hervorhebung des bereiches zwischen tags
;; (simple-wiki-match-tag-nowiki 0
'simple-wiki-nowiki-face t)
;; (simple-wiki-match-tag-pre 0 'simple-
wiki-code-face t)
;; (simple-wiki-match-tag-code 0
'simple-wiki-code-face t)
;; (simple-wiki-match-code-block 0
'simple-wiki-code-face t)
)
:indent 'none
;;
:outline 'none
;;
:horiz '("----" . 0)
;;
)
(defun simple-dokuwiki-init-mode ()
(interactive)
(make-local-variable 'dokuwiki-pagename)
(set (make-local-variable 'dokuwiki-major-change) t)
(set (make-local-variable 'global-mode-string) '(:eval
(progn
(rename-
buffer dokuwiki-pagename)
(if
dokuwiki-major-change "*Major Change*" "*Minor Change*")
)))
;;
;; (auto-fill-mode 1)
(longlines-mode 1)
;;
;;Keymap, sollte in die Definition des Major Mode, aber das l�sst
;; das Makro simple-wiki-define-major-mode nicht zu:
;;
(define-key simple-dokuwiki-mode-map [(control c)(control c)] 'dokuwiki-save-
page)
(define-key simple-dokuwiki-mode-map [(control c)(control h)] 'simple-dokuwiki-
insert-or-region-headline)
(define-key simple-dokuwiki-mode-map [(control c)(control i)] 'simple-dokuwiki-
insert-internal-link)
(define-key simple-dokuwiki-mode-map [(control c)(control m)] 'simple-dokuwiki-
insert-or-region-media-string)
(define-key simple-dokuwiki-mode-map [(control c)(m)] 'simple-dokuwiki-
toggle-major-change)
(define-key simple-dokuwiki-mode-map [(control c)(control u)] 'dokuwiki-upload-
file)
)
;; Diverses:
;; (dokuwiki-get-page "testseite")
;; (call-interactively 'dokuwiki-get-page)
(defun simple-dokuwiki-toggle-major-change ()
"Toggles whether current edit is a major change."
(interactive)
(set 'dokuwiki-major-change (not dokuwiki-major-change))
(redraw-modeline))
;; Headline:
;;
(defun dokuwiki-create-headline-string (level)
"Erstellt einen String mit 7-LEVEL Gleichheitszeichen."
(when (and (numberp level) (not (= level 0)) (< level 7))
(make-string (- 7 level) ?=)))
;; Links einf�gen:
(defun simple-dokuwiki-extract-region-as-string ()
(let ((s (buffer-substring-no-properties (region-beginning) (region-end))))
(delete-region (region-beginning) (region-end))
s))
;; (call-interactively 'simple-dokuwiki-insert-internal-link)
;; Medien verlinken:
(defun simple-dokuwiki-insert-or-region-media-string ()
"Insert media-link, if in region, use current mark as description."
(interactive)
(if (simple-wiki-active-mark)
(let ((begin (min (point) (mark))) (end (max (point) (mark))))
(simple-dokuwiki-media-string-region begin end))
(simple-dokuwiki-insert-media-string)))
;; ============================================================
;; Hilfsfunktionen:
;;
(defun dokuwiki-base-url ()
"Return the URL to the dokuwiki."
(format "http://%s/doku.php" dokuwiki-base-url))
(defun dokuwiki-mediamanager-url ()
"Return the URL to the mediamanager.php of the dokuwiki."
(format "http://%s/lib/exe/mediamanager.php" dokuwiki-base-url))
(char-to-string
(make-char 'eight-bit
(defun x=y (a b)
"Format A and B as to be form parameters for CURL:
\"--form-string A=B\"."
(format "--form-string \"%s=%s\"" a b))
(defun cookieoption ()
"Return CURL-Option for using a file as a cookie jar." ;; mein Englisch. Seufz.
(format "--cookie-jar %s" dokuwiki-cookie-jar))
(defun dokuwiki-propose-blog-entry ()
"Return (relatively) unique name for a new blog entry."
(format-time-string "%d-%H-%m-%y"))
(dokuwiki-propose-blog-entry))))
(setq dokuwiki-newpage-entered-p t)
(dokuwiki-get-page pagename "blog") ;; TODO: Error checking
;; TODO: Wie kriege ich das mit dem Skeleton hin, da hier doch ein
;; Argument �bergeben wird?
(simple-dokuwiki-insert-headline 1)
(save-excursion
(goto-char (point-max))
(insert "\n\n~~DISCUSSION~~\n")))
;; ============================================================
;; Hauptfunktionalit�t:
;;
;; HTTP-Requests �ber CURL:
;; (dokuwiki-call-curl "http://localhost")
;; LOGIN/LOGOUT:
p
r))))
;;
(if (not (setq success (bufferp result)))
(message "Cann't login.")
(kill-buffer result))
;;
success))
;; DEPRECATED
(defun dokuwiki-logout ()
(interactive)
(let* ((url (format "%s?do=logout" (dokuwiki-base-url)))
;;
(result
(with-temp-message "Logout..."
(dokuwiki-call-curl url))))
(when (bufferp result) (kill-buffer result))))
;; LADEN:
(dokuwiki-base-url)
dokuwiki-do-command))
(result (dokuwiki-call-curl url)))
;;
(cond
;; Bei Erfolg zum Buffer wechseln:
;;
((bufferp result)
(dokuwiki-visit-as-dokuwiki-buffer result pagename
namespace)
)
;; Fehler
;;
(t (message "Error %d." result))))))
;; (dokuwiki-get-page "testpage")
;; (call-interactively 'dokuwiki-get-page)
;; INDEX-SEITE HOLEN:
;; (dokuwiki-get-index "philo")
;; SPEICHERN:
"(minor change)"))
(tempfile (dokuwiki-write-region-to-temp-file
point mark))
(pagestring (dokuwiki-get-page-id pagename
namespace))
;;
(o-user (x=y "u" dokuwiki-username))
(o-pwd (x=y "p" dokuwiki-password))
(o-r (x=y "r" "1"))
;;
(o-id (x=y "id" pagestring))
;; (o-rev (x=y "rev" ""))
(o-summary (x=y "summary" summary-string))
(o-minor (x=y "minor" (not dokuwiki-major-
change)))
;;
(o-wikitext (format "-F \"wikitext=<%s\"" tempfile))
;;
(result
(with-temp-message (format "Saving to page %s..."
pagestring)
(dokuwiki-call-curl url
o-id
o-summary
o-minor
o-user
o-pwd
o-r
o-wikitext))))
(delete-file tempfile)
(cond
((bufferp result)
(progn
(message "Page %s was saved." (dokuwiki-get-page-id
pagename namespace))
(kill-buffer result)
))
(t (message "Error %d." result)))))
(defun dokuwiki-save-page ()
"Save current buffer to the DokuWiki."
(interactive)
(let ((buffer (current-buffer)))
(if (not (eq major-mode 'simple-dokuwiki-mode))
(message "Must be in DokuWiki-Mode.")
(dokuwiki-save-current-buffer dokuwiki-pagename))))
;; (dokuwiki-get-page "testseite")
;; UPLOAD:
("�" "ae")
("�" "oe")
("�" "ue")
("�" "Ae")
("�" "Oe")
("�" "Ue")))
(substitution-function (lambda (item)
(setq file
(replace-regexp-in-string
(car item)
(cadr item)
file)))))
(mapc substitution-function substitution-list)
file))
;
(o-upload (format "-F upload=@'%s'" (expand-file-
name file)))
;;
(o-id (x=y "id" id-filename))
(o-ow (x=y "ow" "1")) ;; do overwrite if
necessary
(o-ns (x=y "ns" (format "'%s'" namespace)))
(o-user (x=y "u" dokuwiki-username))
(o-pwd (x=y "p" dokuwiki-password))
(r (x=y "r" 1))
;;
(result
(with-temp-message (format "Save file '%s' into
namespace '%s'" file namespace)
(dokuwiki-call-curl url
o-user
o-pwd
o-upload
o-ow
o-id
o-ns))))
;; R�ckmeldungen parsen und anzeigen (TODO: auslagern)
(when (bufferp result)
(switch-to-buffer result)
(goto-char (point-min))
(cond
((re-search-forward "class=\"error\">\\([^<]+\\)<" nil t)
(let ((error-description (match-string-no-properties
1)))
(when error-description
(kill-buffer result)
(message "Error during upload. DokuWiki
returns '%s'" error-description))))
((re-search-forward "class=\"success\">\\([^<]+\\)<" nil
t)
(let ((success-description (match-string-no-
properties 1)))
(when success-description
(kill-buffer result)
(message "File was uploaded: DokuWiki
returns '%s'" success-description)))
;;
)))
;;
)))
;; (call-interactively 'dokuwiki-upload-file)
;; (dokuwiki-get-media-and-namespaces)
;; INDEX-INFORMATIONEN HOLEN:
;; (dokuwiki-collect-index-information "playground:")
Fordert auf zur Eingabe einer DokuWiki-Seite. Man kann aus den
vorhandenen Seiten ausw�hlen (via completion), wobei die
Eintr�ge, die mit einem : enden (z.B. \"wiki:\"), f�r ein
Namespace stehen. Wird ein solcher Namespace ausgew�hlt, wird die
Suche innerhalb dieses Namenraums fortgesetzt. Auswahl einer
vorhandenen Seite oder die Eingabe eines neuen Seitennamens
beendet diese Funktion.
;; (dokuwiki-get-page (dokuwiki-enter-pagename))
(defun dokuwiki-enter-namespace (&optional namespace)
"Fordert zur Eingabe eines NAMESPACE voraus. Kennt keine
rekursiven Namensr�ume, es wird also nur zur Eingabe eines einzigen m�glichen
Namensraums aufgefordert."
(let* ((nslist (dokuwiki-collect-index-information namespace ":$")))
(completing-read "Namespace: " nslist)))
;; (dokuwiki-enter-namespace)
ns
u p)))
result))
;; (dokuwiki-get-media "playground:")
;; (dokuwiki-collect-media-information "playground:")
ns-and-media-list))))
;;
(t namespace-or-media)))
;; (dokuwiki-get-media-and-namespaces)
;; (dokuwiki-get-media-string)
(provide 'dokuwiki)