static_site_builder 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d255a1dc76e27d47e5549358a8ac023117b0674a084c74bc1911f073fc5d2d55
4
- data.tar.gz: 1d40b7b67100ac3b24c329035466aefb6adcb1a6dfe4bb60328bb7fea09983fb
3
+ metadata.gz: 441b9a8a2cb695e4a89d333ab1ea85bfd76a3f6c16b4ba747025e440098be784
4
+ data.tar.gz: dcb8971a377117b95ab0189ae8993b3d2b42c506e7bd8b05b9009976e77a7570
5
5
  SHA512:
6
- metadata.gz: f3317e6a6cbacf72e49f07fcb4482807c4e52ef3efdff2a62176f5f47565cb7ddc73dc63a883acf45606e4521cbf2024ecb3aaf6ad8f2912c8ff75503e6f0c2a
7
- data.tar.gz: b2284fce96a82d5c3aa6e7b63d89f667e2fbd52f8499325c03abf7547c25fba8a0775ef150fca74fd1e8a74f8bdd257c5eeab158dbdfbec17adf77f9cd517cd4
6
+ metadata.gz: beb2e52cade664496b8f3a4efa5599e2f988a48a638ffe78cd74af481c6d906d4149f95bb90f834ad324dc389c41a6d8d31ee5fbd1b1a9373b529e7482d6ea3d
7
+ data.tar.gz: 39aa9ce17cc9d4dd7aa4954369174f34af27e64c1b20b159d3901fef931f9c17702493001b7d181c964e9b4b17a8e5a061bd76adb70f8dcbcc777ec386ff6c9b
data/.gitignore CHANGED
@@ -6,6 +6,7 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
- markdown/
9
+ /markdown/
10
+ /test/fixtures/output
10
11
  .DS_Store
11
- spike.*
12
+ .byebug_history
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.5.3
1
+ 2.7.0
data/Gemfile CHANGED
@@ -1,6 +1,8 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
3
+ ruby "~> 2.7"
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
6
 
5
7
  # Specify your gem's dependencies in static_site_builder.gemspec
6
8
  gemspec
data/Gemfile.lock CHANGED
@@ -1,32 +1,40 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- static_site_builder (0.4.0)
4
+ static_site_builder (0.5.0)
5
5
  redcarpet (~> 3.4)
6
- thor (~> 0.20)
6
+ thor (~> 1.1)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- coderay (1.1.2)
12
- method_source (0.9.2)
13
- minitest (5.11.3)
14
- pry (0.12.2)
15
- coderay (~> 1.1.0)
16
- method_source (~> 0.9.0)
17
- rake (12.3.2)
18
- redcarpet (3.4.0)
19
- thor (0.20.3)
11
+ byebug (11.1.3)
12
+ coderay (1.1.3)
13
+ method_source (1.0.0)
14
+ minitest (5.14.4)
15
+ pry (0.14.1)
16
+ coderay (~> 1.1)
17
+ method_source (~> 1.0)
18
+ rake (13.0.6)
19
+ redcarpet (3.5.1)
20
+ thor (1.1.0)
21
+ yart (0.1.0)
20
22
 
21
23
  PLATFORMS
22
24
  ruby
25
+ x86_64-linux
23
26
 
24
27
  DEPENDENCIES
25
28
  bundler (~> 2.0)
29
+ byebug (~> 11.1)
26
30
  minitest (~> 5.11)
27
31
  pry (~> 0.12)
28
- rake (~> 12.3)
32
+ rake (~> 13.0)
29
33
  static_site_builder!
34
+ yart (~> 0.1)
35
+
36
+ RUBY VERSION
37
+ ruby 2.7.0p0
30
38
 
31
39
  BUNDLED WITH
32
- 2.0.1
40
+ 2.2.16
data/README.md CHANGED
@@ -53,6 +53,22 @@ If using your own template, you must ensure it's valid HTML and that it contains
53
53
 
54
54
  You can use this gem's built in [default template](https://github.com/michaeltelford/static_site_builder/blob/master/templates/default_template.html) as an example.
55
55
 
