首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用HTML编写博客的次要模式

用HTML编写博客的次要模式
EN

Code Review用户
提问于 2011-03-26 05:00:11
回答 1查看 381关注 0票数 10

这是我为写博客而收集的一组相当有用的功能。

代码语言:javascript
复制
(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>" "</code>")

;; region versions are more complicated to accomodate htmlize
(defun region-to-inline-code ()
  "HTMLize just the current region and wrap it in a <code> 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 bold "b" "<b>" "</b>")这样的事情,这将扩展到definsertdefregiondefine-key。但是,我不知道如何在Elisp中定义一个宏定义多个函数;progn (不管引用与否)似乎没有帮助。

可以随意指出我可以用预先构建的Emacs23函数替换的任何组件,或者任何我可以做得更优雅的组件。

编辑:此代码的更新版本可以找到这里

EN

回答 1

Code Review用户

回答已采纳

发布于 2012-05-11 03:22:50

不确定这是否相关,因为它已经有一年的历史了,但是,您可以查看https://github.com/Neil-Smithline/defassoclist,看看如何在宏中创建多个函数。

您没有包括您在progn中失败的尝试,所以我不能告诉您您做错了什么,但是progn确实有效。

票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/1467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档