first commit
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
;;; my-org-pukiwiki.el --- Simple Org to PukiWiki exporter -*- lexical-binding: t; -*-
|
||||
|
||||
(require 'subr-x)
|
||||
|
||||
(defgroup my-org-pukiwiki nil
|
||||
"Simple Org to PukiWiki exporter."
|
||||
:group 'tools)
|
||||
|
||||
(defcustom my-org-pukiwiki-coding-system 'japanese-shift-jis
|
||||
"Output coding system."
|
||||
:type 'coding-system
|
||||
:group 'my-org-pukiwiki)
|
||||
|
||||
(defun my-org-pukiwiki--metadata-p (line)
|
||||
(string-match-p
|
||||
"^#\\+\\(TITLE\\|AUTHOR\\|OPTIONS\\|DATE\\|EMAIL\\|LANGUAGE\\|KEYWORDS\\):"
|
||||
line))
|
||||
|
||||
(defun my-org-pukiwiki--heading (line)
|
||||
(if (string-match "^\\(\\*+\\)[ \t]+\\(.*\\)$" line)
|
||||
(let* ((level (length (match-string 1 line)))
|
||||
(title (match-string 2 line)))
|
||||
(cond
|
||||
((= level 1) (concat "* " title))
|
||||
((= level 2) (concat "** " title))
|
||||
((= level 3) (concat "*** " title))
|
||||
(t (concat "'''" title "'''"))))
|
||||
line))
|
||||
|
||||
(defun my-org-pukiwiki--list (line)
|
||||
(cond
|
||||
((string-match "^[ \t]*-[ \t]+\\(.*\\)$" line)
|
||||
(concat "-" (match-string 1 line)))
|
||||
((string-match "^[ \t]*[0-9]+\\.[ \t]+\\(.*\\)$" line)
|
||||
(concat "+" (match-string 1 line)))
|
||||
(t line)))
|
||||
|
||||
(defun my-org-pukiwiki--table-separator-p (line)
|
||||
(string-match-p "^[ \t]*|[-+| \t]+|[ \t]*$" line))
|
||||
|
||||
(defun my-org-pukiwiki--table (line)
|
||||
(cond
|
||||
((my-org-pukiwiki--table-separator-p line)
|
||||
nil)
|
||||
((string-match-p "^[ \t]*|" line)
|
||||
(let ((s (string-trim line)))
|
||||
(setq s (replace-regexp-in-string "=" "" s))
|
||||
(if (string-match-p "|[ \t]*キー[ \t]*|\\|[ \t]*関数[ \t]*|\\|[ \t]*機能[ \t]*|" s)
|
||||
(concat s "h")
|
||||
s)))
|
||||
(t line)))
|
||||
|
||||
(defun my-org-pukiwiki--inline (line)
|
||||
(setq line
|
||||
(replace-regexp-in-string
|
||||
"=\\([^=\n]+\\)="
|
||||
"''\\1''"
|
||||
line))
|
||||
(setq line
|
||||
(replace-regexp-in-string
|
||||
"~\\([^~\n]+\\)~"
|
||||
"''\\1''"
|
||||
line))
|
||||
line)
|
||||
|
||||
(defun my-org-pukiwiki--link (line)
|
||||
;; [[file:foo.png]]
|
||||
(setq line
|
||||
(replace-regexp-in-string
|
||||
"\\[\\[file:\\([^]]+\\)\\]\\]"
|
||||
"#ref(\\1)"
|
||||
line))
|
||||
;; [[https://example.org][label]]
|
||||
(setq line
|
||||
(replace-regexp-in-string
|
||||
"\\[\\[\\([^]]+\\)\\]\\[\\([^]]+\\)\\]\\]"
|
||||
"[[\\2>\\1]]"
|
||||
line))
|
||||
;; [[https://example.org]]
|
||||
(setq line
|
||||
(replace-regexp-in-string
|
||||
"\\[\\[\\(https?://[^]]+\\)\\]\\]"
|
||||
"[[\\1]]"
|
||||
line))
|
||||
line)
|
||||
|
||||
(defun my-org-pukiwiki--sjis-safe (text)
|
||||
(let ((s text))
|
||||
(setq s (replace-regexp-in-string "–\\|—\\|―" "--" s))
|
||||
(setq s (replace-regexp-in-string "“\\|”" "\"" s))
|
||||
(setq s (replace-regexp-in-string "‘\\|’" "'" s))
|
||||
(setq s (replace-regexp-in-string "…" "..." s))
|
||||
(setq s (replace-regexp-in-string "⏳" "Busy" s))
|
||||
(setq s (replace-regexp-in-string "→" "->" s))
|
||||
(setq s (replace-regexp-in-string "←" "<-" s))
|
||||
(setq s (replace-regexp-in-string "⇒" "=>" s))
|
||||
(setq s (replace-regexp-in-string "├──" "+-" s))
|
||||
(setq s (replace-regexp-in-string "└──" "+-" s))
|
||||
(setq s (replace-regexp-in-string "│" "|" s))
|
||||
s))
|
||||
|
||||
(defun my-org-pukiwiki-convert-string (text)
|
||||
"Convert Org TEXT to PukiWiki text."
|
||||
(let ((lines (split-string text "\n"))
|
||||
(out nil)
|
||||
(in-block nil))
|
||||
(dolist (line lines)
|
||||
(cond
|
||||
;; src/example block start
|
||||
((string-match-p "^#\\+begin_\\(src\\|example\\)" line)
|
||||
(setq in-block t))
|
||||
|
||||
;; src/example block end
|
||||
((string-match-p "^#\\+end_\\(src\\|example\\)" line)
|
||||
(setq in-block nil))
|
||||
|
||||
;; preformatted block: leading half-width space
|
||||
(in-block
|
||||
(push (concat " " line) out))
|
||||
|
||||
;; skip Org metadata
|
||||
((my-org-pukiwiki--metadata-p line)
|
||||
nil)
|
||||
|
||||
;; skip caption/name lines
|
||||
((string-match-p "^#\\+\\(CAPTION\\|NAME\\):" line)
|
||||
nil)
|
||||
|
||||
;; normal line
|
||||
(t
|
||||
(setq line (my-org-pukiwiki--heading line))
|
||||
(setq line (my-org-pukiwiki--list line))
|
||||
(setq line (my-org-pukiwiki--table line))
|
||||
(when line
|
||||
(setq line (my-org-pukiwiki--inline line))
|
||||
(setq line (my-org-pukiwiki--link line))
|
||||
(push line out)))))
|
||||
(my-org-pukiwiki--sjis-safe
|
||||
(string-join (nreverse out) "\n"))))
|
||||
|
||||
(defun my-org-pukiwiki-export-buffer ()
|
||||
"Convert current Org buffer and show result in *PukiWiki*."
|
||||
(interactive)
|
||||
(let ((text (my-org-pukiwiki-convert-string (buffer-string))))
|
||||
(with-current-buffer (get-buffer-create "*PukiWiki*")
|
||||
(erase-buffer)
|
||||
(insert text)
|
||||
(goto-char (point-min))
|
||||
(pop-to-buffer (current-buffer)))))
|
||||
|
||||
(defun my-org-pukiwiki-export-file (&optional file)
|
||||
"Export current Org buffer to a Shift-JIS PukiWiki file."
|
||||
(interactive)
|
||||
(let* ((src (buffer-file-name))
|
||||
(dst (or file
|
||||
(if src
|
||||
(concat (file-name-sans-extension src) ".pukiwiki")
|
||||
"output.pukiwiki")))
|
||||
(text (my-org-pukiwiki-convert-string (buffer-string)))
|
||||
(coding-system-for-write my-org-pukiwiki-coding-system))
|
||||
(with-temp-file dst
|
||||
(insert text))
|
||||
(message "Exported PukiWiki: %s" dst)))
|
||||
|
||||
(defun my-org-pukiwiki-copy-to-clipboard ()
|
||||
"Convert current Org buffer to PukiWiki text and copy it to kill-ring."
|
||||
(interactive)
|
||||
(let ((text (my-org-pukiwiki-convert-string (buffer-string))))
|
||||
(kill-new text)
|
||||
(message "Copied PukiWiki text to clipboard")))
|
||||
|
||||
(provide 'my-org-pukiwiki)
|
||||
|
||||
;;; my-org-pukiwiki.el ends here
|
||||
Reference in New Issue
Block a user