Дополнительный режим для блога писать в HTML


Это набор достаточно полезных функций, которые я собрал для записи своего блога.

(require 'htmlize)

(defvar blog-mode-map nil
  "Keymap for blog minor mode")

(unless blog-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map "\C-cl" 'insert-link)
    (define-key map "\C-cp" 'insert-code-block)
    (define-key map "\C-cc" 'insert-inline-code)
    (define-key map "\C-cb" 'insert-bold)
    (define-key map "\C-cq" 'insert-quote)
    (define-key map "\C-cs" 'insert-sig)
    (define-key map "\C-cf" 'insert-footnote)

    (define-key map "\C-c\C-l" 'region-to-link)
    (define-key map "\C-c\C-p" 'region-to-code-block)
    (define-key map "\C-c\C-c" 'region-to-inline-code)
    (define-key map "\C-c\C-b" 'region-to-bold)
    (define-key map "\C-c\C-q" 'region-to-quote)
    (define-key map "\C-c\C-s" 'region-to-sig)
    (define-key map "\C-c\C-f" 'region-to-footnote)

    (define-key map "/" 'smart-backslash)
    (setq blog-mode-map map)))

(define-minor-mode blog-mode
  "This is a collection of useful keyboard macros for editing Langnostic"
  nil
  " Blog"
  (use-local-map blog-mode-map))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; simple definitions
(defun insert-tag (start-tag &optional end-tag)
  "Inserts a tag at point"
  (interactive)
  (insert start-tag)
  (save-excursion
    (insert (or end-tag ""))))

(defun wrap-region (start end start-tag &optional end-tag)
  "Inserts end tag at the end of the region, and start tag at point"
  (goto-char end)
  (insert (or end-tag ""))
  (goto-char start)
  (insert start-tag))

(defmacro definsert (tag-name start-tag end-tag)
  "Defines insert function."
  `(defun ,(make-symbol (concat "insert-" (symbol-name tag-name))) ()
     (interactive)
     (insert-tag ,start-tag ,end-tag)))

(defmacro defregion (tag-name start-tag end-tag)
  "Defines region wrapper function."
  `(defun ,(make-symbol (concat "region-to-" (symbol-name tag-name))) ()
     (interactive)
     (wrap-region (region-beginning) (region-end) ,start-tag ,end-tag)))

(definsert link (concat "<a href=\"" (x-get-clipboard) "\">") "</a>")
(defregion link (concat "<a href=\"" (x-get-clipboard) "\">") "</a>")
(definsert bold "<b>" "</b>")
(defregion bold "<b>" "</b>")
(definsert quote "<blockquote>" "</blockquote>")
(defregion quote "<blockquote>" "</blockquote>")
(definsert sig "<span class=\"sig\">" "</span>")
(defregion sig "<span class=\"sig\">" "</span>")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; <pre> and <code> definitions
(definsert code-block "<pre>" "</pre>")
(definsert inline-code "<code>" "")

;; версии регионе являются более сложными для размещения htmlize
(сайт defun области-в inline-код ()
 "HTMLize просто текущей области и оберните его в  block"
  (interactive)
  (let((htmlified (substring (htmlize-region-for-paste (region-beginning) (region-end)) 6 -6)))
    (delete-region (region-beginning) (region-end))
    (insert-inline-code)
    (insert htmlified)))

(defun region-to-code-block ()
  "HTMLize the current region and wrap it in a <pre> block"
  (interactive)
  (let ((htmlified (htmlize-region-for-paste (region-beginning) (region-end))))
    (delete-region (region-beginning) (region-end))
    (insert (concat "<pre>" (substring htmlified 6)))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; footnote definitions
(defun insert-footnote ()
  "Inserts footnote, and a return link at the bottom of the file. 
   Moves point to footnote location."
  (interactive)
  (progn (footnotes-header)
     (let ((footnote-name (format-time-string "%a-%b-%d-%H%M%S%Z-%Y" (current-time))))
       (insert "<a href=\"#foot-" footnote-name "\" name=\"note-" footnote-name "\">[note]</a>")
       (goto-char (point-max))
       (insert "\n\n<a href=\"#note-" footnote-name "\" name=\"foot-" footnote-name "\">[back]</a> - "))))

(defun region-to-footnote ()
  "Inserts a footnote at point and return link at the bottom. Moves the current region to the end of the file. 
   Leaves point where it is."
      (interactive)
  (save-excursion (kill-region (region-beginning) (region-end))
          (insert-footnote)
          (yank)))

(defun footnotes-header ()
  "Inserts footnote header if not already present"
  (unless (save-excursion (search-forward "<hr />\n<h5>Footnotes</h5>" nil t))
    (save-excursion 
      (goto-char (point-max))
      (insert "\n\n<hr />\n<h5>Footnotes</h5>"))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; utility
(defun smart-backslash ()
  "Backslash closes previous tag when used in the combination </. Self-inserts otherwise."
  (interactive)
  (if (equal (save-excursion (backward-char) (thing-at-point 'char)) "<")
      (progn (backward-delete-char 1)
         (sgml-close-tag))
    (insert "/")))

(provide 'blog-mode)

Я хотел бы некоторые советы о том, как удалить дублирования в несколько неожиданных местах. На мой взгляд, я должен быть в состоянии сделать что-то вроде (deftag смелый "Б" "" "") , который будет расширяться в definsert, defregion и определить ключ. Я не уверен, как макрос определяет несколько функций в Elisp, хотя; progn (в кавычках или нет) не похоже, чтобы помочь.

Не стесняйтесь указывать на какие-либо компоненты, я мог бы заменить встроенные функции Emacs23, или что я могу сделать более элегантно.

Редактирования: обновление версии этот код может быть найден здесь.



467
10
задан 26 марта 2011 в 05:03 Источник Поделиться
Комментарии
1 ответ

Не уверен, если это имеет значение, так как это летний, но можно посмотреть https://github.com/Neil-Smithline/defassoclist чтобы узнать, как создавать множественные функции в макросе.

Вы не указали неудачных попыток с progn , поэтому я не могу сказать вам, что вы делали неправильно, но progn работает.

3
ответ дан 11 мая 2012 в 03:05 Источник Поделиться