ruby-md-ssg 0.1.0 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df65115f64a772c620d615e8b0bb752d340bc47821ffc9228a976369c8a65514
4
- data.tar.gz: 1b0e4cfd186cb5b26c0d61051579ab13aec4b0ddf2afe7ec42f5d02d593e364f
3
+ metadata.gz: c43097acb4ef035583e37a2a668d83bdc6522f0c33eab8917cb276b963c478c5
4
+ data.tar.gz: f1a7e9d0f5d514a29cd181f6a77efe8be598462c4700790627bc9f21b8d79e50
5
5
  SHA512:
6
- metadata.gz: 283a2e7203583828fd569f7104b87f8b60a14991562070b315e6b057156fc0fe6015aa10eef6b6d4d371c25b626ef2ab2da943e3153bfff2c63852fc47e34a5e
7
- data.tar.gz: f8fdc454c0b484223430bcc130e230fff533f472a8306230d9fe467b4d258ae98b7c86b6c3ecc8b1fd4b4a4ff6e2dcc511259643982fb9a4c30047157ca11b3d
6
+ metadata.gz: 500ef9b8abc74e5e997850427e330401b54240f4273bd05cf36a3877be69a833d3c43058cd516dfeaa8b09114f295d2e954e753758e8d1855ad6c816271c2d98
7
+ data.tar.gz: 6347f1845b09279476f723cba1c2137c7a23f3d330879ffde553aedc723af7b9cac2e0a7e72072649e8e5f4903fc158dfc96919b21d1e5c56cf641c26d2914c6
data/README.md CHANGED
@@ -12,6 +12,6 @@ bundle exec ruby bin/test
12
12
  ## CLI
13
13
 
14
14
  - `ruby_md_ssg new my-site` — scaffold a new project using the bundled template
15
- - `ruby_md_ssg build` — regenerate the site into `build/` (also emits `sitemap.xml`; pass `--base-url` to control absolute URLs)
15
+ - `ruby_md_ssg build` — regenerate the site into `build/` (also emits `sitemap.xml`; pass `--base-url`/`--base-path` to control canonical URLs and link prefixes)
16
16
  - `ruby_md_ssg serve` — serve the site locally with automatic rebuilds
17
17
  - `ruby_md_ssg menu` — refresh `docs/menu.yml`
@@ -100,7 +100,8 @@ module RubyMdSsg
100
100
  build_dir: options[:build],
101
101
  assets_dir: options[:assets],
102
102
  menu_path: options[:menu],
103
- base_url: options[:base_url]
103
+ base_url: options[:base_url],
104
+ base_path: options[:base_path]
104
105
  )
105
106
  compiler.compile
106
107
  end
@@ -136,6 +137,13 @@ module RubyMdSsg
136
137
  opts.on('--assets PATH', 'Assets directory') do |path|
137
138
  options[:assets] = File.expand_path(path)
138
139
  end
140
+ opts.on(
141
+ '--base-path PATH',
142
+ 'Base path prefix for links/assets',
143
+ 'defaults to ENV RUBY_MD_SSG_BASE_PATH'
144
+ ) do |path|
145
+ options[:base_path] = path
146
+ end
139
147
  opts.on(
140
148
  '--base-url URL',
141
149
  'Base URL for sitemap entries (defaults to ENV RUBY_MD_SSG_BASE_URL)'
@@ -164,6 +172,7 @@ module RubyMdSsg
164
172
  options[:build] ||= RubyMdSsg::Paths.build_dir
165
173
  options[:menu] ||= RubyMdSsg::Paths.menu_config
166
174
  options[:assets] ||= RubyMdSsg::Paths.assets_dir
175
+ options[:base_path] ||= ENV.fetch('RUBY_MD_SSG_BASE_PATH', nil)
167
176
  options[:base_url] ||= ENV.fetch('RUBY_MD_SSG_BASE_URL', nil)
168
177
  options.delete_if { |_key, value| value.nil? }
169
178
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'fileutils'
4
4
  require 'nokogiri'
5
+ require 'uri'
5
6
  require_relative 'paths'
6
7
  require_relative 'document_finder'
7
8
  require_relative 'menu_config'
@@ -16,13 +17,15 @@ module RubyMdSsg
16
17
  build_dir: Paths.build_dir,
17
18
  assets_dir: Paths.assets_dir,
18
19
  menu_path: Paths.menu_config,
19
- base_url: nil
20
+ base_url: nil,
21
+ base_path: nil
20
22
  )
