9
9
10
10
module Jekyll
11
11
module Obsidian
12
- def self . collect_files ( rootdir , path = "" , counts = { dirs : 0 , files : 0 , size : 0 } )
13
- root_files_ = [ ]
14
- Dir . entries ( rootdir ) . each do |entry |
15
- next if entry . start_with? ( "." , "_" )
16
- entry_path = File . join ( rootdir , entry )
17
- root_files_ << if File . directory? ( entry_path )
18
- next if entry . start_with? ( ".obsidian" )
19
- counts [ :dirs ] += 1
20
- { name : entry , type : "dir" , path : File . join ( path , entry ) ,
21
- children : collect_files ( entry_path , File . join ( path , entry ) , counts ) }
22
- else
23
- next if File . zero? ( entry_path ) || File . empty? ( entry_path )
24
-
25
- file_name = entry
26
- file_name += "note" if File . extname ( entry ) == ".md"
27
- entry = file_name
28
- file_size = File . size ( entry_path )
29
- counts [ :files ] += 1
30
- counts [ :size ] += File . size ( entry_path )
31
- { name : entry , type : "file" , path : File . join ( path , entry ) , size : file_size }
32
- end
33
- end
34
- root_files_
35
- end
36
-
37
- def self . build_links ( rootdir , root_files_ , root_files , backlinks = { } , embeds = { } )
38
- root_files_ . each do |file |
39
- if file [ :type ] == "dir"
40
- build_links ( rootdir , file [ :children ] , root_files , backlinks , embeds )
41
- elsif file [ :type ] == "file"
42
- entry_path = File . join ( rootdir , file [ :path ] )
43
- next if File . zero? ( entry_path ) || Obsidian . excluded_file_exts ( file [ :name ] )
44
- if file [ :name ] . end_with? ( ".mdnote" , ".canvas" )
45
- begin
46
- content = File . read ( entry_path )
47
- rescue Errno ::ENOENT
48
- puts "Error reading file: #{ entry_path } - No such file"
49
- next
50
- rescue Errno ::EACCES
51
- puts "Error reading file: #{ entry_path } - Permission denied"
52
- next
53
- end
54
-
55
- links = content . scan ( /\[ \[ (.*?)\] \] / ) . flatten
56
-
57
- backlinks [ file [ :path ] ] ||= { "backlink_paths" => [ ] }
58
-
59
- links . each do |link |
60
- lowercase_link = link . downcase
61
- matched_entry = find_matching_entry ( root_files , lowercase_link )
62
- if matched_entry
63
- unless matched_entry [ :path ] == file [ :path ] ||
64
- backlinks [ file [ :path ] ] [ "backlink_paths" ] . include? ( matched_entry [ :path ] )
65
- backlinks [ file [ :path ] ] [ "backlink_paths" ] << matched_entry [ :path ]
66
- end
67
- end
68
- end
69
- elsif !file [ :name ] . end_with? ( ".mdnote" , ".canvas" )
70
- if embeds [ file [ :path ] ] . nil? || embeds [ file [ :path ] ] [ "embed_paths" ] . nil?
71
- embeds [ file [ :path ] ] = { "embed_paths" => [ entry_path ] }
72
- else
73
- unless embeds [ file [ :path ] ] [ "embed_paths" ] . include? ( entry_path )
74
- embeds [ file [ :path ] ] [ "embed_paths" ] << entry_path
75
- end
76
- end
77
- end
78
- else
79
- puts "Skipping non-markdown file: #{ file [ :name ] } "
80
- end
81
- end
82
- [ backlinks , embeds ]
83
- end
84
-
85
- def self . find_matching_entry ( files , lowercase_link )
86
- stripped_link = lowercase_link . sub ( /\| .*$/ , "" ) . sub ( /#.*$/ , "" )
87
- files . each do |file |
88
- if file [ :type ] == "dir"
89
- result = find_matching_entry ( file [ :children ] , lowercase_link )
90
- return result if result
91
- elsif file [ :type ] == "file" && file [ :name ] . end_with? ( ".mdnote" , ".canvas" )
92
- file_name_without_extension = file [ :name ] . sub ( /\. \w +$/ , "" ) . downcase
93
- return file if file_name_without_extension == stripped_link
94
- end
95
- end
96
- nil
97
- end
98
-
99
- def self . excluded_file_exts ( filename )
100
- extensions = [ ".exe" , ".bat" , ".sh" , ".zip" , ".7z" , ".stl" , ".fbx" ]
101
- is_excluded = extensions . any? { |ext | filename . end_with? ( ext ) }
102
- if is_excluded
103
- puts "Excluded file: #{ filename } "
104
- end
105
- is_excluded
106
- end
107
-
108
- # ------------------------ Ruby Hash object formatters ----------------------- #
109
- def self . escape_backlinks ( backlinks )
110
- escaped_backlinks = { }
111
- backlinks . each do |path , data |
112
- escaped_path = escape_path ( path )
113
- escaped_data = {
114
- "backlink_paths" => data [ "backlink_paths" ] . map do |path |
115
- escape_path ( path )
116
- end
117
- }
118
- escaped_backlinks [ escaped_path ] = escaped_data
119
- end
120
- JSON . pretty_generate ( escaped_backlinks . to_json )
121
- end
122
-
123
- def self . escape_embeds ( embeds )
124
- escaped_embeds = { }
125
- embeds . each do |path , _ |
126
- escaped_path = escape_path ( path )
127
- escaped_embeds [ escaped_path ] = { }
128
- end
129
- JSON . pretty_generate ( escaped_embeds . to_json )
130
- end
131
-
132
- def self . escape_path ( path )
133
- escaped_path = path . gsub ( "'" , "/:|" ) . gsub ( '"' , "/:|" )
134
- ( escaped_path [ 0 ] == "/" ) ? escaped_path . slice ( 1 ..-1 ) : escaped_path
135
- end
136
-
137
- # ---------------------------------------------------------------------------- #
138
- # FileTreeGenerator #
139
- # ---------------------------------------------------------------------------- #
12
+ # Jekyll::Hooks.register :site, :post_write do |site|
13
+ # vault = site.config["obsidian_vault"]
14
+ # vault_path = File.join(site.dest, vault)
15
+ # Dir.glob(File.join(vault_path, "**", "*.md")).each do |md_file|
16
+ # new_file_path = md_file.sub(/\.md$/, ".mdnote")
17
+ # File.rename(md_file, new_file_path)
18
+ # end
19
+ # end
140
20
class FileTreeGenerator < Jekyll ::Generator
141
21
safe true
142
22
priority :lowest
@@ -148,11 +28,43 @@ def generate(site)
148
28
puts "Error: obsidian_vault is not set in config.yml"
149
29
exit ( 1 )
150
30
end
151
- site . config [ "obsidian_homepage" ]
31
+ enable_backlinks = site . config [ "obsidian_backlinks" ]
32
+ enable_embeds = site . config [ "obsidian_embeds" ]
152
33
153
34
# --------------------------------- site data -------------------------------- #
35
+ data_dir = File . join ( File . dirname ( site . dest ) , "_data" , "obsidian" )
36
+ FileUtils . mkdir_p ( data_dir ) unless File . directory? ( data_dir )
37
+
154
38
site . data [ "obsidian" ] = { } unless site . data [ "obsidian" ]
155
39
40
+ counts = { dirs : 0 , files : 0 , size : 0 }
41
+ obsidian_files = collect_files ( vault , "" , counts )
42
+ vault_data_json = File . join ( data_dir , "vault_data.json" )
43
+ File . write ( vault_data_json , JSON . pretty_generate ( counts . to_json ) )
44
+
45
+ vault_files_json = File . join ( data_dir , "vault_files.json" )
46
+ File . write ( vault_files_json , JSON . pretty_generate ( obsidian_files . to_json ) )
47
+
48
+ backlinks , embeds = build_links ( vault , obsidian_files , obsidian_files )
49
+
50
+ if enable_backlinks || enable_backlinks . nil?
51
+ backlinks_json = File . join ( data_dir , "backlinks.json" )
52
+ File . write ( backlinks_json , escape_backlinks ( backlinks ) )
53
+ puts "Backlinks built."
54
+ else
55
+ puts "Backlinks disabled"
56
+ end
57
+
58
+ if enable_embeds || enable_embeds . nil?
59
+ embeds_json = File . join ( data_dir , "embeds.json" )
60
+ File . write ( embeds_json , escape_embeds ( embeds ) )
61
+ puts "Embeds built."
62
+ else
63
+ puts "Embeds disabled"
64
+ end
65
+
66
+ site . config [ "obsidian_homepage" ]
67
+
156
68
obsidian_dir = File . join ( File . dirname ( site . dest ) , "_includes" , "obsidian" )
157
69
FileUtils . mkdir_p ( obsidian_dir ) unless File . directory? ( obsidian_dir )
158
70
@@ -203,50 +115,136 @@ def copy_files_from_dir(source_dir, destination_dir, overwrite = false)
203
115
copy_file_to_dir ( file_path , destination_dir , overwrite )
204
116
end
205
117
end
206
- end
207
118
208
- # ---------------------------------------------------------------------------- #
209
- # POST_WRITE HOOK REGISTER #
210
- # ---------------------------------------------------------------------------- #
211
- Jekyll ::Hooks . register :site , :post_write do |site |
212
- vault = site . config [ "obsidian_vault" ]
213
- vault_path = File . join ( site . dest , vault )
214
- Dir . glob ( File . join ( vault_path , "**" , "*.md" ) ) . each do |md_file |
215
- new_file_path = md_file . sub ( /\. md$/ , ".mdnote" )
216
- File . rename ( md_file , new_file_path )
119
+ def excluded_file_exts ( filename )
120
+ extensions = [ ".exe" , ".bat" , ".sh" , ".zip" , ".7z" , ".stl" , ".fbx" ]
121
+ is_excluded = extensions . any? { |ext | filename . end_with? ( ext ) }
122
+ if is_excluded
123
+ puts "Excluded file: #{ filename } "
124
+ end
125
+ is_excluded
217
126
end
218
- data_dir = File . join ( File . dirname ( site . dest ) , "_data" , "obsidian" )
219
- FileUtils . mkdir_p ( data_dir ) unless File . directory? ( data_dir )
220
- enable_backlinks = site . config [ "obsidian_backlinks" ]
221
- enable_embeds = site . config [ "obsidian_embeds" ]
222
-
223
- counts = { dirs : 0 , files : 0 , size : 0 }
224
- obsidian_files = Obsidian . collect_files ( vault , "" , counts )
225
- vault_data_json = File . join ( data_dir , "vault_data.json" )
226
- File . write ( vault_data_json , JSON . pretty_generate ( counts . to_json ) )
227
-
228
- vault_files_json = File . join ( data_dir , "vault_files.json" )
229
- File . write ( vault_files_json , JSON . pretty_generate ( obsidian_files . to_json ) )
230
-
231
- vault_path = File . join ( site . dest , vault )
232
- backlinks , embeds = Obsidian . build_links ( vault_path , obsidian_files , obsidian_files )
233
-
234
- if enable_backlinks || enable_backlinks . nil?
235
- backlinks_json = File . join ( data_dir , "backlinks.json" )
236
- File . write ( backlinks_json , Obsidian . escape_backlinks ( backlinks ) )
237
- puts "Backlinks built."
238
- else
239
- puts "Backlinks disabled"
127
+
128
+ # ------------------------ Ruby Hash object generators ----------------------- #
129
+ def collect_files ( rootdir , path = "" , counts = { dirs : 0 , files : 0 , size : 0 } )
130
+ root_files_ = [ ]
131
+ Dir . entries ( rootdir ) . each do |entry |
132
+ next if entry . start_with? ( "." , "_" )
133
+ entry_path = File . join ( rootdir , entry )
134
+ root_files_ << if File . directory? ( entry_path )
135
+ next if entry . start_with? ( ".obsidian" )
136
+ counts [ :dirs ] += 1
137
+ { name : entry , type : "dir" , path : File . join ( path , entry ) ,
138
+ children : collect_files ( entry_path , File . join ( path , entry ) , counts ) }
139
+ else
140
+ next if File . zero? ( entry_path ) || File . empty? ( entry_path )
141
+
142
+ if File . extname ( entry ) == ".md"
143
+ new_name = entry . sub ( ".md" , ".mdnote" )
144
+ new_path = File . join ( rootdir , new_name )
145
+ File . rename ( entry_path , new_path )
146
+ entry_path = new_path
147
+ entry = new_name
148
+ end
149
+
150
+ counts [ :files ] += 1
151
+ counts [ :size ] += File . size ( entry_path )
152
+ { name : entry , type : "file" , path : File . join ( path , entry ) , size : File . size ( entry_path ) }
153
+ end
154
+ end
155
+ root_files_
240
156
end
241
157
242
- if enable_embeds || enable_embeds . nil?
243
- embeds_json = File . join ( data_dir , "embeds.json" )
244
- File . write ( embeds_json , Obsidian . escape_embeds ( embeds ) )
245
- puts "Embeds built."
246
- else
247
- puts "Embeds disabled"
158
+ def build_links ( rootdir , root_files_ , root_files , backlinks = { } , embeds = { } )
159
+ root_files_ . each do |file |
160
+ if file [ :type ] == "dir"
161
+ build_links ( rootdir , file [ :children ] , root_files , backlinks , embeds )
162
+ elsif file [ :type ] == "file"
163
+ entry_path = File . join ( rootdir , file [ :path ] )
164
+ next if File . zero? ( entry_path ) || excluded_file_exts ( file [ :name ] )
165
+ if file [ :name ] . end_with? ( ".mdnote" , ".canvas" )
166
+ begin
167
+ content = File . read ( entry_path )
168
+ rescue Errno ::ENOENT
169
+ puts "Error reading file: #{ entry_path } - No such file"
170
+ next
171
+ rescue Errno ::EACCES
172
+ puts "Error reading file: #{ entry_path } - Permission denied"
173
+ next
174
+ end
175
+
176
+ links = content . scan ( /\[ \[ (.*?)\] \] / ) . flatten
177
+
178
+ backlinks [ file [ :path ] ] ||= { "backlink_paths" => [ ] }
179
+
180
+ links . each do |link |
181
+ lowercase_link = link . downcase
182
+ matched_entry = find_matching_entry ( root_files , lowercase_link )
183
+ if matched_entry
184
+ unless matched_entry [ :path ] == file [ :path ] ||
185
+ backlinks [ file [ :path ] ] [ "backlink_paths" ] . include? ( matched_entry [ :path ] )
186
+ backlinks [ file [ :path ] ] [ "backlink_paths" ] << matched_entry [ :path ]
187
+ end
188
+ end
189
+ end
190
+ elsif !file [ :name ] . end_with? ( ".mdnote" , ".canvas" )
191
+ if embeds [ file [ :path ] ] . nil? || embeds [ file [ :path ] ] [ "embed_paths" ] . nil?
192
+ embeds [ file [ :path ] ] = { "embed_paths" => [ entry_path ] }
193
+ else
194
+ unless embeds [ file [ :path ] ] [ "embed_paths" ] . include? ( entry_path )
195
+ embeds [ file [ :path ] ] [ "embed_paths" ] << entry_path
196
+ end
197
+ end
198
+ end
199
+ else
200
+ puts "Skipping non-markdown file: #{ file [ :name ] } "
201
+ end
202
+ end
203
+ [ backlinks , embeds ]
204
+ end
205
+
206
+ def find_matching_entry ( files , lowercase_link )
207
+ stripped_link = lowercase_link . sub ( /\| .*$/ , "" ) . sub ( /#.*$/ , "" )
208
+ files . each do |file |
209
+ if file [ :type ] == "dir"
210
+ result = find_matching_entry ( file [ :children ] , lowercase_link )
211
+ return result if result
212
+ elsif file [ :type ] == "file" && file [ :name ] . end_with? ( ".mdnote" , ".canvas" )
213
+ file_name_without_extension = file [ :name ] . sub ( /\. \w +$/ , "" ) . downcase
214
+ return file if file_name_without_extension == stripped_link
215
+ end
216
+ end
217
+ nil
218
+ end
219
+
220
+ # ------------------------ Ruby Hash object formatters ----------------------- #
221
+ def escape_backlinks ( backlinks )
222
+ escaped_backlinks = { }
223
+ backlinks . each do |path , data |
224
+ escaped_path = escape_path ( path )
225
+ escaped_data = {
226
+ "backlink_paths" => data [ "backlink_paths" ] . map do |path |
227
+ escape_path ( path )
228
+ end
229
+ }
230
+ escaped_backlinks [ escaped_path ] = escaped_data
231
+ end
232
+ JSON . pretty_generate ( escaped_backlinks . to_json )
248
233
end
249
- end
250
234
235
+ def escape_embeds ( embeds )
236
+ escaped_embeds = { }
237
+ embeds . each do |path , _ |
238
+ escaped_path = escape_path ( path )
239
+ escaped_embeds [ escaped_path ] = { }
240
+ end
241
+ JSON . pretty_generate ( escaped_embeds . to_json )
242
+ end
243
+
244
+ def escape_path ( path )
245
+ escaped_path = path . gsub ( "'" , "/:|" ) . gsub ( '"' , "/:|" )
246
+ ( escaped_path [ 0 ] == "/" ) ? escaped_path . slice ( 1 ..-1 ) : escaped_path
247
+ end
248
+ end
251
249
end
252
250
end
0 commit comments