govuk_tech_docs 1.5.0 → 1.6.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 +4 -4
 - data/.rubocop.yml +3 -0
 - data/CHANGELOG.md +90 -0
 - data/docs/configuration.md +15 -0
 - data/docs/frontmatter.md +2 -14
 - data/docs/page-expiry.md +69 -0
 - data/example/Gemfile +1 -0
 - data/example/config/tech-docs.yml +6 -0
 - data/example/source/api-path.html.md +7 -0
 - data/example/source/api-reference.html.md +5 -0
 - data/example/source/pets.yml +106 -0
 - data/govuk_tech_docs.gemspec +2 -0
 - data/lib/assets/javascripts/_analytics.js +12 -0
 - data/lib/assets/javascripts/_modules/collapsible-navigation.js +5 -3
 - data/lib/assets/javascripts/_modules/search.js +175 -6
 - data/lib/assets/stylesheets/modules/_collapsible.scss +12 -5
 - data/lib/assets/stylesheets/modules/_technical-documentation.scss +16 -11
 - data/lib/assets/stylesheets/modules/_toc.scss +1 -1
 - data/lib/govuk_tech_docs.rb +13 -2
 - data/lib/govuk_tech_docs/api_reference/api_reference_extension.rb +100 -0
 - data/lib/govuk_tech_docs/api_reference/api_reference_renderer.rb +279 -0
 - data/lib/govuk_tech_docs/api_reference/templates/api_reference_full.html.erb +9 -0
 - data/lib/govuk_tech_docs/api_reference/templates/operation.html.erb +11 -0
 - data/lib/govuk_tech_docs/api_reference/templates/parameters.html.erb +28 -0
 - data/lib/govuk_tech_docs/api_reference/templates/path.html.erb +4 -0
 - data/lib/govuk_tech_docs/api_reference/templates/responses.html.erb +33 -0
 - data/lib/govuk_tech_docs/api_reference/templates/schema.html.erb +29 -0
 - data/lib/govuk_tech_docs/page_review.rb +15 -3
 - data/lib/govuk_tech_docs/pages.rb +3 -2
 - data/lib/govuk_tech_docs/tech_docs_html_renderer.rb +10 -0
 - data/lib/govuk_tech_docs/version.rb +1 -1
 - data/lib/source/layouts/_header.erb +2 -4
 - metadata +42 -4
 - data/lib/source/images/arrow-down.svg +0 -9
 - data/lib/source/images/arrow-up.svg +0 -9
 
| 
         @@ -11,6 +11,10 @@ 
     | 
|
| 
       11 
11 
     | 
    
         
             
                display: block
         
     | 
| 
       12 
12 
     | 
    
         
             
              }
         
     | 
| 
       13 
13 
     | 
    
         
             
            }
         
     | 
| 
      
 14 
     | 
    
         
            +
            .collapsible__heading,
         
     | 
| 
      
 15 
     | 
    
         
            +
            .toc__list > ul > li > a:link.collapsible__heading {
         
     | 
| 
      
 16 
     | 
    
         
            +
              margin-right: 30px;
         
     | 
| 
      
 17 
     | 
    
         
            +
            }
         
     | 
| 
       14 
18 
     | 
    
         
             
            .collapsible__toggle {
         
     | 
| 
       15 
19 
     | 
    
         
             
              position: absolute;
         
     | 
| 
       16 
20 
     | 
    
         
             
              top: 0;
         
     | 
| 
         @@ -34,12 +38,15 @@ 
     | 
|
| 
       34 
38 
     | 
    
         
             
              &::after {
         
     | 
| 
       35 
39 
     | 
    
         
             
                content: '';
         
     | 
| 
       36 
40 
     | 
    
         
             
                display: block;
         
     | 
| 
       37 
     | 
    
         
            -
                 
     | 
| 
       38 
     | 
    
         
            -
                 
     | 
| 
       39 
     | 
    
         
            -
                 
     | 
| 
       40 
     | 
    
         
            -
                 
     | 
| 
      
 41 
     | 
    
         
            +
                border: 2px solid $black;
         
     | 
| 
      
 42 
     | 
    
         
            +
                border-width: 2px 2px 0 0;
         
     | 
| 
      
 43 
     | 
    
         
            +
                transform: rotate(135deg);
         
     | 
| 
      
 44 
     | 
    
         
            +
                width: 10px;
         
     | 
| 
      
 45 
     | 
    
         
            +
                height: 10px;
         
     | 
| 
      
 46 
     | 
    
         
            +
                margin-top: 10px;
         
     | 
| 
       41 
47 
     | 
    
         
             
              }
         
     | 
| 
       42 
48 
     | 
    
         
             
              .collapsible.is-open &::after {
         
     | 
| 
       43 
     | 
    
         
            -
                 
     | 
| 
      
 49 
     | 
    
         
            +
                transform: rotate(315deg);
         
     | 
| 
      
 50 
     | 
    
         
            +
                margin-top: 18px;
         
     | 
| 
       44 
51 
     | 
    
         
             
              }
         
     | 
| 
       45 
52 
     | 
    
         
             
            }
         
     | 