21
23
  @docs_dir = docs_dir
22
24
  @build_dir = build_dir
23
25
  @assets_dir = assets_dir
24
26
  @menu_path = menu_path
25
27
  @base_url = base_url
28
+ @base_path = base_path || derive_base_path_from_base_url(base_url)
26
29
  @markdown = MarkdownRenderer.new
27
30
  @layout = LayoutRenderer.new
28
31
  @html_formatter = HtmlFormatter.new
@@ -46,7 +49,7 @@ module RubyMdSsg
46
49
  private
47
50
 
48
51
  attr_reader :docs_dir, :build_dir, :assets_dir, :menu_path,
49
- :markdown, :layout, :html_formatter, :base_url
52
+ :markdown, :layout, :html_formatter, :base_url, :base_path
50
53
 
51
54
  def purge_build
52
55
  FileUtils.rm_rf(build_dir)
@@ -67,7 +70,12 @@ module RubyMdSsg
67
70
 
68
71
  def render_document(document, menu)
69
72
  html_body = markdown.render(document.body_markdown)
70
- page = layout.render(document: document, body_html: html_body, menu: menu)
73
+ page = layout.render(
74
+ document: document,
75
+ body_html: html_body,
76
+ menu: menu,
77
+ base_path: normalized_base_path
78
+ )
71
79
  page = html_formatter.format(page)
72
80
  output_path = document.output_path
73
81
  FileUtils.mkdir_p(File.dirname(output_path))
@@ -106,10 +114,39 @@ module RubyMdSsg
106
114
 
107
115
  def sitemap_location_for(route)
108
116
  normalized_route = route == '/' ? '/' : route
109
- return normalized_route if base_url.nil? || base_url.empty?
117
+ return route_with_base_path(route) if base_url.nil? || base_url.empty?
110
118
 
111
119
  normalized_base = base_url.end_with?('/') ? base_url.chomp('/') : base_url
112
120
  normalized_base + normalized_route
113
121
  end
122
+
123
+ def route_with_base_path(route)
124
+ return '/' if normalized_base_path.empty? && (route.nil? || route == '/')
125
+ return normalized_base_path if !normalized_base_path.empty? && (route.nil? || route == '/')
126
+
127
+ tail = route.delete_prefix('/')
128
+ normalized_base_path.empty? ? "/#{tail}" : "#{normalized_base_path}/#{tail}"
129
+ end
130
+
131
+ def derive_base_path_from_base_url(url)
132
+ return nil if url.nil? || url.empty?
133
+
134
+ uri = URI.parse(url)
135
+ path = uri.path
136
+ path == '/' ? nil : path
137
+ rescue URI::InvalidURIError
138
+ nil
139
+ end
140
+
141
+ def normalized_base_path
142
+ @normalized_base_path ||= normalize_base_path(base_path)
143
+ end
144
+
145
+ def normalize_base_path(path)
146
+ return '' if path.nil? || path.empty? || path == '/'
147
+
148
+ normalized = path.start_with?('/') ? path : "/#{path}"
149
+ normalized.chomp('/')
150
+ end
114
151
  end
115
152
  end
@@ -9,12 +9,13 @@ module RubyMdSsg
9
9
  @template_path = template_path
10
10
  end
11
11
 
12
- def render(document:, body_html:, menu:)
12
+ def render(document:, body_html:, menu:, base_path: '')
13
13
  template.result_with_hash(
14
14
  title: document.title,
15
15
  body_html: body_html,
16
16
  menu: menu,
17
- meta_description: document.meta_description
17
+ meta_description: document.meta_description,
18
+ helpers: TemplateHelpers.new(base_path)
18
19
  )
