hyphae 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/hyphae +54 -0
- data/lib/hyphae.rb +166 -0
- metadata +59 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 26fffd773e8c0b6c43d8a286fd4be72a835246377634ee003cd41adead85234c
|
4
|
+
data.tar.gz: 37abf4892e01b535f8e8585cbf616eae7bbce2d3a27663cb318f3f514d49b4b7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5aecfc870811743bcd373bbdab8942982e0781554d30f867df1045597550f29caa20bff837d1c461b89925f4632dfcd6f73a7e17b3a73dcf47a01d5aeea750ad
|
7
|
+
data.tar.gz: e09d2ac065b089110e335d556494a3fbec5eb80c6456c8f2aa6c0cf66ecd9fd6df58f4023cbe0545149adbd6ca4bcc0d1b45e59f6b60a675c23874ec713414cc
|
data/bin/hyphae
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'hyphae'
|
4
|
+
|
5
|
+
###################
|
6
|
+
### Main Script ###
|
7
|
+
###################
|
8
|
+
|
9
|
+
# The first argument given is the site input directory
|
10
|
+
input_dir = ARGV[0] || "site"
|
11
|
+
if not Dir.exist?(input_dir) then
|
12
|
+
puts "ERROR: No input directory '#{input_dir}'"
|
13
|
+
exit
|
14
|
+
end
|
15
|
+
|
16
|
+
# The second argument is the rendered html site output directory
|
17
|
+
output_dir = ARGV[1] || "_build"
|
18
|
+
|
19
|
+
# Builds the page tree of the site
|
20
|
+
if not Dir.exist?(input_dir + "/pages") then
|
21
|
+
puts "ERROR: No '/pages' directory in #{input_dir}"
|
22
|
+
exit
|
23
|
+
end
|
24
|
+
page_tree = Hyphae::SiteDir.new(input_dir + '/pages')
|
25
|
+
|
26
|
+
# Reads site template file
|
27
|
+
if not File.exist?(input_dir + "/template.html") then
|
28
|
+
puts "ERROR: No 'template.html' file in #{input_dir}"
|
29
|
+
exit
|
30
|
+
end
|
31
|
+
template = File.read(input_dir + "/template.html")
|
32
|
+
|
33
|
+
# Reads site index content file
|
34
|
+
index_content = ''
|
35
|
+
if File.exist?(input_dir + "/index.html") then
|
36
|
+
index_content = File.read(input_dir + "/template.html")
|
37
|
+
end
|
38
|
+
|
39
|
+
# Makes the output directory
|
40
|
+
FileUtils.rm_rf output_dir
|
41
|
+
FileUtils.mkdir output_dir
|
42
|
+
|
43
|
+
# Moves site's static files
|
44
|
+
if not Dir.exist?(input_dir + "/static") then
|
45
|
+
puts "ERROR: No '/static' directory in #{input_dir}"
|
46
|
+
exit
|
47
|
+
end
|
48
|
+
FileUtils.cp_r(input_dir + '/static', output_dir)
|
49
|
+
|
50
|
+
# Builds html pages
|
51
|
+
page_tree.build(output_dir, template)
|
52
|
+
|
53
|
+
# Build site index
|
54
|
+
page_tree.build_index(output_dir, template, index_content)
|
data/lib/hyphae.rb
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'kramdown'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Hyphae
|
5
|
+
|
6
|
+
#########################
|
7
|
+
### Utility Functions ###
|
8
|
+
#########################
|
9
|
+
|
10
|
+
# Produces a URL safe version of a string
|
11
|
+
def self.sanitize(str)
|
12
|
+
str.downcase.gsub(' ', '_').gsub(/[^\d\w_]/, "")
|
13
|
+
end
|
14
|
+
|
15
|
+
# Renders an HTML tag
|
16
|
+
def self.make_tag(tag, content, attrs={})
|
17
|
+
attrs_str = ""
|
18
|
+
attrs.map { |x, y| attrs_str << " #{x}=\"#{y}\""}
|
19
|
+
"<#{tag}#{attrs_str}>#{content}</#{tag}>"
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
#############################
|
25
|
+
### Site Building Classes ###
|
26
|
+
#############################
|
27
|
+
|
28
|
+
# Site content node, all other site node classes inherit from this one
|
29
|
+
class SiteNode
|
30
|
+
attr_reader :name, :slug, :path, :parent, :order, :date
|
31
|
+
|
32
|
+
def initialize(filename, parent=nil)
|
33
|
+
@name = File.basename(filename, '.*')
|
34
|
+
@parent = parent
|
35
|
+
@hidden = false
|
36
|
+
@order = nil
|
37
|
+
@date = nil
|
38
|
+
if captures = @name.match(/^_(.+)/) then
|
39
|
+
@hidden = true
|
40
|
+
@name = captures[1]
|
41
|
+
elsif captures = @name.match(/^o(\d+)_(.+)/) then
|
42
|
+
@order = captures[1].to_i
|
43
|
+
@name = captures[2]
|
44
|
+
elsif captures = @name.match(/^ut(\d+)_(.+)/) then
|
45
|
+
@date = Time.at(captures[1].to_i)
|
46
|
+
@name = captures[2]
|
47
|
+
end
|
48
|
+
@slug = Hyphae::sanitize @name
|
49
|
+
@path = @parent ? @parent.path + [(@slug)] : []
|
50
|
+
return self
|
51
|
+
end
|
52
|
+
|
53
|
+
# Get the root SiteNode of a tree of SiteNodes
|
54
|
+
def root
|
55
|
+
return self if @parent.nil?
|
56
|
+
@parent.root
|
57
|
+
end
|
58
|
+
|
59
|
+
# Compare this SiteNode with another
|
60
|
+
def cmp(other)
|
61
|
+
if other.order then
|
62
|
+
return 1 if @order.nil?
|
63
|
+
return @order <=> other.order
|
64
|
+
end
|
65
|
+
if other.date then
|
66
|
+
return 1 if @date.nil?
|
67
|
+
return other.date <=> @date
|
68
|
+
end
|
69
|
+
@name <=> other.name
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
# A SiteDir represents a directory containing nested SiteNodes
|
75
|
+
class SiteDir < SiteNode
|
76
|
+
def initialize(filename, parent=nil)
|
77
|
+
super
|
78
|
+
@children = []
|
79
|
+
Dir.glob(filename + '/*').each do |f|
|
80
|
+
if File.directory? f then
|
81
|
+
@children.push SiteDir.new(f, self)
|
82
|
+
elsif File.extname(f) == '.md' then
|
83
|
+
@children.push SitePage.new(f, self)
|
84
|
+
elsif File.extname(f) == '.link' then
|
85
|
+
@children.push SiteLink.new(f, self)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
@children.sort! { |x, y| x.cmp(y) }
|
89
|
+
return self
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns the html for each child's nav menu link
|
93
|
+
def menu_items(open_path=[])
|
94
|
+
@children.map { |x| x.nav_link(open_path) }.join
|
95
|
+
end
|
96
|
+
|
97
|
+
# Returns the html for this SiteDir's nav menu link
|
98
|
+
def nav_link(open_path=[])
|
99
|
+
return "" if @hidden
|
100
|
+
link = Hyphae::make_tag('span', @name, {'class' => 'nav_menu_link'})
|
101
|
+
menu_attrs = { 'class' => 'nav_menu_items' }
|
102
|
+
menu_attrs['class'] += ' open' if open_path.first == @slug
|
103
|
+
menu = Hyphae::make_tag('div', menu_items(open_path[1..-1] || []), menu_attrs)
|
104
|
+
Hyphae::make_tag('div', link + menu, {'class' => 'nav_menu'})
|
105
|
+
end
|
106
|
+
|
107
|
+
# Recursively builds pages for all children
|
108
|
+
def build(build_dir, template)
|
109
|
+
@children.each { |child| child.build(build_dir, template) }
|
110
|
+
end
|
111
|
+
|
112
|
+
# Builds an index page for this SiteDir
|
113
|
+
def build_index(build_dir, template, index_content='')
|
114
|
+
page_html = template.gsub('{{navbar}}', menu_items).gsub("{{content}}", index_content).gsub('{{index_class}}', ' index_page')
|
115
|
+
File.open("#{build_dir}/index.html", 'w') { |f| f << page_html }
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
# A SitePage represents a markdown document
|
121
|
+
class SitePage < SiteNode
|
122
|
+
def initialize(filename, parent)
|
123
|
+
super
|
124
|
+
markdown = File.read filename
|
125
|
+
@html = Kramdown::Document.new(markdown).to_html
|
126
|
+
end
|
127
|
+
|
128
|
+
# Builds the nav menu tag for this page
|
129
|
+
def nav_link(open_path=[])
|
130
|
+
return "" if @hidden
|
131
|
+
attrs = { 'class' => 'nav_page', 'href' => "/#{@path.join('/')}.html" }
|
132
|
+
attrs['class'] += ' current_page' if @slug == open_path.first
|
133
|
+
Hyphae::make_tag('a', @name, attrs)
|
134
|
+
end
|
135
|
+
|
136
|
+
# Builds html page
|
137
|
+
def build(build_dir, template)
|
138
|
+
nav = root.menu_items(@path)
|
139
|
+
page_html = template.gsub('{{navbar}}', nav).gsub("{{content}}", @html).gsub('{{index_class}}', '')
|
140
|
+
page_dir_path = "#{build_dir}/#{@parent.path.join('/')}"
|
141
|
+
FileUtils.mkdir_p page_dir_path
|
142
|
+
File.open("#{page_dir_path}/#{@slug}.html", 'w') { |f| f << page_html }
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
# A SiteLink represents an arbitrary link
|
148
|
+
class SiteLink < SiteNode
|
149
|
+
def initialize(filename, parent)
|
150
|
+
super
|
151
|
+
@link = File.read(filename).strip
|
152
|
+
end
|
153
|
+
|
154
|
+
# Builds the nav menu tag for this page
|
155
|
+
def nav_link(open_path=[])
|
156
|
+
return "" if @hidden
|
157
|
+
attrs = { 'class' => 'nav_link', 'href' => @link }
|
158
|
+
Hyphae::make_tag('a', @name, attrs)
|
159
|
+
end
|
160
|
+
|
161
|
+
# Builds html page (does nothing for a link)
|
162
|
+
def build(build_dir, template)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hyphae
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nicholas Rakita
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-10-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: kramdown
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.11.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.11.1
|
27
|
+
description: A Minimal SSG
|
28
|
+
email: rakita@protonmail.ch
|
29
|
+
executables:
|
30
|
+
- hyphae
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- bin/hyphae
|
35
|
+
- lib/hyphae.rb
|
36
|
+
homepage: https://rubygems.org/gems/hyphae
|
37
|
+
licenses:
|
38
|
+
- Unlicense
|
39
|
+
metadata: {}
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options: []
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
requirements: []
|
55
|
+
rubygems_version: 3.3.7
|
56
|
+
signing_key:
|
57
|
+
specification_version: 4
|
58
|
+
summary: Hyphae
|
59
|
+
test_files: []
|