| 
         @@ -3,11 +3,11 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            @mixin heading-offset($tabletTopMargin) {
         
     | 
| 
       4 
4 
     | 
    
         
             
              // Scale margins with font size on mobile (16/19ths)
         
     | 
| 
       5 
5 
     | 
    
         
             
              $mobileTopMargin: ceil($tabletTopMargin * (16 / 19));
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
       7 
7 
     | 
    
         
             
              // Offset headings down on mobile so that linking to anchors they appear after
         
     | 
| 
       8 
8 
     | 
    
         
             
              // the sticky 'table of contents' element
         
     | 
| 
       9 
9 
     | 
    
         
             
              $stickyTocOffset: 20px + $gutter-half + 10px + 1px;
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
       11 
11 
     | 
    
         
             
              // Pad the heading so that when linking to an anchor there is at most a
         
     | 
| 
       12 
12 
     | 
    
         
             
              // $gutter-half (mobile) or $gutter (tablet and above) sized gap between the
         
     | 
| 
       13 
13 
     | 
    
         
             
              // top of the viewport and the heading.
         
     | 
| 
         @@ -25,9 +25,9 @@ 
     | 
|
| 
       25 
25 
     | 
    
         
             
              display: block;
         
     | 
| 
       26 
26 
     | 
    
         
             
              margin: 0 $gutter-half 10px;
         
     | 
| 
       27 
27 
     | 
    
         
             
              max-width: 40em;
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
       29 
29 
     | 
    
         
             
              line-height: 1.4;
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
       31 
31 
     | 
    
         
             
              color: $text-colour;
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
       33 
33 
     | 
    
         
             
              @include media(tablet) {
         
     | 
| 
         @@ -45,14 +45,14 @@ 
     | 
|
| 
       45 
45 
     | 
    
         
             
                @include bold-48;
         
     | 
| 
       46 
46 
     | 
    
         
             
                @include heading-offset($gutter * 2);
         
     | 
| 
       47 
47 
     | 
    
         
             
                border-top: 5px solid $text-colour;
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
       49 
49 
     | 
    
         
             
                &:first-of-type {
         
     | 
| 
       50 
50 
     | 
    
         
             
                  @include heading-offset($gutter);
         
     | 
| 
       51 
51 
     | 
    
         
             
                  border-top: none;
         
     | 
| 
       52 
52 
     | 
    
         
             
                }
         
     | 
| 
       53 
53 
     | 
    
         
             
              }
         
     | 
| 
       54 
54 
     | 
    
         | 
| 
       55 
     | 
    
         
            -
              h2 { 
     | 
| 
      
 55 
     | 
    
         
            +
              h2 {
         
     | 
| 
       56 
56 
     | 
    
         
             
                @include bold-36;
         
     | 
| 
       57 
57 
     | 
    
         
             
                @include heading-offset($gutter * 1.5);
         
     | 
| 
       58 
58 
     | 
    
         
             
              }
         
     | 
| 
         @@ -125,7 +125,7 @@ 
     | 
|
| 
       125 
125 
     | 
    
         | 
| 
       126 
126 
     | 
    
         
             
              ol + p, ul + p, .table-container + p {
         
     | 
| 
       127 
127 
     | 
    
         
             
                margin-top: ceil($gutter * (16 / 19));
         
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
       129 
129 
     | 
    
         
             
                @include media(tablet) {
         
     | 
| 
       130 
130 
     | 
    
         
             
                  margin-top: $gutter;
         
     | 
| 
       131 
131 
     | 
    
         
             
                }
         
     | 
| 
         @@ -144,6 +144,11 @@ 
     | 
|
| 
       144 
144 
     | 
    
         
             
                overflow: auto;
         
     | 
| 
       145 
145 
     | 
    
         
             
                position: relative;
         
     | 
| 
       146 
146 
     | 
    
         
             
                border: 1px solid $code-02;
         
     | 
| 
      
 147 
     | 
    
         
            +
                // Restrict the width of pre tags, as they have a tendency grow larger than
         
     | 
| 
      
 148 
     | 
    
         
            +
                // the viewport when placed within table cells.
         
     | 
| 
      
 149 
     | 
    
         
            +
                // @todo: Use table-layout: fixed, and remove the max-width definition from
         
     | 
| 
      
 150 
     | 
    
         
            +
                // .technical-documentation so tables can fill the viewport.
         
     | 
| 
      
 151 
     | 
    
         
            +
                max-width: 40em;
         
     | 
| 
       147 
152 
     | 
    
         
             
              }
         
     | 
| 
       148 
153 
     | 
    
         | 
| 
       149 
154 
     | 
    
         
             
              pre code {
         
     | 
| 
         @@ -156,11 +161,11 @@ 
     | 
|
| 
       156 
161 
     | 
    
         
             
                background: $code-01;
         
     | 
| 
       157 
162 
     | 
    
         
             
                padding: 3px 5px;
         
     | 
| 
       158 
163 
     | 
    
         
             
                border-radius: 1px;
         
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
       160 
165 
     | 
    
         
             
                font-family: monaco, Consolas, "Lucida Console", monospace;
         
     | 
| 
       161 
166 
     | 
    
         
             
                font-size: 15px;
         
     | 
| 
       162 
167 
     | 
    
         
             
                color: $code-0E;
         
     | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
       164 
169 
     | 
    
         
             
                @include media(tablet) {
         
     | 
| 
       165 
170 
     | 
    
         
             
                  font-size: 16px;
         
     | 
| 
       166 
171 
     | 
    
         
             
                }
         
     | 
| 
         @@ -191,11 +196,11 @@ 
     | 
|
| 
       191 
196 
     | 
    
         
             
                display: block;
         
     | 
| 
       192 
197 
     | 
    
         
             
                max-width: 100%;
         
     | 
| 
       193 
198 
     | 
    
         
             
                overflow-x: auto;
         
     | 
| 
       194 
     | 
    
         
            -
             
     | 
| 
      
 199 
     | 
    
         
            +
             
     | 
| 
       195 
200 
     | 
    
         
             
                margin-top: $gutter-half;
         
     | 
| 
       196 
201 
     | 
    
         
             
              }
         
     | 
| 
       197 
202 
     | 
    
         | 
| 
       198 
     | 
    
         
            -
              table { 
     | 
| 
      
 203 
     | 
    
         
            +
              table {
         
     | 
| 
       199 
204 
     | 
    
         
             
                width: 100%;
         
     | 
| 
       200 
205 
     | 
    
         | 
| 
       201 
206 
     | 
    
         
             
                border-collapse: collapse;
         
     | 
    
        data/lib/govuk_tech_docs.rb
    CHANGED
    
    | 
         @@ -20,6 +20,7 @@ require 'govuk_tech_docs/pages' 
     | 
|
| 
       20 
20 
     | 
    
         
             
            require 'govuk_tech_docs/tech_docs_html_renderer'
         
     | 
| 
       21 
21 
     | 
    
         
             
            require 'govuk_tech_docs/unique_identifier_extension'
         
     | 
| 
       22 
22 
     | 
    
         
             
            require 'govuk_tech_docs/unique_identifier_generator'
         
     | 
| 
      
 23 
     | 
    
         
            +
            require 'govuk_tech_docs/api_reference/api_reference_extension'
         
     | 
| 
       23 
24 
     | 
    
         | 
| 
       24 
25 
     | 
    
         
             
            module GovukTechDocs
         
     | 
| 
       25 
26 
     | 
    
         
             
              # Configure the tech docs template
         
     | 
| 
         @@ -37,7 +38,9 @@ module GovukTechDocs 
     | 
|
| 
       37 
38 
     | 
    
         
             
                context.set :markdown_engine, :redcarpet
         
     | 
| 
       38 
39 
     | 
    
         
             
                context.set :markdown,
         
     | 
| 
       39 
40 
     | 
    
         
             
                    renderer: TechDocsHTMLRenderer.new(
         
     | 
| 
       40 
     | 
    
         
            -
                      with_toc_data: true
         
     | 
| 
      
 41 
     | 
    
         
            +
                      with_toc_data: true,
         
     | 
| 
      
 42 
     | 
    
         
            +
                      api: true,
         
     | 
| 
      
 43 
     | 
    
         
            +
                      context: context
         
     | 
| 
       41 
44 
     | 
    
         
             
                    ),
         
     | 
| 
       42 
45 
     | 
    
         
             
                    fenced_code_blocks: true,
         
     | 
| 
       43 
46 
     | 
    
         
             
                    tables: true,
         
     | 
| 
         @@ -56,6 +59,8 @@ module GovukTechDocs 
     | 
|
| 
       56 
59 
     | 
    
         
             
                context.config[:tech_docs] = YAML.load_file('config/tech-docs.yml').with_indifferent_access
         
     | 
| 
       57 
60 
     | 
    
         
             
                context.activate :unique_identifier
         
     | 
| 
       58 
61 
     | 
    
         | 
| 
      
 62 
     | 
    
         
            +
                context.activate :api_reference
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
       59 
64 
     | 
    
         
             
                context.helpers do
         
     | 
| 
       60 
65 
     | 
    
         
             
                  include GovukTechDocs::TableOfContents::Helpers
         
     | 
| 
       61 
66 
     | 
    
         
             
                  include GovukTechDocs::ContributionBanner
         
     | 
| 
         @@ -65,7 +70,7 @@ module GovukTechDocs 
     | 
|
| 
       65 
70 
     | 
    
         
             
                  end
         
     | 
| 
       66 
71 
     | 
    
         | 
| 
       67 
72 
     | 
    
         
             
                  def current_page_review
         
     | 
| 
       68 
     | 
    
         
            -
                    @current_page_review ||= GovukTechDocs::PageReview.new(current_page)
         
     | 
| 
      
 73 
     | 
    
         
            +
                    @current_page_review ||= GovukTechDocs::PageReview.new(current_page, config)
         
     | 
| 
       69 
74 
     | 
    
         
             
                  end
         
     | 
| 
       70 
75 
     | 
    
         | 
| 
       71 
76 
     | 
    
         
             
                  def format_date(date)
         
     | 
| 
         @@ -102,6 +107,12 @@ module GovukTechDocs 
     | 
|
| 
       102 
107 
     | 
    
         
             
                      content: { boost: 50, store: true },
         
     | 
| 
       103 
108 
     | 
    
         
             
                      url:     { index: false, store: true },
         
     | 
| 
       104 
109 
     | 
    
         
             
                    }
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                    search.pipeline_remove = [
         
     | 
| 
      
 112 
     | 
    
         
            +
                      'stopWordFilter'
         
     | 
| 
      
 113 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                    search.tokenizer_separator = '/[\s\-/]+/'
         
     | 
| 
       105 
116 
     | 
    
         
             
                  end
         
     | 
| 
       106 
117 
     | 
    
         
             
                end
         
     | 
| 
       107 
118 
     | 
    
         
             
              end
         
     | 
| 
         @@ -0,0 +1,100 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'erb'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'openapi3_parser'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'uri'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'pry'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'govuk_tech_docs/api_reference/api_reference_renderer'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            module GovukTechDocs
         
     | 
| 
      
 8 
     | 
    
         
            +
              module ApiReference
         
     | 
| 
      
 9 
     | 
    
         
            +
                class Extension < Middleman::Extension
         
     | 
| 
      
 10 
     | 
    
         
            +
                  expose_to_application api: :api
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  def initialize(app, options_hash = {}, &block)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    super
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    @app = app
         
     | 
| 
      
 16 
     | 
    
         
            +
                    @config = @app.config[:tech_docs]
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                    # If no api path then just return.
         
     | 
| 
      
 19 
     | 
    
         
            +
                    if @config['api_path'].to_s.empty?
         
     | 
| 
      
 20 
     | 
    
         
            +
                      raise 'No api path defined in tech-docs.yml'
         
     | 
| 
      
 21 
     | 
    
         
            +
                    end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                    # Is the api_path a url or path?
         
     | 
| 
      
 24 
     | 
    
         
            +
                    if uri?(@config['api_path'])
         
     | 
| 
      
 25 
     | 
    
         
            +
                      @api_parser = true
         
     | 
| 
      
 26 
     | 
    
         
            +
                      @document = Openapi3Parser.load_url(@config['api_path'])
         
     | 
| 
      
 27 
     | 
    
         
            +
                    elsif File.exist?(@config['api_path'])
         
     | 
| 
      
 28 
     | 
    
         
            +
                      # Load api file and set existence flag.
         
     | 
| 
      
 29 
     | 
    
         
            +
                      @api_parser = true
         
     | 
| 
      
 30 
     | 
    
         
            +
                      @document = Openapi3Parser.load_file(@config['api_path'])
         
     | 
| 
      
 31 
     | 
    
         
            +
                    else
         
     | 
| 
      
 32 
     | 
    
         
            +
                      @api_parser = false
         
     | 
| 
      
 33 
     | 
    
         
            +
                      raise 'Unable to load api path from tech-docs.yml'
         
     | 
| 
      
 34 
     | 
    
         
            +
                    end
         
     | 
| 
      
 35 
     | 
    
         
            +
                    @render = Renderer.new(@app, @document)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  def uri?(string)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    uri = URI.parse(string)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    %w(http https).include?(uri.scheme)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  rescue URI::BadURIError
         
     | 
| 
      
 42 
     | 
    
         
            +
                    false
         
     | 
| 
      
 43 
     | 
    
         
            +
                  rescue URI::InvalidURIError
         
     | 
| 
      
 44 
     | 
    
         
            +
                    false
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  def api(text)
         
     | 
| 
      
 48 
     | 
    
         
            +
                    if @api_parser == true
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                      keywords = {
         
     | 
| 
      
 51 
     | 
    
         
            +
                        'api>' => 'default',
         
     | 
| 
      
 52 
     | 
    
         
            +
                        'api_schema>' => 'schema'
         
     | 
| 
      
 53 
     | 
    
         
            +
                      }
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                      regexp = keywords.map { |k, _| Regexp.escape(k) }.join('|')
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                      md = text.match(/^<p>(#{regexp})/)
         
     | 
| 
      
 58 
     | 
    
         
            +
                      if md
         
     | 
| 
      
 59 
     | 
    
         
            +
                        key = md.captures[0]
         
     | 
| 
      
 60 
     | 
    
         
            +
                        type = keywords[key]
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                        text.gsub!(/#{ Regexp.escape(key) }\s+?/, '')
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                        # Strip paragraph tags from text
         
     | 
| 
      
 65 
     | 
    
         
            +
                        text = text.gsub(/<\/?[^>]*>/, '')
         
     | 
| 
      
 66 
     | 
    
         
            +
                        text = text.strip
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                        if text == 'api>'
         
     | 
| 
      
 69 
     | 
    
         
            +
                          @render.api_full(api_info, api_server)
         
     | 
| 
      
 70 
     | 
    
         
            +
                        elsif type == 'default'
         
     | 
| 
      
 71 
     | 
    
         
            +
                          output = @render.path(text)
         
     | 
| 
      
 72 
     | 
    
         
            +
                          # Render any schemas referenced in the above path
         
     | 
| 
      
 73 
     | 
    
         
            +
                          output += @render.schemas_from_path(text)
         
     | 
| 
      
 74 
     | 
    
         
            +
                          output
         
     | 
| 
      
 75 
     | 
    
         
            +
                        else
         
     | 
| 
      
 76 
     | 
    
         
            +
                          @render.schema(text)
         
     | 
| 
      
 77 
     | 
    
         
            +
                        end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                      else
         
     | 
| 
      
 80 
     | 
    
         
            +
                        return text
         
     | 
| 
      
 81 
     | 
    
         
            +
                      end
         
     | 
| 
      
 82 
     | 
    
         
            +
                    else
         
     | 
| 
      
 83 
     | 
    
         
            +
                      text
         
     | 
| 
      
 84 
     | 
    
         
            +
                    end
         
     | 
| 
      
 85 
     | 
    
         
            +
                  end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                private
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                  def api_info
         
     | 
| 
      
 90 
     | 
    
         
            +
                    @document.info
         
     | 
| 
      
 91 
     | 
    
         
            +
                  end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                  def api_server
         
     | 
| 
      
 94 
     | 
    
         
            +
                    @document.servers[0]
         
     | 
| 
      
 95 
     | 
    
         
            +
                  end
         
     | 
| 
      
 96 
     | 
    
         
            +
                end
         
     | 
| 
      
 97 
     | 
    
         
            +
              end
         
     | 
| 
      
 98 
     | 
    
         
            +
            end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
            ::Middleman::Extensions.register(:api_reference, GovukTechDocs::ApiReference::Extension)
         
     | 
| 
         @@ -0,0 +1,279 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'erb'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'json'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module GovukTechDocs
         
     | 
| 
      
 5 
     | 
    
         
            +
              module ApiReference
         
     | 
| 
      
 6 
     | 
    
         
            +
                class Renderer
         
     | 
| 
      
 7 
     | 
    
         
            +
                  def initialize(app, document)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    @app = app
         
     | 
| 
      
 9 
     | 
    
         
            +
                    @document = document
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                    # Load template files
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @template_api_full = get_renderer('api_reference_full.html.erb')
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @template_path = get_renderer('path.html.erb')
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @template_schema = get_renderer('schema.html.erb')
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @template_operation = get_renderer('operation.html.erb')
         
     | 
| 
      
 16 
     | 
    
         
            +
                    @template_parameters = get_renderer('parameters.html.erb')
         
     | 
| 
      
 17 
     | 
    
         
            +
                    @template_responses = get_renderer('responses.html.erb')
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  def api_full(info, server)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    paths = ''
         
     | 
| 
      
 22 
     | 
    
         
            +
                    paths_data = @document.paths
         
     | 
| 
      
 23 
     | 
    
         
            +
                    paths_data.each do |path_data|
         
     | 
| 
      
 24 
     | 
    
         
            +
                      # For some reason paths.each returns an array of arrays [title, object]
         
     | 
| 
      
 25 
     | 
    
         
            +
                      # instead of an array of objects
         
     | 
| 
      
 26 
     | 
    
         
            +
                      text = path_data[0]
         
     | 
| 
      
 27 
     | 
    
         
            +
                      paths += path(text)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    end
         
     | 
| 
      
 29 
     | 
    
         
            +
                    schemas = ''
         
     | 
| 
      
 30 
     | 
    
         
            +
                    schemas_data = @document.components.schemas
         
     | 
| 
      
 31 
     | 
    
         
            +
                    schemas_data.each do |schema_data|
         
     | 
| 
      
 32 
     | 
    
         
            +
                      text = schema_data[0]
         
     | 
| 
      
 33 
     | 
    
         
            +
                      schemas += schema(text)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    end
         
     | 
| 
      
 35 
     | 
    
         
            +
                    @template_api_full.result(binding)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  def path(text)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    path = @document.paths[text]
         
     | 
| 
      
 40 
     | 
    
         
            +
                    id = text.parameterize
         
     | 
| 
      
 41 
     | 
    
         
            +
                    operations = operations(path, id)
         
     | 
| 
      
 42 
     | 
    
         
            +
                    @template_path.result(binding)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  def schema(text)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    schemas = ''
         
     | 
| 
      
 47 
     | 
    
         
            +
                    schemas_data = @document.components.schemas
         
     | 
| 
      
 48 
     | 
    
         
            +
                    schemas_data.each do |schema_data|
         
     | 
| 
      
 49 
     | 
    
         
            +
                      all_of = schema_data[1]["allOf"]
         
     | 
| 
      
 50 
     | 
    
         
            +
                      properties = []
         
     | 
| 
      
 51 
     | 
    
         
            +
                      if !all_of.blank?
         
     | 
| 
      
 52 
     | 
    
         
            +
                        all_of.each do |schema_nested|
         
     | 
| 
      
 53 
     | 
    
         
            +
                          schema_nested.properties.each do |property|
         
     | 
| 
      
 54 
     | 
    
         
            +
                            properties.push property
         
     | 
| 
      
 55 
     | 
    
         
            +
                          end
         
     | 
| 
      
 56 
     | 
    
         
            +
                        end
         
     | 
| 
      
 57 
     | 
    
         
            +
                      end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                      schema_data[1].properties.each do |property|
         
     | 
| 
      
 60 
     | 
    
         
            +
                        properties.push property
         
     | 
| 
      
 61 
     | 
    
         
            +
                      end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                      if schema_data[0] == text
         
     | 
| 
      
 64 
     | 
    
         
            +
                        title = schema_data[0]
         
     | 
| 
      
 65 
     | 
    
         
            +
                        schema = schema_data[1]
         
     | 
| 
      
 66 
     | 
    
         
            +
                        return @template_schema.result(binding)
         
     | 
| 
      
 67 
     | 
    
         
            +
                      end
         
     | 
| 
      
 68 
     | 
    
         
            +
                    end
         
     | 
| 
      
 69 
     | 
    
         
            +
                  end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                  def schemas_from_path(text)
         
     | 
| 
      
 72 
     | 
    
         
            +
                    path = @document.paths[text]
         
     | 
| 
      
 73 
     | 
    
         
            +
                    operations = get_operations(path)
         
     | 
| 
      
 74 
     | 
    
         
            +
                    # Get all referenced schemas
         
     | 
| 
      
 75 
     | 
    
         
            +
                    schemas = []
         
     | 
| 
      
 76 
     | 
    
         
            +
                    operations.compact.each_value do |operation|
         
     | 
| 
      
 77 
     | 
    
         
            +
                      responses = operation.responses
         
     | 
| 
      
 78 
     | 
    
         
            +
                      responses.each do |_rkey, response|
         
     | 
| 
      
 79 
     | 
    
         
            +
                        if response.content['application/json']
         
     | 
| 
      
 80 
     | 
    
         
            +
                          schema = response.content['application/json'].schema
         
     | 
| 
      
 81 
     | 
    
         
            +
                          schema_name = get_schema_name(schema.node_context.source_location.to_s)
         
     | 
| 
      
 82 
     | 
    
         
            +
                          if !schema_name.nil?
         
     | 
| 
      
 83 
     | 
    
         
            +
                            schemas.push schema_name
         
     | 
| 
      
 84 
     | 
    
         
            +
                          end
         
     | 
| 
      
 85 
     | 
    
         
            +
                          schemas.concat(schemas_from_schema(schema))
         
     | 
| 
      
 86 
     | 
    
         
            +
                        end
         
     | 
| 
      
 87 
     | 
    
         
            +
                      end
         
     | 
| 
      
 88 
     | 
    
         
            +
                    end
         
     | 
| 
      
 89 
     | 
    
         
            +
                    # Render all referenced schemas
         
     | 
| 
      
 90 
     | 
    
         
            +
                    output = ''
         
     | 
| 
      
 91 
     | 
    
         
            +
                    schemas.uniq.each do |schema_name|
         
     | 
| 
      
 92 
     | 
    
         
            +
                      output += schema(schema_name)
         
     | 
| 
      
 93 
     | 
    
         
            +
                    end
         
     | 
| 
      
 94 
     | 
    
         
            +
                    if !output.empty?
         
     | 
| 
      
 95 
     | 
    
         
            +
                      output.prepend('<h2 id="schemas">Schemas</h2>')
         
     | 
| 
      
 96 
     | 
    
         
            +
                    end
         
     | 
| 
      
 97 
     | 
    
         
            +
                    output
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                  def schemas_from_schema(schema)
         
     | 
| 
      
 101 
     | 
    
         
            +
                    schemas = []
         
     | 
| 
      
 102 
     | 
    
         
            +
                    properties = []
         
     | 
| 
      
 103 
     | 
    
         
            +
                    schema.properties.each do |property|
         
     | 
| 
      
 104 
     | 
    
         
            +
                      properties.push property[1]
         
     | 
| 
      
 105 
     | 
    
         
            +
                    end
         
     | 
| 
      
 106 
     | 
    
         
            +
                    if schema.type == 'array'
         
     | 
| 
      
 107 
     | 
    
         
            +
                      properties.push schema.items
         
     | 
| 
      
 108 
     | 
    
         
            +
                    end
         
     | 
| 
      
 109 
     | 
    
         
            +
                    all_of = schema["allOf"]
         
     | 
| 
      
 110 
     | 
    
         
            +
                    if !all_of.blank?
         
     | 
| 
      
 111 
     | 
    
         
            +
                      all_of.each do |schema_nested|
         
     | 
| 
      
 112 
     | 
    
         
            +
                        schema_nested.properties.each do |property|
         
     | 
| 
      
 113 
     | 
    
         
            +
                          properties.push property[1]
         
     | 
| 
      
 114 
     | 
    
         
            +
                        end
         
     | 
| 
      
 115 
     | 
    
         
            +
                      end
         
     | 
| 
      
 116 
     | 
    
         
            +
                    end
         
     | 
| 
      
 117 
     | 
    
         
            +
                    properties.each do |property|
         
     | 
| 
      
 118 
     | 
    
         
            +
                      # Must be a schema be referenced by another schema
         
     | 
| 
      
 119 
     | 
    
         
            +
                      # And not a property of a schema
         
     | 
| 
      
 120 
     | 
    
         
            +
                      if property.node_context.referenced_by.to_s.include?('#/components/schemas') &&
         
     | 
| 
      
 121 
     | 
    
         
            +
                          !property.node_context.source_location.to_s.include?('/properties/')
         
     | 
| 
      
 122 
     | 
    
         
            +
                        schema_name = get_schema_name(property.node_context.source_location.to_s)
         
     | 
| 
      
 123 
     | 
    
         
            +
                      end
         
     | 
| 
      
 124 
     | 
    
         
            +
                      if !schema_name.nil?
         
     | 
| 
      
 125 
     | 
    
         
            +
                        schemas.push schema_name
         
     | 
| 
      
 126 
     | 
    
         
            +
                      end
         
     | 
| 
      
 127 
     | 
    
         
            +
                      # Check sub-properties for references
         
     | 
| 
      
 128 
     | 
    
         
            +
                      schemas.concat(schemas_from_schema(property))
         
     | 
| 
      
 129 
     | 
    
         
            +
                    end
         
     | 
| 
      
 130 
     | 
    
         
            +
                    schemas
         
     | 
| 
      
 131 
     | 
    
         
            +
                  end
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
                  def operations(path, path_id)
         
     | 
| 
      
 134 
     | 
    
         
            +
                    output = ''
         
     | 
| 
      
 135 
     | 
    
         
            +
                    operations = get_operations(path)
         
     | 
| 
      
 136 
     | 
    
         
            +
                    operations.compact.each do |key, operation|
         
     | 
| 
      
 137 
     | 
    
         
            +
                      id = "#{path_id}-#{key.parameterize}"
         
     | 
| 
      
 138 
     | 
    
         
            +
                      parameters = parameters(operation, id)
         
     | 
| 
      
 139 
     | 
    
         
            +
                      responses = responses(operation, id)
         
     | 
| 
      
 140 
     | 
    
         
            +
                      output += @template_operation.result(binding)
         
     | 
| 
      
 141 
     | 
    
         
            +
                    end
         
     | 
| 
      
 142 
     | 
    
         
            +
                    output
         
     | 
| 
      
 143 
     | 
    
         
            +
                  end
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                  def parameters(operation, operation_id)
         
     | 
| 
      
 146 
     | 
    
         
            +
                    parameters = operation.parameters
         
     | 
| 
      
 147 
     | 
    
         
            +
                    id = "#{operation_id}-parameters"
         
     | 
| 
      
 148 
     | 
    
         
            +
                    output = @template_parameters.result(binding)
         
     | 
| 
      
 149 
     | 
    
         
            +
                    output
         
     | 
| 
      
 150 
     | 
    
         
            +
                  end
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                  def responses(operation, operation_id)
         
     | 
| 
      
 153 
     | 
    
         
            +
                    responses = operation.responses
         
     | 
| 
      
 154 
     | 
    
         
            +
                    id = "#{operation_id}-responses"
         
     | 
| 
      
 155 
     | 
    
         
            +
                    output = @template_responses.result(binding)
         
     | 
| 
      
 156 
     | 
    
         
            +
                    output
         
     | 
| 
      
 157 
     | 
    
         
            +
                  end
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                  def markdown(text)
         
     | 
| 
      
 160 
     | 
    
         
            +
                    if text
         
     | 
| 
      
 161 
     | 
    
         
            +
                      Tilt['markdown'].new(context: @app) { text }.render
         
     | 
| 
      
 162 
     | 
    
         
            +
                    end
         
     | 
| 
      
 163 
     | 
    
         
            +
                  end
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
                  def json_output(schema)
         
     | 
| 
      
 166 
     | 
    
         
            +
                    properties =  schema_properties(schema)
         
     | 
| 
      
 167 
     | 
    
         
            +
                    JSON.pretty_generate(properties)
         
     | 
| 
      
 168 
     | 
    
         
            +
                  end
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
                  def json_prettyprint(data)
         
     | 
| 
      
 171 
     | 
    
         
            +
                    JSON.pretty_generate(data)
         
     | 
| 
      
 172 
     | 
    
         
            +
                  end
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
                  def schema_properties(schema_data)
         
     | 
| 
      
 175 
     | 
    
         
            +
                    properties = Hash.new
         
     | 
| 
      
 176 
     | 
    
         
            +
                    if defined? schema_data.properties
         
     | 
| 
      
 177 
     | 
    
         
            +
                      schema_data.properties.each do |key, property|
         
     | 
| 
      
 178 
     | 
    
         
            +
                        properties[key] = property
         
     | 
| 
      
 179 
     | 
    
         
            +
                      end
         
     | 
| 
      
 180 
     | 
    
         
            +
                    end
         
     | 
| 
      
 181 
     | 
    
         
            +
                    properties.merge! get_all_of_hash(schema_data)
         
     | 
| 
      
 182 
     | 
    
         
            +
                    properties_hash = Hash.new
         
     | 
| 
      
 183 
     | 
    
         
            +
                    properties.each do |pkey, property|
         
     | 
| 
      
 184 
     | 
    
         
            +
                      if property.type == 'object'
         
     | 
| 
      
 185 
     | 
    
         
            +
                        properties_hash[pkey] = Hash.new
         
     | 
| 
      
 186 
     | 
    
         
            +
                        items = property.items
         
     | 
| 
      
 187 
     | 
    
         
            +
                        if !items.blank?
         
     | 
| 
      
 188 
     | 
    
         
            +
                          properties_hash[pkey] = schema_properties(items)
         
     | 
| 
      
 189 
     | 
    
         
            +
                        end
         
     | 
| 
      
 190 
     | 
    
         
            +
                        if !property.properties.blank?
         
     | 
| 
      
 191 
     | 
    
         
            +
                          properties_hash[pkey] = schema_properties(property)
         
     | 
| 
      
 192 
     | 
    
         
            +
                        end
         
     | 
| 
      
 193 
     | 
    
         
            +
                      elsif property.type == 'array'
         
     | 
| 
      
 194 
     | 
    
         
            +
                        properties_hash[pkey] = Array.new
         
     | 
| 
      
 195 
     | 
    
         
            +
                        items = property.items
         
     | 
| 
      
 196 
     | 
    
         
            +
                        if !items.blank?
         
     | 
| 
      
 197 
     | 
    
         
            +
                          properties_hash[pkey].push schema_properties(items)
         
     | 
| 
      
 198 
     | 
    
         
            +
                        end
         
     | 
| 
      
 199 
     | 
    
         
            +
                      else
         
     | 
| 
      
 200 
     | 
    
         
            +
                        properties_hash[pkey] = !property.example.nil? ? property.example : property.type
         
     | 
| 
      
 201 
     | 
    
         
            +
                      end
         
     | 
| 
      
 202 
     | 
    
         
            +
                    end
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
                    properties_hash
         
     | 
| 
      
 205 
     | 
    
         
            +
                  end
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
                private
         
     | 
| 
      
 208 
     | 
    
         
            +
             
     | 
| 
      
 209 
     | 
    
         
            +
                  def get_all_of_array(schema)
         
     | 
| 
      
 210 
     | 
    
         
            +
                    properties = Array.new
         
     | 
| 
      
 211 
     | 
    
         
            +
                    if schema.is_a?(Array)
         
     | 
| 
      
 212 
     | 
    
         
            +
                      schema = schema[1]
         
     | 
| 
      
 213 
     | 
    
         
            +
                    end
         
     | 
| 
      
 214 
     | 
    
         
            +
                    if schema["allOf"]
         
     | 
| 
      
 215 
     | 
    
         
            +
                      all_of = schema["allOf"]
         
     | 
| 
      
 216 
     | 
    
         
            +
                    end
         
     | 
| 
      
 217 
     | 
    
         
            +
                    if !all_of.blank?
         
     | 
| 
      
 218 
     | 
    
         
            +
                      all_of.each do |schema_nested|
         
     | 
| 
      
 219 
     | 
    
         
            +
                        schema_nested.properties.each do |property|
         
     | 
| 
      
 220 
     | 
    
         
            +
                          if property.is_a?(Array)
         
     | 
| 
      
 221 
     | 
    
         
            +
                            property = property[1]
         
     | 
| 
      
 222 
     | 
    
         
            +
                          end
         
     | 
| 
      
 223 
     | 
    
         
            +
                          properties.push property
         
     | 
| 
      
 224 
     | 
    
         
            +
                        end
         
     | 
| 
      
 225 
     | 
    
         
            +
                      end
         
     | 
| 
      
 226 
     | 
    
         
            +
                    end
         
     | 
| 
      
 227 
     | 
    
         
            +
                    properties
         
     | 
| 
      
 228 
     | 
    
         
            +
                  end
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
                  def get_all_of_hash(schema)
         
     | 
| 
      
 231 
     | 
    
         
            +
                    properties = Hash.new
         
     | 
| 
      
 232 
     | 
    
         
            +
                    if schema["allOf"]
         
     | 
| 
      
 233 
     | 
    
         
            +
                      all_of = schema["allOf"]
         
     | 
| 
      
 234 
     | 
    
         
            +
                    end
         
     | 
| 
      
 235 
     | 
    
         
            +
                    if !all_of.blank?
         
     | 
| 
      
 236 
     | 
    
         
            +
                      all_of.each do |schema_nested|
         
     | 
| 
      
 237 
     | 
    
         
            +
                        schema_nested.properties.each do |key, property|
         
     | 
| 
      
 238 
     | 
    
         
            +
                          properties[key] = property
         
     | 
| 
      
 239 
     | 
    
         
            +
                        end
         
     | 
| 
      
 240 
     | 
    
         
            +
                      end
         
     | 
| 
      
 241 
     | 
    
         
            +
                    end
         
     | 
| 
      
 242 
     | 
    
         
            +
                    properties
         
     | 
| 
      
 243 
     | 
    
         
            +
                  end
         
     | 
| 
      
 244 
     | 
    
         
            +
             
     | 
| 
      
 245 
     | 
    
         
            +
                  def get_renderer(file)
         
     | 
| 
      
 246 
     | 
    
         
            +
                    template_path = File.join(File.dirname(__FILE__), 'templates/' + file)
         
     | 
| 
      
 247 
     | 
    
         
            +
                    template = File.open(template_path, 'r').read
         
     | 
| 
      
 248 
     | 
    
         
            +
                    ERB.new(template)
         
     | 
| 
      
 249 
     | 
    
         
            +
                  end
         
     | 
| 
      
 250 
     | 
    
         
            +
             
     | 
| 
      
 251 
     | 
    
         
            +
                  def get_operations(path)
         
     | 
| 
      
 252 
     | 
    
         
            +
                    operations = {}
         
     | 
| 
      
 253 
     | 
    
         
            +
                    operations['get'] = path.get if defined? path.get
         
     | 
| 
      
 254 
     | 
    
         
            +
                    operations['put'] = path.put if defined? path.put
         
     | 
| 
      
 255 
     | 
    
         
            +
                    operations['post'] = path.post if defined? path.post
         
     | 
| 
      
 256 
     | 
    
         
            +
                    operations['delete'] = path.delete if defined? path.delete
         
     | 
| 
      
 257 
     | 
    
         
            +
                    operations['patch'] = path.patch if defined? path.patch
         
     | 
| 
      
 258 
     | 
    
         
            +
                    operations
         
     | 
| 
      
 259 
     | 
    
         
            +
                  end
         
     | 
| 
      
 260 
     | 
    
         
            +
             
     | 
| 
      
 261 
     | 
    
         
            +
                  def get_schema_name(text)
         
     | 
| 
      
 262 
     | 
    
         
            +
                    unless text.is_a?(String)
         
     | 
| 
      
 263 
     | 
    
         
            +
                      return nil
         
     | 
| 
      
 264 
     | 
    
         
            +
                    end
         
     | 
| 
      
 265 
     | 
    
         
            +
                    # Schema dictates that it's always components['schemas']
         
     | 
| 
      
 266 
     | 
    
         
            +
                    text.gsub(/#\/components\/schemas\//, '')
         
     | 
| 
      
 267 
     | 
    
         
            +
                  end
         
     | 
| 
      
 268 
     | 
    
         
            +
             
     | 
| 
      
 269 
     | 
    
         
            +
                  def get_schema_link(schema)
         
     | 
| 
      
 270 
     | 
    
         
            +
                    schema_name = get_schema_name schema.node_context.source_location.to_s
         
     | 
| 
      
 271 
     | 
    
         
            +
                    if !schema_name.nil?
         
     | 
| 
      
 272 
     | 
    
         
            +
                      id = "schema-#{schema_name.parameterize}"
         
     | 
| 
      
 273 
     | 
    
         
            +
                      output = "<a href='\##{id}'>#{schema_name}</a>"
         
     | 
| 
      
 274 
     | 
    
         
            +
                      output
         
     | 
| 
      
 275 
     | 
    
         
            +
                    end
         
     | 
| 
      
 276 
     | 
    
         
            +
                  end
         
     | 
| 
      
 277 
     | 
    
         
            +
                end
         
     | 
| 
      
 278 
     | 
    
         
            +
              end
         
     | 
| 
      
 279 
     | 
    
         
            +
            end
         
     |