@@ -63,26 +63,98 @@ function! s:get_month_name(month)
63
63
return vimwiki#vars#get_global (' diary_months' )[str2nr (a: month )]
64
64
endfunction
65
65
66
+ function ! s: get_first_header (fl)
67
+ " Get the first header in the file within the first s:vimwiki_max_scan_for_caption lines.
68
+ let header_rx = vimwiki#vars#get_syntaxlocal (' rxHeader' )
69
+
70
+ for line in readfile (a: fl , ' ' , s: vimwiki_max_scan_for_caption )
71
+ if line = ~# header_rx
72
+ return vimwiki#u#trim (matchstr (line , header_rx))
73
+ endif
74
+ endfor
75
+ return ' '
76
+ endfunction
77
+
78
+ function ! s: get_all_headers (fl, maxlevel)
79
+ " Get a list of all headers in a file up to a given level.
80
+ " Returns a list whose elements are pairs [level, title]
81
+ let headers_rx = {}
82
+ for i in range (1 , a: maxlevel )
83
+ let headers_rx[i ] = vimwiki#vars#get_syntaxlocal (' rxH' .i .' _Text' )
84
+ endfor
85
+
86
+ let headers = []
87
+ for line in readfile (a: fl , ' ' )
88
+ for [i , header_rx] in items (headers_rx)
89
+ if line = ~# header_rx
90
+ call add (headers, [i , vimwiki#u#trim (matchstr (line , header_rx))])
91
+ break
92
+ endif
93
+ endfor
94
+ endfor
95
+ return headers
96
+ endfunction
97
+
98
+ function ! s: count_headers_level_less_equal (headers, maxlevel)
99
+ " Count headers with level <= maxlevel in a list of [level, title] pairs.
100
+ let l: count = 0
101
+ for [header_level, _] in a: headers
102
+ if header_level <= a: maxlevel
103
+ let l: count += 1
104
+ endif
105
+ endfor
106
+ return l: count
107
+ endfunction
108
+
109
+ function ! s: get_min_header_level (headers)
110
+ " The minimum level of any header in a list of [level, title] pairs.
111
+ if len (a: headers ) == 0
112
+ return 0
113
+ endif
114
+ let minlevel = a: headers [0 ][0 ]
115
+ for [level , _] in a: headers
116
+ let minlevel = min ([minlevel, level ])
117
+ endfor
118
+ return minlevel
119
+ endfunction
120
+
66
121
67
122
function ! s: read_captions (files )
68
123
let result = {}
69
- let rx_header = vimwiki#vars#get_syntaxlocal (' rxHeader' )
124
+ let caption_level = vimwiki#vars#get_wikilocal (' diary_caption_level' )
125
+
70
126
for fl in a: files
71
127
" remove paths and extensions
72
- let fl_key = substitute (fnamemodify (fl, ' :t' ), vimwiki#vars#get_wikilocal (' ext' ).' $' , ' ' , ' ' )
128
+ let fl_captions = {}
129
+
130
+ " Default; no captions from the file.
131
+ let fl_captions[' top' ] = ' '
132
+ let fl_captions[' rest' ] = []
133
+
134
+ if caption_level >= 0 && filereadable (fl)
135
+ if caption_level == 0
136
+ " Take first header of any level as the top caption.
137
+ let fl_captions[' top' ] = s: get_first_header (fl)
138
+ else
139
+ let headers = s: get_all_headers (fl, caption_level)
140
+ if len (headers) > 0
141
+ " If first header is the only one at its level or less, then make it the top caption.
142
+ let [first_level, first_header] = headers[0 ]
143
+ if s: count_headers_level_less_equal (headers, first_level) == 1
144
+ let fl_captions[' top' ] = first_header
145
+ call remove (headers, 0 )
146
+ endif
73
147
74
- if filereadable (fl )
75
- for line in readfile (fl, ' ' , s: vimwiki_max_scan_for_caption )
76
- if line = ~# rx_header && ! has_key (result, fl_key )
77
- let result[fl_key] = vimwiki#u#trim ( matchstr ( line , rx_header))
148
+ let min_header_level = s: get_min_header_level (headers )
149
+ for [ level , header] in headers
150
+ call add (fl_captions[ ' rest ' ], [ level - min_header_level, header] )
151
+ endfor
78
152
endif
79
- endfor
80
- endif
81
-
82
- if ! has_key (result, fl_key)
83
- let result[fl_key] = ' '
153
+ endif
84
154
endif
85
155
156
+ let fl_key = substitute (fnamemodify (fl, ' :t' ), vimwiki#vars#get_wikilocal (' ext' ).' $' , ' ' , ' ' )
157
+ let result[fl_key] = fl_captions
86
158
endfor
87
159
return result
88
160
endfunction
@@ -149,22 +221,36 @@ function! s:format_diary()
149
221
call add (result, substitute (vimwiki#vars#get_syntaxlocal (' rxH3_Template' ),
150
222
\ ' __Header__' , s: get_month_name (month), ' ' ))
151
223
152
- for [fl, cap] in s: sort (items (g_files[year][month]))
224
+ for [fl, captions] in s: sort (items (g_files[year][month]))
225
+ let topcap = captions[' top' ]
153
226
let link_tpl = vimwiki#vars#get_global (' WikiLinkTemplate2' )
154
227
155
228
if vimwiki#vars#get_wikilocal (' syntax' ) == ' markdown'
156
229
let link_tpl = vimwiki#vars#get_syntaxlocal (' Weblink1Template' )
157
230
158
- if empty (cap ) " When using markdown syntax, we should ensure we always have a link description.
159
- let cap = fl
231
+ if empty (topcap ) " When using markdown syntax, we should ensure we always have a link description.
232
+ let topcap = fl
160
233
endif
161
- elseif empty (cap)
162
- let link_tpl = vimwiki#vars#get_global (' WikiLinkTemplate1' )
163
234
endif
164
235
165
- let entry = substitute (link_tpl, ' __LinkUrl__' , fl, ' ' )
166
- let entry = substitute (entry, ' __LinkDescription__' , cap, ' ' )
236
+ if empty (topcap)
237
+ let top_link_tpl = vimwiki#vars#get_global (' WikiLinkTemplate1' )
238
+ else
239
+ let top_link_tpl = link_tpl
240
+ endif
241
+
242
+ let entry = substitute (top_link_tpl, ' __LinkUrl__' , fl, ' ' )
243
+ let entry = substitute (entry, ' __LinkDescription__' , topcap, ' ' )
167
244
call add (result, repeat (' ' , vimwiki#lst#get_list_margin ()).' * ' .entry)
245
+
246
+ for [depth, subcap] in captions[' rest' ]
247
+ if empty (subcap)
248
+ continue
249
+ endif
250
+ let entry = substitute (link_tpl, ' __LinkUrl__' , fl.' #' .subcap, ' ' )
251
+ let entry = substitute (entry, ' __LinkDescription__' , subcap, ' ' )
252
+ call add (result, repeat (' ' , vimwiki#lst#get_list_margin () * (2 + depth)).' - ' .entry)
253
+ endfor
168
254
endfor
169
255
170
256
endfor
@@ -285,7 +371,7 @@ function! vimwiki#diary#generate_diary_section()
285
371
let current_file = vimwiki#path#path_norm (expand (" %:p" ))
286
372
let diary_file = vimwiki#path#path_norm (s: diary_index ())
287
373
if vimwiki#path#is_equal (current_file, diary_file)
288
- let content_rx = ' ^\%(\s*\* \)\|\%(^\s*$\)\|\%(' .vimwiki#vars#get_syntaxlocal (' rxHeader' ).' \)'
374
+ let content_rx = ' ^\%(\s*[*-] \)\|\%(^\s*$\)\|\%(' .vimwiki#vars#get_syntaxlocal (' rxHeader' ).' \)'
289
375
call vimwiki#base#update_listing_in_buffer (s: format_diary (),
290
376
\ vimwiki#vars#get_wikilocal (' diary_header' ), content_rx, line (' $' )+ 1 , 1 , 1 )
291
377
else
@@ -324,4 +410,3 @@ function vimwiki#diary#calendar_sign(day, month, year)
324
410
\ a: year .' -' .month.' -' .day.vimwiki#vars#get_wikilocal (' ext' )
325
411
return filereadable (expand (sfile))
326
412
endfunction
327
-
0 commit comments