56
+ ## Beyond Markdown
57
+
58
+ Markdown makes writing static content easy, but it doesn't support more advanced HTML features (like forms etc). You can write your own HTML within the markdown document and it will be parsed as is. Alternatively, you can use the [`yart`](https://github.com/michaeltelford/yart) gem to turn Ruby into HTML, removing the boiler plate from generating HTML.
59
+
60
+ For example, placing the following code snippet inside your markdown will create a contact form in the generated HTML page:
61
+
62
+ ```yart
63
+ form action: "/api/contact" do
64
+ input type: :email, required: true
65
+ input type: :textarea, required: true
66
+ button(type: :submit) { "Send Message" }
67
+ end
68
+ ```
69
+
70
+ The important bit here is the ` ```yart ` line which tells the `YART` parser to render this snippet of Ruby into HTML. Check out the [`yart README`](https://github.com/michaeltelford/yart) for more details on how to use the `YART` DSL.
71
+
56
72
  ## Development
57
73
 
58
74
  I welcome community contribution as long as the changes makes sense.
data/Rakefile CHANGED
@@ -1,6 +1,7 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
3
  require "static_site_builder"
4
+ require "byebug"
4
5
 
5
6
  task default: :help
6
7
 
@@ -20,7 +21,7 @@ task :build_site, :markdown_dirpath, :output_dirpath do |t, args|
20
21
  args.with_defaults(output_dirpath: "./markdown/html")
21
22
  puts StaticSiteBuilder.build_website(
22
23
  args[:markdown_dirpath],
23
- StaticSiteBuilder::HTMLTemplater.new,
24
+ StaticSiteBuilder::TemplateRenderer.new,
24
25
  args[:output_dirpath]
25
26
  )
26
27
  end
data/exe/site_builder CHANGED
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
4
+
4
5
  require "static_site_builder"
5
6
  require "thor"
6
7
 
7
- DEFAULT_TEMPLATE = StaticSiteBuilder::HTMLTemplater::DEFAULT_TEMPLATE
8
+ DEFAULT_TEMPLATE = StaticSiteBuilder::TemplateRenderer::DEFAULT_TEMPLATE
8
9
 
9
10
  class SiteBuilderCLI < Thor
10
11
  desc "build", "Builds a static HTML website from markdown"
@@ -16,20 +17,20 @@ class SiteBuilderCLI < Thor
16
17
  desc: "HTML template which embeds the markdown (<body>) of each webpage"
17
18
  )
18
19
  def build
19
- template = StaticSiteBuilder::HTMLTemplater.new(
20
+ template = StaticSiteBuilder::TemplateRenderer.new(
20
21
  template_filepath: options[:template],
21
22
  gem_included_template: options[:template] == DEFAULT_TEMPLATE
22
23
  )
23
24
 
24
- html = StaticSiteBuilder.build_website(
25
+ html_files = StaticSiteBuilder.build_website(
25
26
  options[:in],
26
27
  template,
27
28
  options[:out]
28
29
  )
29
30
 
30
- if not html.empty?
31
- puts "Site built with #{html.length} HTML file(s):"
32
- puts html
31
+ unless html_files.empty?
32
+ puts "Site built with #{html_files.length} HTML file(s):"
33
+ puts html_files
33
34
  else
34
35
  puts "No markdown files found in: #{options[:in]}"
35
36
  end
@@ -1,64 +1,64 @@
1
- # Require all lib files here to enable a single require.
2
- require "static_site_builder/version"
3
- require "static_site_builder/html_templater"
4
-
5
1
  # Require any non lib code here to enable a single require.
6
2
  require "fileutils"
7
3
  require "redcarpet"
8
4
 
5
+ # Require all lib files here to enable a single require.
6
+ require "static_site_builder/version"
7
+ require "static_site_builder/renderers/renderer"
8
+ require "static_site_builder/renderers/yart_renderer"
9
+ require "static_site_builder/renderers/markdown_renderer"
10
+ require "static_site_builder/renderers/template_renderer"
11
+
9
12
  module StaticSiteBuilder
10
- # Converts markdown to html and returns it.
11
- def self.render(markdown)
12
- renderer = Redcarpet::Markdown.new(Redcarpet::Render::HTML,
13
- tables: true,
14
- fenced_code_blocks: true,
15
- autolink: true,
16
- strikethrough: true,
17
- superscript: true,
18
- underline: true,
19
- highlight: true,
20
- quote: true,
21
- footnotes: true
22
- )
23
- renderer.render(markdown)
13
+ # Takes a markdown_dirpath, finds all "*.md" files and converts each to a
14
+ # "*.html" file in order to build a static website. A template is used to
15
+ # embed each built webpage in. The output_dirpath will default to the
16
+ # markdown_dirpath if not set.
17
+ def self.build_website(markdown_dirpath, template, output_dirpath=nil)
18
+ pattern = "#{markdown_dirpath}/*.md"
19
+
20
+ Dir.glob(pattern).map { |f| self.build_webpage(f, template, output_dirpath) }
24
21
  end
25
22
 
23
+ private
24
+
26
25
  # Takes a markdown_filepath, reads and converts its contents to html before
27
26
  # creating a html file of the same name in the output_dirpath directory.
28
27
  # If not provided, the output_dirpath will be the same directory as the
29
28
  # markdown file. The output_dirpath will be created if not already.
30
- # Note: If the html file already exists it's contents will be overwritten.
29
+ # Note: If the html file already exists its contents will be overwritten.
31
30
  # A template is used to house the html body in, creating a full webpage.
32
31
  def self.build_webpage(markdown_filepath, template, output_dirpath=nil)
33
- markdown = File.read(markdown_filepath)
32
+ markdown_filepath = self.remove_trailing_slash(markdown_filepath)
33
+ output_dirpath = self.remove_trailing_slash(output_dirpath)
34
34
 
35
- html_body = self.render(markdown)
36
- html = template.render(html_body)
35
+ markdown = File.read(markdown_filepath)
36
+ html = self.apply_renderers(template, markdown)
37
37
 
38
38
  dirpath = File.dirname(markdown_filepath)
39
39
  output_dirpath ||= dirpath
40
- FileUtils.mkdir_p(output_dirpath) unless Dir.exists?(output_dirpath)
40
+ FileUtils.mkdir_p(output_dirpath) unless Dir.exist?(output_dirpath)
41
41
 
42
42
  filename_with_md_ext = File.basename(markdown_filepath)
43
- filename_without_md_ext = filename_with_md_ext.split(".md")[0]
44
- html_filepath = "#{output_dirpath}/#{filename_without_md_ext}.html"
43
+ filename_without_md_ext = filename_with_md_ext.gsub(".md", "")
45
44
 
45
+ html_filepath = "#{output_dirpath}/#{filename_without_md_ext}.html"
46
46
  File.open(html_filepath, "w") { |f| f.write(html) }
47
+
47
48
  html_filepath
48
49
  end
49
50
 
50
- # Takes a markdown_dirpath, finds all "*.md" files and converts each to a
51
- # "*.html" file in order to build a static website. A template is used to
52
- # embed each built webpage in. The output_dirpath will default to the
53
- # markdown_dirpath if not set.
54
- def self.build_website(markdown_dirpath, template, output_dirpath=nil)
55
- html_filepaths = []
56
- pattern = "#{markdown_dirpath}/*.md"
51
+ # Removes the trailing / (if present) and returns.
52
+ def self.remove_trailing_slash(filepath)
53
+ return filepath unless filepath.end_with?("/")
57
54
 
58
- Dir.glob(pattern).each do |f|
59
- html_filepaths << self.build_webpage(f, template, output_dirpath)
60
- end
55
+ filepath.chop
56
+ end
61
57
 
62
- html_filepaths
58
+ # Apply the necessary renderers to the Markdown, returning a HTML String.
59
+ def self.apply_renderers(template, markdown)
60
+ markdown = YARTRenderer.new(markdown).render
61
+ html_body = MarkdownRenderer.new(markdown).render
62
+ template.render(html_body)
63
63
  end
64
64
  end
@@ -0,0 +1,30 @@
1
+ module StaticSiteBuilder
2
+ # Renders Markdown into HTML. Any existing HTML inside the Markdown will NOT be removed,
3
+ # allowing other renderers to be applied before this one where required.
4
+ class MarkdownRenderer < Renderer
5
+ attr_reader :markdown
6
+
7
+ def initialize(markdown)
8
+ super()
9
+
10
+ @markdown = markdown
11
+ @redcarpet = Redcarpet::Markdown.new(
12
+ Redcarpet::Render::HTML,
13
+ tables: true,
14
+ fenced_code_blocks: true,
15
+ autolink: true,
16
+ strikethrough: true,
17
+ superscript: true,
18
+ underline: true,
19
+ highlight: true,
20
+ quote: true,
21
+ footnotes: true,
22
+ )
23
+ end
24
+
25
+ # Returns a String of HTML (rendered from the given Markdown).
26
+ def render
27
+ @redcarpet.render(@markdown)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,11 @@
1
+ module StaticSiteBuilder
2
+ # Renderer super class to be inherited from.
3
+ class Renderer
4
+ def initialize
5
+ end
6
+
7
+ def render
8
+ raise "Missing `render` method in sub-class"
9
+ end
10
+ end
11
+ end
@@ -1,7 +1,8 @@
1
1
  module StaticSiteBuilder
2
- class HTMLTemplater
3
- EDITABLE_REGION = '<div id="editable_region"></div>'.freeze
4
- DEFAULT_TEMPLATE = "templates/default_template.html".freeze
2
+ # Renders the given HTML body inside the given HTML webpage template.
3
+ class TemplateRenderer < Renderer
4
+ EDITABLE_REGION = '<div id="editable_region"></div>'.freeze
5
+ DEFAULT_TEMPLATE = "../templates/default_template.html".freeze
5
6
 
6
7
  attr_reader :template_filepath, :gem_included_template, :html
7
8
 
@@ -18,15 +19,15 @@ module StaticSiteBuilder
18
19
  gem_included_template: true,
19
20
  html: nil
20
21
  )
22
+ super()
23
+
21
24
  @template_filepath = template_filepath
22
25
  @gem_included_template = gem_included_template
23
26
  @html = html
24
27
 
25
28
  read_template unless @html
26
29
 
27
- if not valid?
28
- raise "Missing editable region in template: #{EDITABLE_REGION}"
29
- end
30
+ raise "Missing editable region in template: #{EDITABLE_REGION}" unless valid?
30
31
  end
31
32
 
32
33
  # Returns wether or not the @html has an EDITABLE_REGION or not.
@@ -45,15 +46,17 @@ module StaticSiteBuilder
45
46
 
46
47
  private
47
48
 
48
- # Reads the @template_filepath file and sets @html to it's contents.
49
+ # Reads the @template_filepath file and sets @html to its contents.
49
50
  # The correct filepath is decided on based on wether or not the template is
50
51
  # built into the gem or on the user's local filesystem.
51
52
  def read_template
52
53
  path = @template_filepath
54
+
53
55
  if @gem_included_template
54
56
  relative_path = "../../#{@template_filepath}"
55
57
  path = File.expand_path(relative_path, File.dirname(__FILE__))
56
58
  end
59
+
57
60
  @html = File.read(path)
58
61
  end
59
62
  end
@@ -0,0 +1,56 @@
1
+ def yart_installed?
2
+ require("yart")
3
+ true
4
+ rescue LoadError
5
+ puts "Skipping YART rendering because the 'yart' gem isn't installed"
6
+ false
7
+ end
8
+
9
+ $yart_installed = yart_installed?
10
+
11
+ module StaticSiteBuilder
12
+ # Renders YART snippets into HTML (within a Markdown document).
13
+ class YARTRenderer < Renderer
14
+ YART_START_LINE = "```yart"
15
+ YART_END_LINE = "```"
16
+ YART_PARSE_ERROR = "'YART.parse' detected in markdown, remove it leaving just the block to be parsed by YART"
17
+
18
+ attr_reader :markdown
19
+
20
+ def initialize(markdown)
21
+ super()
22
+
23
+ @markdown = markdown
24
+ end
25
+
26
+ # Returns a String of Markdown (having recursively rendered any found YART snippets into HTML).
27
+ def render
28
+ return @markdown unless $yart_installed
29
+
30
+ lines = @markdown.split("\n")
31
+ return @markdown unless yart_snippet?(lines)
32
+
33
+ yart_lines = extract_yart_lines(lines)
34
+ yart_snippet = yart_lines[1..-2].join("\n")
35
+ raise YART_PARSE_ERROR if yart_snippet.include?("YART.parse")
36
+
37
+ html = YART.parse { eval(yart_snippet) }
38
+ @markdown.sub!(yart_lines.join("\n"), html)
39
+
40
+ render
41
+ end
42
+
43
+ private
44
+
45
+ def yart_snippet?(lines)
46
+ lines.include?(YART_START_LINE) && lines.include?(YART_END_LINE)
47
+ end
48
+
49
+ def extract_yart_lines(lines)
50
+ start = lines.find_index(YART_START_LINE)
51
+ finish = lines.find_index(YART_END_LINE)
52
+
53
+ lines[start..finish]
54
+ end
55
+ end
56
+ end
@@ -1,3 +1,3 @@
1
1
  module StaticSiteBuilder
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -13,10 +13,10 @@ Gem::Specification.new do |spec|
13
13
  spec.description = "Gem for building static content websites from markdown."