19
20
  end
20
21
 
@@ -29,5 +30,48 @@ module RubyMdSsg
29
30
  def default_template_path
30
31
  File.join(Paths.root, 'templates', 'layout.html.erb')
31
32
  end
33
+
34
+ class TemplateHelpers
35
+ def initialize(base_path)
36
+ @base_path = normalize_base_path(base_path)
37
+ end
38
+
39
+ def asset_path(filename)
40
+ build_path('assets', filename)
41
+ end
42
+
43
+ def route_path(route)
44
+ return base_path if base_path? && root_route?(route)
45
+ return '/' if root_route?(route)
46
+
47
+ build_path(route.delete_prefix('/'))
48
+ end
49
+
50
+ private
51
+
52
+ attr_reader :base_path
53
+
54
+ def base_path?
55
+ !base_path.empty?
56
+ end
57
+
58
+ def normalize_base_path(path)
59
+ return '' if path.nil? || path.empty? || path == '/'
60
+
61
+ normalized = path.start_with?('/') ? path : "/#{path}"
62
+ normalized.chomp('/')
63
+ end
64
+
65
+ def build_path(*segments)
66
+ tail = segments.join('/').sub(%r{^/+}, '')
67
+ return "/#{tail}" unless base_path?
68
+
69
+ "#{base_path}/#{tail}"
70
+ end
71
+
72
+ def root_route?(route)
73
+ route.nil? || route == '/'
74
+ end
75
+ end
32
76
  end
33
77
  end
@@ -22,7 +22,8 @@ module RubyMdSsg
22
22
  auto_build: true,
23
23
  watch: true,
24
24
  interval: 1.0,
25
- base_url: ENV.fetch('RUBY_MD_SSG_BASE_URL', nil)
25
+ base_url: ENV.fetch('RUBY_MD_SSG_BASE_URL', nil),
26
+ base_path: ENV.fetch('RUBY_MD_SSG_BASE_PATH', nil)
26
27
  }
27
28
  end
28
29
  end
@@ -51,7 +52,8 @@ module RubyMdSsg
51
52
  build_dir: options[:build],
52
53
  assets_dir: options[:assets],
53
54
  menu_path: options[:menu],
54
- base_url: options[:base_url]
55
+ base_url: options[:base_url],
56
+ base_path: options[:base_path]
55
57
  )
56
58
  compiler.compile
57
59
  puts "[#{timestamp}] Build complete."
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyMdSsg
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
@@ -10,6 +10,7 @@ Generated by Ruby MD SSG <%= gem_version %>.
10
10
  - `bundle exec ruby_md_ssg test` — run the Minitest suite (if present)
11
11
 
12
12
  Set `RUBY_MD_SSG_BASE_URL` (or pass `--base-url`) when building to control sitemap URLs.
13
+ Set `RUBY_MD_SSG_BASE_PATH` (or pass `--base-path`) when deploying under a subdirectory (e.g., GitHub Pages project sites).
13
14
 
14
15
  Docs live in `docs/`, assets in `assets/`, templates in `templates/`.
15
16
 
@@ -7,8 +7,8 @@
7
7
  <% if meta_description && !meta_description.empty? %>
8
8
  <meta name="description" content="<%= meta_description %>" />
9
9
  <% end %>
10
- <link rel="stylesheet" href="/assets/style.css" />
11
- <script defer src="/assets/app.js"></script>
10
+ <link rel="stylesheet" href="<%= helpers.asset_path('style.css') %>" />
11
+ <script defer src="<%= helpers.asset_path('app.js') %>"></script>
12
12
  </head>
13
13
  <body>
14
14
  <div class="layout">
@@ -24,7 +24,7 @@
24
24
  <ul>
25
25
  <% section.links.each do |link| %>
26
26
  <li>
27
- <a href="<%= link.route %>"><%= link.label %></a>
27
+ <a href="<%= helpers.route_path(link.route) %>"><%= link.label %></a>
28
28
  </li>
29
29
  <% end %>
30
30
  </ul>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-md-ssg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruby MD SSG Maintainers