markdowndocs 0.8.0 → 0.10.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.
data/config/routes.rb CHANGED
@@ -7,12 +7,15 @@ Markdowndocs::Engine.routes.draw do
7
7
  # Mode-scoped doc route: matches /<mode>/<slug> where <mode> is one of
8
8
  # the configured modes. Must come BEFORE the unconstrained :slug route
9
9
  # so the more specific match wins.
10
- mode_constraint = if Markdowndocs.config.modes.any?
11
- Regexp.new("(?:#{Markdowndocs.config.modes.map { |m| Regexp.escape(m) }.join("|")})")
12
- else
13
- /impossible/
10
+ #
11
+ # The constraint reads live config so dev-reload edits to config.modes
12
+ # take effect without a full server restart. Proc constraints apply only
13
+ # to request recognition; URL generation remains permissive.
14
+ mode_constraint = lambda do |request|
15
+ mode = request.path_parameters[:mode]
16
+ Array(Markdowndocs.config.modes).include?(mode)
14
17
  end
15
- get ":mode/:slug", to: "docs#show", as: :scoped_doc, constraints: {mode: mode_constraint}
18
+ get ":mode/:slug", to: "docs#show", as: :scoped_doc, constraints: mode_constraint
16
19
 
17
20
  get ":slug", to: "docs#show", as: :doc
18
21
  resource :preference, only: [:update]
@@ -5,14 +5,27 @@ Markdowndocs.configure do |config|
5
5
  # config.docs_path = Rails.root.join("app", "docs")
6
6
 
7
7
  # Category → slug mapping
8
- # Maps category names to arrays of markdown file slugs (filenames without .md)
8
+ # Maps category names to arrays of markdown file slugs (filenames without .md).
9
+ # Bare slugs ("welcome") match files at app/docs/. Path-prefixed slugs
10
+ # ("technical/architecture") match files in mode subdirectories — see modes
11
+ # below.
9
12
  config.categories = {
10
13
  # "Getting Started" => %w[introduction quickstart],
11
14
  # "Guides" => %w[authentication deployment],
12
- # "Reference" => %w[api-reference configuration]
15
+ # "Reference" => %w[api-reference technical/architecture]
13
16
  }
14
17
 
15
18
  # Available documentation modes (default: %w[guide technical])
19
+ #
20
+ # Each entry in `modes` also doubles as a path-based audience scope: files
21
+ # under `app/docs/<mode>/` are visible ONLY in that mode and served at
22
+ # `/docs/<mode>/<slug>`. Files at the docs root are shared across all modes.
23
+ #
24
+ # app/docs/
25
+ # ├── welcome.md → shared, visible in every mode
26
+ # └── technical/
27
+ # └── architecture.md → technical mode only
28
+ #
16
29
  # config.modes = %w[guide technical]
17
30
 
18
31
  # Default mode (default: "guide")
@@ -28,6 +41,11 @@ Markdowndocs.configure do |config|
28
41
  # Adds a search bar that filters docs by title, description, and content
29
42
  # config.search_enabled = true
30
43
 
44
+ # Allow a curated, safe subset of inline SVG for hand-authored diagrams
45
+ # (default: false). Scripts, event handlers, and javascript: URIs are
46
+ # always stripped by the sanitizer regardless of this setting.
47
+ # config.allow_svg = true
48
+
31
49
  # Optional: Resolve current user's mode preference from database
32
50
  # Return nil to fall back to cookie/default
33
51
  # config.user_mode_resolver = ->(controller) {
@@ -2,16 +2,24 @@
2
2
 
3
3
  module Markdowndocs
4
4
  class Configuration
5
- attr_accessor :docs_path, :categories, :modes, :default_mode,
5
+ # Route segments owned by the engine itself. A mode name matching any
6
+ # of these would collide with built-in routes / controller actions.
7
+ RESERVED_MODE_NAMES = %w[search_index preference preferences].freeze
8
+
9
+ attr_accessor :docs_path, :categories, :default_mode,
6
10
  :markdown_options, :rouge_theme, :cache_expiry,
7
11
  :user_mode_resolver, :user_mode_saver, :search_enabled,
8
12
  :layout, :allow_svg
9
- attr_reader :non_mode_subdirs_warned, :audience_deprecation_emitted
13
+ attr_reader :modes, :non_mode_subdirs_warned, :audience_deprecation_emitted
14
+
15
+ def modes=(value)
16
+ @modes = normalize_modes(value)
17
+ end
10
18
 
11
19
  def initialize
12
20
  @docs_path = nil # Resolved lazily so Rails.root is available