14
14
  spec.homepage = "https://github.com/michaeltelford/static_site_builder"
15
15
  spec.license = "MIT"
16
-
16
+
17
17
  spec.post_install_message = "Added the executable 'site_builder' to $PATH"
18
18
 
19
- spec.required_ruby_version = '~> 2.5'
19
+ spec.required_ruby_version = '~> 2.7'
20
20
 
21
21
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
22
22
  # to allow pushing to a single host or delete this section to allow pushing to any host.
@@ -35,10 +35,12 @@ Gem::Specification.new do |spec|
35
35
  spec.require_paths = ["lib"]
36
36
 
37
37
  spec.add_development_dependency "bundler", "~> 2.0"
38
- spec.add_development_dependency "rake", "~> 12.3"
38
+ spec.add_development_dependency "rake", "~> 13.0"
39
39
  spec.add_development_dependency "minitest", "~> 5.11"
40
40
  spec.add_development_dependency "pry", "~> 0.12"
41
+ spec.add_development_dependency "byebug", "~> 11.1"
42
+ spec.add_development_dependency "yart", "~> 0.1"
41
43
 
42
44
  spec.add_runtime_dependency "redcarpet", "~> 3.4"
43
- spec.add_runtime_dependency "thor", "~> 0.20"
45
+ spec.add_runtime_dependency "thor", "~> 1.1"
44
46
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: static_site_builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Telford
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-06-04 00:00:00.000000000 Z
11
+ date: 2021-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '12.3'
33
+ version: '13.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '12.3'
40
+ version: '13.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +66,34 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0.12'
69
+ - !ruby/object:Gem::Dependency
70
+ name: byebug
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '11.1'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '11.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: yart
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.1'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.1'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: redcarpet
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +114,14 @@ dependencies:
86
114
  requirements:
