Class: Markdowndocs::Documentation

Inherits:
Object
  • Object
show all
Defined in:
app/models/markdowndocs/documentation.rb

Overview

Documentation PORO (Plain Old Ruby Object) Represents markdown documentation files from a configurable directory. Handles metadata extraction, frontmatter parsing, and category associations.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file_path) ⇒ Documentation

Returns a new instance of Documentation.



10
11
12
13
14
15
# File 'app/models/markdowndocs/documentation.rb', line 10

def initialize(file_path)
  @file_path = file_path
  @slug = derive_slug
  
  @category = assign_category
end

Instance Attribute Details

#categoryObject (readonly)

Returns the value of attribute category.



8
9
10
# File 'app/models/markdowndocs/documentation.rb', line 8

def category
  @category
end

#descriptionObject (readonly)

Returns the value of attribute description.



8
9
10
# File 'app/models/markdowndocs/documentation.rb', line 8

def description
  @description
end

#file_pathObject (readonly)

Returns the value of attribute file_path.



8
9
10
# File 'app/models/markdowndocs/documentation.rb', line 8

def file_path
  @file_path
end

#keywordsObject (readonly)

Returns the value of attribute keywords.



8
9
10
# File 'app/models/markdowndocs/documentation.rb', line 8

def keywords
  @keywords
end

#slugObject (readonly)

Returns the value of attribute slug.



8
9
10
# File 'app/models/markdowndocs/documentation.rb', line 8

def slug
  @slug
end

#titleObject (readonly)

Returns the value of attribute title.



8
9
10
# File 'app/models/markdowndocs/documentation.rb', line 8

def title
  @title
end

Class Method Details

.allObject



17
18
19
20
21
22
23
24
# File 'app/models/markdowndocs/documentation.rb', line 17

def self.all
  docs_path = Markdowndocs.config.resolved_docs_path
  return [] unless docs_path.exist?

  Dir.glob(docs_path.join("*.md")).map do |file|
    new(Pathname.new(file))
  end.sort_by(&:slug)
end

.by_category(category) ⇒ Object



39
40
41
# File 'app/models/markdowndocs/documentation.rb', line 39

def self.by_category(category)
  all.select { |doc| doc.category == category }
end

.find_by_slug(slug) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
# File 'app/models/markdowndocs/documentation.rb', line 26

def self.find_by_slug(slug)
  return nil if slug.blank?
  return nil if slug.include?("..") || slug.include?("/")

  file_path = Markdowndocs.config.resolved_docs_path.join("#{slug}.md")
  return nil unless file_path.exist?

  new(file_path)
rescue => e
  Rails.logger.error("Error finding documentation by slug '#{slug}': #{e.message}")
  nil
end

.grouped_by_categoryObject



43
44
45
46
47
# File 'app/models/markdowndocs/documentation.rb', line 43

def self.grouped_by_category
  Markdowndocs.config.categories.each_with_object({}) do |(category, slugs), hash|
    hash[category] = slugs.map { |slug| find_by_slug(slug) }.compact
  end
end

Instance Method Details

#available_modesObject



66
67
68
69
70
71
72
# File 'app/models/markdowndocs/documentation.rb', line 66

def available_modes
  @available_modes ||= begin
    parsed = parse_frontmatter
    modes = parsed[:frontmatter]["modes"]
    modes.is_a?(Array) ? modes.map(&:to_s) : Markdowndocs.config.modes.dup
  end
end

#cache_keyObject



56
57
58
# File 'app/models/markdowndocs/documentation.rb', line 56

def cache_key
  "#{slug}-#{mtime.to_i}"
end

#code_contentObject

Returns text extracted from fenced code blocks for search indexing.



102
103
104
105
106
# File 'app/models/markdowndocs/documentation.rb', line 102

def code_content
  parsed = parse_frontmatter
  blocks = parsed[:markdown].scan(/```\w*\n([\s\S]*?)```/)
  blocks.flatten.join(" ").gsub(/\s+/, " ").strip
end

#contentObject



49
50
51
52
53
54
# File 'app/models/markdowndocs/documentation.rb', line 49

def content
  @content ||= file_path.read
rescue => e
  Rails.logger.error("Error reading documentation file '#{file_path}': #{e.message}")
  ""
end

#default_modeObject



74
75
76
77
78
79
80
# File 'app/models/markdowndocs/documentation.rb', line 74

def default_mode
  @default_mode ||= begin
    parsed = parse_frontmatter
    mode = parsed[:frontmatter]["default_mode"]
    mode.present? ? mode.to_s : Markdowndocs.config.default_mode
  end
end

#mtimeObject



60
61
62
63
64
# File 'app/models/markdowndocs/documentation.rb', line 60

def mtime
  @mtime ||= file_path.mtime
rescue
  Time.current
end

#plain_text_contentObject

Returns content stripped of frontmatter, markdown syntax, and HTML tags for use in search indexing.



88
89
90
91
92
93
94
95
96
97
98
99
# File 'app/models/markdowndocs/documentation.rb', line 88

def plain_text_content
  parsed = parse_frontmatter
  text = parsed[:markdown]
  text = text.gsub(/^#+\s*/, "")          # headings
  text = text.gsub(/\[([^\]]+)\]\([^)]+\)/, '\1') # links
  text = text.gsub(/[*_~`]/, "")          # emphasis markers
  text = text.gsub(/```[\s\S]*?```/, "")  # fenced code blocks
  text = text.gsub(/<[^>]+>/, "")         # HTML tags
  text = text.gsub(/^\s*[-*+]\s/, "")     # list markers
  text = text.gsub(/\n{2,}/, "\n")        # collapse blank lines
  text.strip
end

#supports_mode?(mode) ⇒ Boolean

Returns:

  • (Boolean)


82
83
84
# File 'app/models/markdowndocs/documentation.rb', line 82

def supports_mode?(mode)
  available_modes.include?(mode.to_s)
end