-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmake_html_mobi.vim
More file actions
224 lines (189 loc) · 7 KB
/
make_html_mobi.vim
File metadata and controls
224 lines (189 loc) · 7 KB
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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
" Usage: Install Pandoc 2+ and Calibre. Specify paths to their executables.
" Open this file in a new instance of Vim and source it with
" :so %
" In case of any Vim problems, try starting Vim without .vimrc:
" gvim -u NONE make_html_mobi.vim
" The log will be saved in "make_html_mobi.log".
" Pandoc executable:
let s:PANDOC_EXE = 'C:/Programs/Pandoc/pandoc.exe'
" Calibre ebook-convert executable:
let s:CALIBRE_EXE = 'C:/Programs/CalibrePortable/Calibre/ebook-convert.exe'
" Debian Linux 9 (Stretch): `sudo apt-get install pandoc calibre`
" installs Pandoc 1.17.2 and Calibre 2.75.1. The script works, but
" PANDOC_CMD need to be edited: remove options `-smart` and `--eol=lf`.
"let s:PANDOC_EXE = 'pandoc'
"let s:CALIBRE_EXE = 'ebook-convert'
" Set to 1 to join sentences within paragraphs.
let s:JOIN_SENTENCES = 0
"let s:JOIN_SENTENCES = 1
" Generate .mobi files (takes a long time) or not.
let s:GENERATE_MOBI = 1
"let s:GENERATE_MOBI = 0
" debug
let s:DELETE_TEMP_FILES = 1
"let s:DELETE_TEMP_FILES = 0
" List of sub-directories with .md files to convert. If empty, convert all .md files in
" all subdirs. Each subdir must have html/ and mobi/ subdirs.
let s:DIRLIST = []
"let s:DIRLIST = ['en', 'ru']
"let s:DIRLIST = ['choice_extracts']
"---------------------------------------------------------------------
"---------------------------------------------------------------------
let s:cpo_ = &cpo
set cpo&vim
let s:scriptdir = fnamemodify(expand("<sfile>:p:h"), ":p")
if s:DIRLIST == []
exe 'cd ' . s:scriptdir
for f in glob('*',0,1,1)
if isdirectory(f)
call add(s:DIRLIST, f)
endif
endfor
call sort(s:DIRLIST)
endif
let s:log = [' vim:fdm=marker:wrap:', '']
func! MarkdownToHtml_Pre(filedir, filename)
exe 'cd ' . a:filedir
exe 'silent edit ++enc=utf-8 ++ff=unix '. a:filename . '.md'
exe 'silent saveas! ' . a:filename . '.temp'
" add ' ' to line ends that must be preserved
if s:JOIN_SENTENCES
" file header: lines before the first ruler
normal! gg
let lnum_hr = search('^----------', 'n')
if lnum_hr > 0
silent exe '1,' . (lnum_hr-1) . 'g!/^$/s/\s*$/ /'
else
echo 'ERROR: DID NOT FIND ^---------- in:' filename
endif
" protect indented lines, ... lines; other lines always has blanks before or after
silent %s@^.\+\zs\s*\ze\n\( \|\[^[^]]\+\]:\|\.\)@ @e
"silent g@^\( \|\[^[^]]\+\]:\|\.\)@s@\s*$@ @e
endif
" replace leading whitespace with nbsp
silent %s/^ \+/\=substitute(submatch(0), ' ', '\ ', 'g')/e
" convert footnotes into links
" target in FOOTNOTES (do first)
silent %s@^\[^[^]]\+\]:\( \[^[^]]\+\]:\)*@\=substitute(submatch(0), '\[^\([^]]\+\)\]:', '<a id="fn_\1" href="#fr_\1">[\1]:</a>', 'g')@e
" reference in text
silent %s@\[^\([^]]\+\)\]@<a id="fr_\1" href="#fn_\1">[\1]</a>@ge
silent write
silent bd
endfunc
func! MarkdownToHtml(filedir, filename)
exe 'cd ' . a:filedir
if a:filename =~ 'Epistulae_Morales' && a:filename !~ 'intro_etc'
let tocdepth = 1
else
let tocdepth = 6
endif
if s:JOIN_SENTENCES
let hard_line_breaks = ''
else
let hard_line_breaks = '+hard_line_breaks'
endif
" no title, no author: pandoc will use filename without extension as title
let PANDOC_CMD = s:PANDOC_EXE . ' -f markdown-smart-footnotes-startnum-fancy_lists-example_lists'.hard_line_breaks. ' -t html4 --toc --toc-depth='.tocdepth.' --eol=lf -H ../pandoc.css -s -o ' . 'html/'.a:filename.'.html ' . a:filename.'.temp'
call add(s:log, PANDOC_CMD)
call extend(s:log, systemlist(PANDOC_CMD))
call add(s:log, '')
if v:shell_error
echo 'PANDOC_CMD failed for: ' . a:filename
endif
endfunc
func! MarkdownToHtml_Post(filedir, filename)
exe 'cd ' . a:filedir
exe 'silent edit ++enc=utf-8 ++ff=unix '. 'html/'.a:filename.'.html'
" move TOC to before the first <hr>
normal! gg
let hasTOC = search('<div id="TOC">')
if !hasTOC
return
endif
silent normal! vatd
call search('<hr />')
call append(line('.') - 1, ['','',''])
normal! kk
silent normal! P
" insert another <hr> before TOC
normal! gg
call search('<div id="TOC">')
call append(line('.') - 1, '<hr />')
" delete footnote links from TOC. E.g.:
"<li><a href="#on-despising-death24-1">24. On Despising Death<a id="fr_24-1" href="#fn_24-1">[^24-1]</a></a></li>
"normal! gg
"call search('<div id="TOC">')
"silent normal! vat
"exe "normal \<Esc>"
"silent '<,'>g@^<li><a href="#@s@<a id="fr_.\{-}>\(\[.\{-}\]\)</a>@\1@ge
" convert <ul> with I. II. etc in TOC into one line
" search: <ul>\n\zs<li><a href=.\{-}>I\.\=<\/a><\/li>\_.\{-}\ze<\/ul>
normal! gg
call search('<div id="TOC">')
silent normal! vat
exe "normal \<Esc>"
silent '<,'>s@<ul>\n\zs<li><a href=.\{-}>[A-Z]\.\=</a></li>\_.\{-}\ze</ul>@\=substitute(submatch(0), '</li>\n<li>', ' ', 'g')@ge
" write
silent write
silent bd
endfunc
func! HtmlToMobi(filedir, filename)
exe 'cd ' . a:filedir
let s:CALIBRE_CMD = s:CALIBRE_EXE . ' html/'.a:filename.'.html ' . 'mobi/'.a:filename.'.mobi' . ' --no-inline-toc --authors=Seneca'
call add(s:log, s:CALIBRE_CMD)
call extend(s:log, systemlist(s:CALIBRE_CMD))
call add(s:log, '')
if v:shell_error
echo 'CALIBRE_CMD failed for: ' . a:filename
endif
endfunc
func! ConvertAllFilesInDir(dirpath)
exe 'cd ' . a:dirpath
let filelist = glob('*.md',0,1,1)
call sort(filelist)
let s = 'STARTING CONVERSION of '. len(filelist) . ' files in directory ' . a:dirpath
echo s
call add(s:log, '=== ' . s . ' === {{'.'{1')
for filename in filelist
call add(s:log, '--- ' . filename . ' --- {{'.'{2')
let filename = filename[:-4]
echo 'CONVERTING to .html: ' . filename . '.md'
" save .md as .temp and edit
call MarkdownToHtml_Pre(a:dirpath, filename)
" convert .temp to .html
call MarkdownToHtml(a:dirpath, filename)
" edit .html
call MarkdownToHtml_Post(a:dirpath, filename)
" delete .temp
if s:DELETE_TEMP_FILES
exe 'cd ' . a:dirpath
call delete(filename.'.temp')
endif
if s:GENERATE_MOBI
" convert .html to .mobi
echo 'CONVERTING to .mobi: ' . filename . '.html'
call HtmlToMobi(a:dirpath, filename)
endif
endfor
endfunc
func! ConvertAllFiles()
let eventignore_ = &eventignore
let enc_ = &enc
set enc=utf-8
set eventignore=all
let shm_ = &shm
set shm=atI
let more_ = &more
set nomore
let [vb_ , t_vb_] = [&vb, &t_vb]
set vb t_vb=
for dirname in s:DIRLIST
call ConvertAllFilesInDir(s:scriptdir . dirname)
endfor
exe 'cd ' . s:scriptdir
call writefile(s:log, 'make_html_mobi.log')
let [&vb, &t_vb, &shm, &more, &enc]=[vb_, t_vb_, shm_, more_, enc_]
let &eventignore = eventignore_
endfunc
call ConvertAllFiles()
let &cpo = s:cpo_