Class: BBK::Utils::Cli::Docs::Markdown

Inherits:
Object
  • Object
show all
Defined in:
lib/bbk/utils/cli/docs/markdown.rb

Overview

Класс для генерации документации в формате Markdown

Создает таблицы с переменными окружения, параметрами конфигурации и т.д. Поддерживает настраиваемые колонки, выравнивание, обрамление значений и предупреждения в двух режимах: сноски или встроенные

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Markdown

Инициализирует генератор Markdown

Parameters:

  • opts (Hash) (defaults to: {})

    опции генерации

Options Hash (opts):

  • :columns (Hash)

    отображаемые колонки с заголовками

  • :alignments (Hash)

    выравнивание для каждой колонки

  • :wrappers (Hash)

    обрамление значений колонок

  • :title_level (Integer)

    уровень заголовка (1-6)

  • :warning (Hash)

    настройки вывода предупреждений



38
39
40
# File 'lib/bbk/utils/cli/docs/markdown.rb', line 38

def initialize(opts = {})
  @opts = opts
end

Instance Attribute Details

#optsObject (readonly)

Генерация markdown-документации для категории category_data = {

category_data: {
},
env_vars: category.env_vars

}

options =

columns: { env: "Название",
alignments: { 1 => :center, 3 => :center }, # :left, :right, :center для каждой колонки
wrappers: { 1 => "`", 3 => "`" }, # wrappers - символ или строка для обрамления значений колонки, например: "`", "```", "**"
title_level: 4, # уровень заголовка от 1 до 6
warning: {
  column_index: 3, # индекс колонки для вывода предупреждений
  mode: :footnote # или :inline
}

}



28
29
30
# File 'lib/bbk/utils/cli/docs/markdown.rb', line 28

def opts
  @opts
end

Instance Method Details

#generate(category) ⇒ String

Генерирует markdown-документацию для заданной категории

Parameters:

  • category (Docs::Builder::Category)

    категория конфигурации

Returns:

  • (String)

    markdown-разметка документации



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/bbk/utils/cli/docs/markdown.rb', line 46

def generate(category)
  # Соберем заголовок
  level = opts[:title_level].clamp(1, 6)
  title = "#{'#' * level} (#{category.id}) #{category.name}"
  desc = category.desc.to_s

  # Конвертируем данные в формат для таблицы
  rows, footnotes = generate_rows(category, opts)
  # Создаем таблицу с заголовком и описанием

  table = generate_table(opts[:columns].values, opts[:alignments], rows)
  [
    title,
    '',
    desc,
    '',
    *table,
    '',
    *footnotes
  ].join("\n")
end

#generate_rows(category, opts) ⇒ Array

Генерирует строки для таблицы документации

Parameters:

  • category (Docs::Builder::Category)

    категория конфигурации

  • opts (Hash)

    опции генерации

Returns:

  • (Array)

    массив строк и сносок



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/bbk/utils/cli/docs/markdown.rb', line 73

def generate_rows(category, opts)
  # извлекаем даныне
  rows = category.cfgs.map do |cfg|
    opts[:columns].keys.each_with_object([]) do |key, row|
      row << cfg[key.to_sym]
    end
  end

  # Применяем обрамление к значениям
  rows = wrap_row_values(rows, opts[:wrappers])

  # Применяем форматирование предупреждений
  rows, footnotes = process_warnings(rows, category, opts[:warning])

  [rows, footnotes]
end

#generate_table(headers = [], alignments = {}, rows) ⇒ Array<String>

Генерирует таблицу в формате Markdown

Parameters:

  • headers (Array<String>) (defaults to: [])

    заголовки колонок

  • alignments (Hash) (defaults to: {})

    выравнивание для каждой колонки

  • rows (Array<Array>)

    строки данных таблицы

Returns:

  • (Array<String>)

    массив строк markdown-таблицы



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/bbk/utils/cli/docs/markdown.rb', line 155

def generate_table(headers = [], alignments = {}, rows)
  # Вычисляем ширину колонок
  column_widths = if headers.any?
                    headers.map(&:size)
                  else
                    Array.new(rows[0].count, 0)
                  end

  rows.each do |row|
    row.each_with_index do |data, i|
      column_widths[i] = data.to_s.size if data.to_s.size > column_widths[i]
    end
  end

  # Создаем заголовок таблицы
  if headers.any?
    header_string = '|'
    separator_string = '|'

    headers.each_with_index do |header, col|
      header_string += " #{header.ljust(column_widths[col])} |"

      # Создаем разделитель с учетом выравнивания
      separator_string += case alignments[col]
                          when :right
                            "#{'-' * (column_widths[col] + 1)}:|"
                          when :center
                            if column_widths[col] >= 1
                              ":#{'-' * column_widths[col]}:|"
                            else
                              '::|'
                            end
                          when :left
                            ":#{'-' * (column_widths[col] + 1)}|"
                          else
                            "#{'-' * (column_widths[col] + 2)}|"
                          end
    end

  end

  # Создаем строки данных
  lines = rows.map do |row|
    line = row.each_with_index.map do |value, col|
      value.to_s.ljust(column_widths[col])
    end.join(' | ')

    "| #{line} |"
  end

  [
    header_string,
    separator_string,
    *lines
  ]
end

#process_warnings(rows, category, warning_opts) ⇒ Array

Обрабатывает предупреждения для строк таблицы

Parameters:

  • rows (Array<Array>)

    строки таблицы

  • category (Docs::Builder::Category)

    категория конфигурации

  • warning_opts (Hash)

    опции обработки предупреждений

Options Hash (warning_opts):

  • :column_index (Integer)

    индекс колонки для предупреждений

  • :mode (Symbol)

    режим вывода (:footnote или :inline)

Returns:

  • (Array)

    кортеж из обработанных строк и массива сносок



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/bbk/utils/cli/docs/markdown.rb', line 118

def process_warnings(rows, category, warning_opts)
  return [rows, []] if !warning_opts || !warning_opts[:column_index]

  column_index = warning_opts[:column_index]
  mode = warning_opts[:mode] || :footnote
  footnotes = []
  footnote_counter = 1

  processed_rows = rows.each_with_index.map do |row, row_index|
    cfg = category.cfgs[row_index]
    warning = cfg[:warning]

    if warning && !warning.empty?
      case mode
      when :footnote
        # Добавляем номер сноски
        id = "#{category.id}_#{footnote_counter}"
        row[column_index] = "#{row[column_index]} [^#{id}]"
        footnotes << "[^#{id}]: #{warning}"
        footnote_counter += 1
      when :inline
        # Добавляем предупреждение жирным текстом с переносом строки
        row[column_index] = "#{row[column_index]}<br>⚠️ **#{warning}**"
      end
    end
    row
  end

  [processed_rows, footnotes]
end

#wrap_row_values(rows, wrappers) ⇒ Array<Array>

Применяет обрамление к значениям в строках таблицы

Parameters:

  • rows (Array<Array>)

    строки таблицы

  • wrappers (Hash)

    хеш обрамления по индексам колонок

Returns:

  • (Array<Array>)

    строки с обрамленными значениями



95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/bbk/utils/cli/docs/markdown.rb', line 95

def wrap_row_values(rows, wrappers)
  return rows if wrappers.empty?

  rows.map do |row|
    row.each_with_index.map do |value, index|
      wrapper = wrappers[index]
      if wrapper && !value.nil? # может быть пустым
        "#{wrapper}#{value}#{wrapper}"
      else
        value
      end
    end
  end
end