87
115
  - - "~>"
88
116
  - !ruby/object:Gem::Version
89
- version: '0.20'
117
+ version: '1.1'
90
118
  type: :runtime
91
119
  prerelease: false
92
120
  version_requirements: !ruby/object:Gem::Requirement
93
121
  requirements:
94
122
  - - "~>"
95
123
  - !ruby/object:Gem::Version
96
- version: '0.20'
124
+ version: '1.1'
97
125
  description: Gem for building static content websites from markdown.
98
126
  email:
99
127
  - michael.telford@live.com
@@ -115,7 +143,10 @@ files:
115
143
  - bin/setup
116
144
  - exe/site_builder
117
145
  - lib/static_site_builder.rb
118
- - lib/static_site_builder/html_templater.rb
146
+ - lib/static_site_builder/renderers/markdown_renderer.rb
147
+ - lib/static_site_builder/renderers/renderer.rb
148
+ - lib/static_site_builder/renderers/template_renderer.rb
149
+ - lib/static_site_builder/renderers/yart_renderer.rb
119
150
  - lib/static_site_builder/version.rb
120
151
  - static_site_builder.gemspec
121
152
  - templates/default_template.html
@@ -132,15 +163,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
132
163
  requirements:
133
164
  - - "~>"
134
165
  - !ruby/object:Gem::Version
135
- version: '2.5'
166
+ version: '2.7'
136
167
  required_rubygems_version: !ruby/object:Gem::Requirement
137
168
  requirements:
138
169
  - - ">="
139
170
  - !ruby/object:Gem::Version
140
171
  version: '0'
141
172
  requirements: []
142
- rubyforge_project:
143
- rubygems_version: 2.7.6
173
+ rubygems_version: 3.1.2
144
174
  signing_key:
145
175
  specification_version: 4
146
176
  summary: Gem for building static content websites from markdown.