-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathorg-export-html.el
203 lines (176 loc) · 7.1 KB
/
org-export-html.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
(setq lexical-binding t)
(require 'cli (concat (file-name-directory load-file-name) "org-export-cli.el"))
(cli-eval-file cli-config-file)
(cli-package-setup cli-package-dir cli-packages)
(require 'request)
(require 'ox)
(require 'ox-html)
(defvar oe-html-css-styles
'((:name "bootstrap5"
:url "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
:integrity "sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
:reference "https://getbootstrap.com/docs/5.1/getting-started/introduction/"
:pre-export (lambda ()
(setq org-html-htmlize-output-type 'css))
:post-export (lambda () (oe-html-fix-bootstrap)))
(:name "orgcss"
:url "https://gongzhitaao.org/orgcss/org.css"
:reference "https://github.com/gongzhitaao/orgcss"
:pre-export (lambda ()
(setq org-html-htmlize-output-type 'css)
(setq org-html-head-include-default-style nil)))
(:name "org-manual"
:url "https://www.gnu.org/software/emacs/manual.css"
:reference "https://orgmode.org"
:pre-export (lambda ()
(setq org-html-htmlize-output-type 'css)
(setq org-html-head-include-default-style nil)))
))
(defvar oe-html-css-style-names
(mapconcat (lambda (plist) (format "'%s'" (plist-get plist ':name))) oe-html-css-styles ", "))
(defvar oe-html-pre-export nil)
(defvar oe-html-post-export nil)
(defun oe-html-fix-bootstrap ()
"Make adjustments to html in current buffer for bootstrap"
(cli-replace-all "<body>" "<body class=\"container\">")
(cli-replace-all
"<table>"
"<table class=\"table table-bordered table-sm\" style=\"width: auto;\">")
)
(defun oe-html-css-link (url &optional integrity)
"Return a <link> tag specifying a css style"
(if integrity
(format
"<link rel=\"stylesheet\" type=\"text/css\" href=\"%s\"
integrity=\"%s\" crossorigin=\"anonymous\" />"
url integrity)
(format
"<link rel=\"stylesheet\" type=\"text/css\" href=\"%s\" />"
url)))
(defun oe-html-css-content (url)
"Return a <style> tag with embedded css"
(message (format "Inserting contents of %s" url))
(format "<style type=\"text/css\">\n%s\n</style>\n"
(if (string-match "^http" url)
(request-response-data
(request url :parser 'buffer-string :sync t))
(with-temp-buffer
(insert-file-contents url)
(buffer-string)))))
(defun oe-get-plist-by-name (name list-of-plists)
(car (remq nil (mapcar
(lambda(plist)
(if (string-equal name (plist-get plist ':name))
plist))
list-of-plists))))
;; (byte-compile-file (concat (file-name-directory load-file-name) "cli.el"))
(setq options-alist
`(("--infile" "Path to input .org file (required)")
("--outfile"
"Path to output .html file (use base name of infile by default)"
nil)
("--add-langs"
"Comma-delimited list of additional languages
to enable in code blocks"
nil)
("--evaluate" "Evaluate source code blocks" nil)
("--css-name"
,(format "Use the named css style; choose from %s" oe-html-css-style-names)
nil)
("--css" "Path or URL of css stylesheet" nil)
("--css-integrity"
"Optional value for css link integrity attribute" nil)
("--embed-css" "Include contents of css in a <style> block" nil)
("--config"
"An elisp expression defining additional configuration" nil)
("--config-file"
"A file path providing additional configuration" nil)
))
(setq docstring "
Note that code block evaluation is disabled by default; use
'--evaluate' to set a default value of ':eval yes' for all code
blocks. If you would like to evaluate by default without requiring
this option, include '#+PROPERTY: header-args :eval yes' in the file
header. Individual blocks can be selectively evaluated using ':eval
yes' in the block header.")
(condition-case err
(setq args (cli-parse-args options-alist docstring))
(quit (kill-emacs 0))
(error (progn (message (nth 1 err)) (kill-emacs 1))))
(defun getopt (name) (gethash name args))
;; css configuration
(cond
((getopt "css")
(setq css-config
`(:name "custom" :url ,(getopt "css") :integrity ,(getopt "css-integrity"))))
((getopt "css-name")
(setq css-config
(oe-get-plist-by-name (getopt "css-name") oe-html-css-styles))
(unless css-config
(message "'--css-name %s' is not a valid selection, choose from %s"
(getopt "css-name") oe-html-css-style-names)
(kill-emacs 1))
(setq oe-html-pre-export (plist-get css-config ':pre-export))
(setq oe-html-post-export (plist-get css-config ':post-export)))
(t
(setq css-config nil)))
(defvar oe-html-head
(if css-config
(let ((url (plist-get css-config ':url))
(integrity (plist-get css-config ':integrity)))
(if (getopt "embed-css")
(oe-html-css-content url)
(oe-html-css-link url integrity)))))
;; apparently this needs to be explicitly global to be easily defined in
;; org-mode-hook
(defvar oe-output-dir nil)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;; compile and export ;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; evaluate extra configuration if provided
(cli-eval-file cli-config-file)
(cli-eval-expr (getopt "config"))
(cli-eval-file (getopt "config-file"))
;; export using a temporary buffer to avoid modifying input file; working
;; directory contains the input file.
(let* ((infile (expand-file-name (getopt "infile")))
(outfile (cli-get-output-file (getopt "outfile") infile ".html")))
(setq oe-output-dir (file-name-directory outfile))
(add-hook 'org-mode-hook
(lambda ()
(setq org-confirm-babel-evaluate nil)
(setq org-export-allow-BIND 1)
(setq org-html-doctype "html5")
(setq org-html-head oe-html-head)
(setq org-babel-sh-command "bash")
(setq org-babel-python-command "python3")
(setq org-babel-default-header-args
(list `(:session . "none")
`(:eval . ,(if (getopt "evaluate") "yes" "no"))
`(:results . "output replace")
`(:exports . "both")
`(:cache . "no")
`(:noweb . "no")
`(:hlines . "no")
`(:tangle . "no")
`(:padnewline . "yes")
`(:output-dir . ,oe-output-dir)))
(setq org-babel-default-header-args:sh
(list `(:prologue . ,cli-sh-src-prologue)))
(cli-org-babel-load-languages (getopt "add-langs"))))
(with-temp-buffer
(insert-file-contents-literally infile)
(cd (file-name-directory infile))
(org-mode)
;; Required for syntax hightlighting
(outline-show-all)
(htmlize-buffer)
(font-lock-flush)
(font-lock-fontify-buffer)
(if oe-html-pre-export
(funcall oe-html-pre-export))
(org-html-export-as-html)
(if oe-html-post-export
(funcall oe-html-post-export))
(write-file outfile)
(message "wrote %s" outfile)))