diff --git a/lib/gitlab/help/hugo_transformer.rb b/lib/gitlab/help/hugo_transformer.rb index bebdf3ea9a24d7367dc6319dd39e97354ec5ef08..ed3105a8547120acb3bc2b74e3c95948acd0d124 100644 --- a/lib/gitlab/help/hugo_transformer.rb +++ b/lib/gitlab/help/hugo_transformer.rb @@ -27,7 +27,16 @@ class HugoTransformer HISTORY_PATTERN = %r{\{\{<\s*history\s*>\}\}(.*?)\{\{<\s*/history\s*>\}\}}m MAINTAINED_VERSIONS_PATTERN = %r{\{\{<\s*maintained-versions\s*/?\s*>\}\}} COLLAPSIBLE_PATTERN = %r{\{\{<\s*collapsible\s+title="([^"]+)"\s*>\}\}(.*?)\{\{<\s*/collapsible\s*>\}\}}m - + # Patterns for Hugo attributes + TABLE_ATTRIBUTE_PATTERN = %r{ + \{ + (?: + \.[\w-]+(?:\s+\.[\w-]+)* + | + class=["'][\w-]+(?:\s+[\w-]+)*["'] + ) + \} + }x # Markdown heading constants HEADING_PATTERN = /^(\#{1,6})\s+[^\n]+$/m MAX_HEADING_LEVEL = 6 # Represents an h6 @@ -52,6 +61,7 @@ def transform(content) handle_maintained_versions_shortcodes(processed_content) handle_collapsible_shortcodes(processed_content) remove_generic_shortcodes(processed_content) + remove_table_attributes(processed_content) clean_up_blank_lines(processed_content) # Restore code blocks @@ -171,6 +181,11 @@ def remove_generic_shortcodes(content) content end + def remove_table_attributes(content) + content.gsub!(TABLE_ATTRIBUTE_PATTERN, '') + content + end + def clean_up_blank_lines(content) content.gsub!(/\n{3,}/, "\n\n") content diff --git a/spec/lib/gitlab/help/hugo_transformer_spec.rb b/spec/lib/gitlab/help/hugo_transformer_spec.rb index 18390739cc1e6c1e7f7f36516f682a6634eeaa89..c1f0647b40b818cb67bb20a44826d9a067df09aa 100644 --- a/spec/lib/gitlab/help/hugo_transformer_spec.rb +++ b/spec/lib/gitlab/help/hugo_transformer_spec.rb @@ -2,9 +2,7 @@ require 'spec_helper' -# rubocop:disable RSpec/FeatureCategory -- Help pages are not part of a feature category. This feature is supported by the Technical Writing team. -RSpec.describe Gitlab::Help::HugoTransformer do - # rubocop:enable RSpec/FeatureCategory +RSpec.describe Gitlab::Help::HugoTransformer, feature_category: :gitlab_docs do describe '#transform' do let(:transformer) { described_class.new } @@ -518,6 +516,102 @@ expect(transformer.transform(content).strip).to eq(expected_content.strip) end + it 'handles table attributes by removing them from the content' do + content = <<~MARKDOWN + # Documentation + Here is a table: + | Header 1 | Header 2 | + |----------|----------| + | Cell 1 | Cell 2 | + {.expandable} + MARKDOWN + expected_content = <<~MARKDOWN + # Documentation + Here is a table: + | Header 1 | Header 2 | + |----------|----------| + | Cell 1 | Cell 2 | + MARKDOWN + + expect(transformer.transform(content).strip).to eq(expected_content.strip) + end + + it 'handles table attributes in long format by removing them from the content' do + content = <<~MARKDOWN + # Documentation + Here is a table: + | Header 1 | Header 2 | + |----------|----------| + | Cell 1 | Cell 2 | + {class="expandable"} + MARKDOWN + expected_content = <<~MARKDOWN + # Documentation + Here is a table: + | Header 1 | Header 2 | + |----------|----------| + | Cell 1 | Cell 2 | + MARKDOWN + + expect(transformer.transform(content).strip).to eq(expected_content.strip) + end + + it 'handles multiple table attributes by removing them from the content' do + content = <<~MARKDOWN + # Documentation + Here is a table: + | Header 1 | Header 2 | + |----------|----------| + | Cell 1 | Cell 2 | + {.something-dashed .word .another} + MARKDOWN + expected_content = <<~MARKDOWN + # Documentation + Here is a table: + | Header 1 | Header 2 | + |----------|----------| + | Cell 1 | Cell 2 | + MARKDOWN + + expect(transformer.transform(content).strip).to eq(expected_content.strip) + end + + it 'handles multiple table attributes in long format by removing them from the content' do + content = <<~MARKDOWN + # Documentation + Here is a table: + | Header 1 | Header 2 | + |----------|----------| + | Cell 1 | Cell 2 | + {class="expandable condensed"} + MARKDOWN + expected_content = <<~MARKDOWN + # Documentation + Here is a table: + | Header 1 | Header 2 | + |----------|----------| + | Cell 1 | Cell 2 | + MARKDOWN + + expect(transformer.transform(content).strip).to eq(expected_content.strip) + end + + it 'does not transform content in code blocks' do + content = <<~MARKDOWN + ```shell + {range .env[*]}{.name}{","}{end}{"\n"}{end} + ``` + MARKDOWN + + expected_content = <<~MARKDOWN + ```shell + {range .env[*]}{.name}{","}{end}{"\n"}{end} + ``` + MARKDOWN + + expect(transformer.transform(content).strip).to eq(expected_content.strip) + end + describe '#find_next_heading_level' do it 'returns level 2 when no previous headings exist' do content = "Some content without headings"