13
21
  @categories = {}
14
- @modes = %w[guide technical]
22
+ self.modes = %w[guide technical]
15
23
  @default_mode = "guide"
16
24
  @markdown_options = default_markdown_options
17
25
  @rouge_theme = "github"
@@ -36,6 +44,38 @@ module Markdowndocs
36
44
 
37
45
  private
38
46
 
47
+ def normalize_modes(value)
48
+ list = Array(value).map do |entry|
49
+ unless entry.is_a?(String)
50
+ raise ArgumentError,
51
+ "config.modes entries must be strings; got #{entry.inspect}"
52
+ end
53
+
54
+ name = entry.strip
55
+
56
+ if name.empty?
57
+ raise ArgumentError, "config.modes contains an invalid empty entry"
58
+ end
59
+
60
+ if name.match?(%r{[/?#&\s]})
61
+ raise ArgumentError,
62
+ "config.modes entry #{entry.inspect} is invalid — names cannot contain " \
63
+ "path separators, URL-significant characters, or whitespace"
64
+ end
65
+
66
+ if RESERVED_MODE_NAMES.include?(name)
67
+ raise ArgumentError,
68
+ "config.modes entry #{name.inspect} is reserved by the engine " \
69
+ "(conflicts with built-in route or controller). " \
70
+ "Reserved names: #{RESERVED_MODE_NAMES.join(", ")}"
71
+ end
72
+
73
+ name
74
+ end
75
+
76
+ list.uniq
77
+ end
78
+
39
79
  def default_markdown_options
40
80
  {
41
81
  parse: {
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Markdowndocs
4
- VERSION = "0.8.0"
4
+ VERSION = "0.10.0"
5
5
  end
data/mise.toml ADDED
@@ -0,0 +1,2 @@
1
+ [tools]
2
+ ruby = "3.4.6"
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markdowndocs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dave Chmura
8
+ autorequire:
8
9
  bindir: exe
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2026-06-24 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: rails
@@ -74,6 +75,7 @@ executables: []
74
75
  extensions: []
75
76
  extra_rdoc_files: []
76
77
  files:
78
+ - ".tool-versions"
77
79
  - CHANGELOG.md
78
80
  - README.md
79
81
  - Rakefile
@@ -90,6 +92,7 @@ files:
90
92
  - app/views/layouts/markdowndocs/application.html.erb
91
93
  - app/views/markdowndocs/docs/_breadcrumb.html.erb
92
94
  - app/views/markdowndocs/docs/_card.html.erb
95
+ - app/views/markdowndocs/docs/_docs_toolbar.html.erb
93
96
  - app/views/markdowndocs/docs/_mode_switcher.html.erb
94
97
  - app/views/markdowndocs/docs/_navigation.html.erb
95
98
  - app/views/markdowndocs/docs/index.html.erb
@@ -97,15 +100,13 @@ files:
97
100
  - config/importmap.rb
98
101
  - config/locales/en.yml
99
102
  - config/routes.rb
100
- - docs/superpowers/plans/2026-05-15-path-based-audience-routing.md
101
- - docs/superpowers/specs/2026-05-15-path-based-audience-routing-design.md
102
103
  - lib/generators/markdowndocs/install/install_generator.rb
103
104
  - lib/generators/markdowndocs/install/templates/initializer.rb
104
105
  - lib/markdowndocs.rb
105
106
  - lib/markdowndocs/configuration.rb
106
107
  - lib/markdowndocs/engine.rb
107
108
  - lib/markdowndocs/version.rb
108
- - log/test.log
109
+ - mise.toml
109
110
  - sig/markdowndocs.rbs
110
111
  homepage: https://github.com/dschmura/markdowndocs
111
112
  licenses:
@@ -114,6 +115,7 @@ metadata:
114
115
  homepage_uri: https://github.com/dschmura/markdowndocs
115
116
  source_code_uri: https://github.com/dschmura/markdowndocs
116
117
  changelog_uri: https://github.com/dschmura/markdowndocs/blob/main/CHANGELOG.md
118
+ post_install_message:
117
119
  rdoc_options: []
118
120
  require_paths:
119
121
  - lib
@@ -128,7 +130,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
130
  - !ruby/object:Gem::Version
129
131
  version: '0'
130
132
  requirements: []
131
- rubygems_version: 3.6.9
133
+ rubygems_version: 3.4.19
134
+ signing_key:
132
135
  specification_version: 4
133
136
  summary: A drop-in markdown documentation site for Rails apps
134
137
  test_files: []