Full Code of realm/jazzy for AI

master 5ff729211cc7 cached
90 files
527.4 KB
133.8k tokens
656 symbols
1 requests
Download .txt
Showing preview only (556K chars total). Download the full file or copy to clipboard to get everything.
Repository: realm/jazzy
Branch: master
Commit: 5ff729211cc7
Files: 90
Total size: 527.4 KB

Directory structure:
gitextract_xj36c4n0/

├── .github/
│   └── workflows/
│       └── Tests.yml
├── .gitignore
├── .gitmodules
├── .rubocop.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Dangerfile
├── Gemfile
├── LICENSE
├── ObjectiveC.md
├── README.md
├── Rakefile
├── bin/
│   ├── jazzy
│   └── sourcekitten
├── images/
│   └── logo.sketch
├── jazzy.gemspec
├── js/
│   └── package.json
├── lib/
│   ├── jazzy/
│   │   ├── config.rb
│   │   ├── doc.rb
│   │   ├── doc_builder.rb
│   │   ├── doc_index.rb
│   │   ├── docset_builder/
│   │   │   └── info_plist.mustache
│   │   ├── docset_builder.rb
│   │   ├── documentation_generator.rb
│   │   ├── executable.rb
│   │   ├── gem_version.rb
│   │   ├── grouper.rb
│   │   ├── highlighter.rb
│   │   ├── jazzy_markdown.rb
│   │   ├── podspec_documenter.rb
│   │   ├── search_builder.rb
│   │   ├── source_declaration/
│   │   │   ├── access_control_level.rb
│   │   │   └── type.rb
│   │   ├── source_declaration.rb
│   │   ├── source_document.rb
│   │   ├── source_host.rb
│   │   ├── source_mark.rb
│   │   ├── source_module.rb
│   │   ├── sourcekitten.rb
│   │   ├── stats.rb
│   │   ├── symbol_graph/
│   │   │   ├── constraint.rb
│   │   │   ├── ext_key.rb
│   │   │   ├── ext_node.rb
│   │   │   ├── graph.rb
│   │   │   ├── relationship.rb
│   │   │   ├── sym_node.rb
│   │   │   └── symbol.rb
│   │   ├── symbol_graph.rb
│   │   └── themes/
│   │       ├── apple/
│   │       │   ├── assets/
│   │       │   │   ├── css/
│   │       │   │   │   ├── highlight.css.scss
│   │       │   │   │   └── jazzy.css.scss
│   │       │   │   └── js/
│   │       │   │       ├── jazzy.js
│   │       │   │       ├── jazzy.search.js
│   │       │   │       └── typeahead.jquery.js
│   │       │   └── templates/
│   │       │       ├── deprecation.mustache
│   │       │       ├── doc.mustache
│   │       │       ├── footer.mustache
│   │       │       ├── header.mustache
│   │       │       ├── nav.mustache
│   │       │       ├── parameter.mustache
│   │       │       ├── task.mustache
│   │       │       └── tasks.mustache
│   │       ├── fullwidth/
│   │       │   ├── assets/
│   │       │   │   ├── css/
│   │       │   │   │   ├── highlight.css.scss
│   │       │   │   │   └── jazzy.css.scss
│   │       │   │   └── js/
│   │       │   │       ├── jazzy.js
│   │       │   │       ├── jazzy.search.js
│   │       │   │       └── typeahead.jquery.js
│   │       │   └── templates/
│   │       │       ├── deprecation.mustache
│   │       │       ├── doc.mustache
│   │       │       ├── footer.mustache
│   │       │       ├── header.mustache
│   │       │       ├── nav.mustache
│   │       │       ├── parameter.mustache
│   │       │       ├── task.mustache
│   │       │       └── tasks.mustache
│   │       └── jony/
│   │           ├── assets/
│   │           │   ├── css/
│   │           │   │   ├── highlight.css.scss
│   │           │   │   └── jazzy.css.scss
│   │           │   └── js/
│   │           │       └── jazzy.js
│   │           └── templates/
│   │               ├── deprecation.mustache
│   │               ├── doc.mustache
│   │               ├── footer.mustache
│   │               ├── header.mustache
│   │               ├── nav.mustache
│   │               ├── parameter.mustache
│   │               ├── task.mustache
│   │               └── tasks.mustache
│   └── jazzy.rb
└── spec/
    ├── Moya.podspec
    ├── integration_spec.rb
    ├── spec_helper/
    │   └── pre_flight.rb
    └── spec_helper.rb

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/Tests.yml
================================================
name: Tests
  
on:
  push:
    branches: [master]
  pull_request:
    branches: ['*']

jobs:
  danger_and_rubocop:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.3
          bundler-cache: true
      - name: Rubocop
        run: |
          bundle exec rake rubocop
      - name: Danger
        env:
          DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          bundle exec danger --verbose

  spec:
    runs-on: macos-15
    continue-on-error: true
    strategy:
      matrix:
        spec: ["objc_spec", "swift_spec", "cocoapods_spec"]
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: recursive
          persist-credentials: false
      - uses: maxim-lobanov/setup-xcode@v1
        with:
          xcode-version: '26.2'
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.3
          bundler-cache: true
      - name: Cache cocoapods
        uses: actions/cache@v4
        env:
          cache-name: cocoapods
        with:
          path: ~/.cocoapods
          key: ${{ matrix.spec }}-${{ env.cache-name }}
      - name: Test
        run: |
          bundle exec rake ${{ matrix.spec }}


================================================
FILE: .gitignore
================================================
jazzy-docs/
/docs/
node_modules

*.gem
*.rbc
/.config
/coverage/
/InstalledFiles
/pkg/
/spec/reports/
/test/tmp/
/test/version_tmp/
/tmp/

## Specific to RubyMotion:
.dat*
.repl_history
build/

## Documentation cache and generated files:
/.yardoc/
/_yardoc/
/doc/
/rdoc/

## Environment normalisation:
/.bundle/
/lib/bundler/man/

# for a library or gem, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# Gemfile.lock
# .ruby-version
# .ruby-gemset

# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
.rvmrc

.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon


# Thumbnails
._*

# Files that might appear on external disk
.Spotlight-V100
.Trashes

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
vendor


================================================
FILE: .gitmodules
================================================
[submodule "SourceKitten"]
	path = SourceKitten
	url = https://github.com/jpsim/SourceKitten.git
[submodule "spec/integration_specs"]
	path = spec/integration_specs
	url = https://github.com/realm/jazzy-integration-specs.git


================================================
FILE: .rubocop.yml
================================================
AllCops:
  Exclude:
    - ./spec/integration_specs/**/*
    - ./spec/Moya.podspec
    - ./vendor/**/*
    - ./tmp/**/*
    - ./SourceKitten/**/*
  SuggestExtensions: false
  TargetRubyVersion: 2.6

#- Pending Cops as of 1.81.1 ---------------------------------------------#

Gemspec/AddRuntimeDependency: # new in 1.65
  Enabled: true
Gemspec/AttributeAssignment: # new in 1.77
  Enabled: true
Gemspec/DeprecatedAttributeAssignment: # new in 1.30
  Enabled: true
Gemspec/DevelopmentDependencies: # new in 1.44
  Enabled: false
Gemspec/RequireMFA: # new in 1.23
  Enabled: true
Layout/EmptyLinesAfterModuleInclusion: # new in 1.79
  Enabled: true
Layout/LineContinuationLeadingSpace: # new in 1.31
  Enabled: false
Layout/LineContinuationSpacing: # new in 1.31
  Enabled: true
Layout/SpaceBeforeBrackets: # (new in 1.7)
  Enabled: true
Lint/AmbiguousAssignment: # (new in 1.7)
  Enabled: true
Lint/AmbiguousRange: # (new in 1.19)
  Enabled: true
Lint/ArrayLiteralInRegexp: # new in 1.71
  Enabled: true
Lint/ConstantOverwrittenInRescue: # new in 1.31
  Enabled: true
Lint/ConstantReassignment: # new in 1.70
  Enabled: true
Lint/CopDirectiveSyntax: # new in 1.72
  Enabled: true
Lint/DeprecatedConstants: # (new in 1.8)
  Enabled: true
Lint/DuplicateBranch: # (new in 1.3)
  Enabled: true
Lint/DuplicateMagicComment: # new in 1.37
  Enabled: true
Lint/DuplicateMatchPattern: # new in 1.50
  Enabled: true
Lint/DuplicateRegexpCharacterClassElement: # (new in 1.1)
  Enabled: true
Lint/DuplicateSetElement: # new in 1.67
  Enabled: true
Lint/EmptyBlock: # (new in 1.1)
  Enabled: true
Lint/EmptyClass: # (new in 1.3)
  Enabled: true
Lint/EmptyInPattern: # (new in 1.16)
  Enabled: true
Lint/HashNewWithKeywordArgumentsAsDefault: # new in 1.69
  Enabled: true
Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
  Enabled: true
Lint/ItWithoutArgumentsInBlock: # new in 1.59
  Enabled: true
Lint/LambdaWithoutLiteralBlock: # (new in 1.8)
  Enabled: true
Lint/LiteralAssignmentInCondition: # new in 1.58
  Enabled: true
Lint/MixedCaseRange: # new in 1.53
  Enabled: true
Lint/NonAtomicFileOperation: # new in 1.31
  Enabled: true
Lint/NoReturnInBeginEndBlocks: # (new in 1.2)
  Enabled: true
Lint/NumberedParameterAssignment: # (new in 1.9)
  Enabled: true
Lint/NumericOperationWithConstantResult: # new in 1.69
  Enabled: true
Lint/OrAssignmentToConstant: # (new in 1.9)
  Enabled: true
Lint/RedundantDirGlobSort: # (new in 1.8)
  Enabled: true
Lint/RedundantRegexpQuantifiers: # new in 1.53
  Enabled: true
Lint/RedundantTypeConversion: # new in 1.72
  Enabled: true
Lint/RefinementImportMethods: # new in 1.27
  Enabled: true
Lint/RequireRangeParentheses: # new in 1.32
  Enabled: true
Lint/RequireRelativeSelfPath: # new in 1.22
  Enabled: true
Lint/SharedMutableDefault: # new in 1.70
  Enabled: true
Lint/SuppressedExceptionInNumberConversion: # new in 1.72
  Enabled: true
Lint/SymbolConversion: # (new in 1.9)
  Enabled: true
Lint/ToEnumArguments: # (new in 1.1)
  Enabled: true
Lint/TripleQuotes: # (new in 1.9)
  Enabled: true
Lint/UnescapedBracketInRegexp: # new in 1.68
  Enabled: true
Lint/UnexpectedBlockArity: # (new in 1.5)
  Enabled: true
Lint/UnmodifiedReduceAccumulator: # (new in 1.1)
  Enabled: true
Lint/UselessConstantScoping: # new in 1.72
  Enabled: true
Lint/UselessDefaultValueArgument: # new in 1.76
  Enabled: true
Lint/UselessDefined: # new in 1.69
  Enabled: true
Lint/UselessNumericOperation: # new in 1.66
  Enabled: true
Lint/UselessOr: # new in 1.76
  Enabled: true
Lint/UselessRescue: # new in 1.43
  Enabled: true
Lint/UselessRuby2Keywords: # new in 1.23
  Enabled: true
Metrics/CollectionLiteralLength: # new in 1.47
  Enabled: true
Naming/BlockForwarding: # new in 1.24
  Enabled: true
Naming/InclusiveLanguage: # (new in 1.18)
  Enabled: true
Naming/PredicateMethod: # new in 1.76
  Enabled: true
Security/CompoundHash: # new in 1.28
  Enabled: true
Style/BitwisePredicate: # new in 1.68
  Enabled: true
Style/CombinableDefined: # new in 1.68
  Enabled: true
Style/ComparableBetween: # new in 1.74
  Enabled: true
Style/ConcatArrayLiterals: # new in 1.41
  Enabled: true
Security/IoMethods: # new in 1.22
  Enabled: true
Style/AmbiguousEndlessMethodDefinition: # new in 1.68
  Enabled: true
Style/ArgumentsForwarding: # (new in 1.1)
  Enabled: true
Style/ArrayIntersect: # new in 1.40
  Enabled: true
Style/ArrayIntersectWithSingleElement: # new in 1.81
  Enabled: true
Style/CollectionCompact: # (new in 1.2)
  Enabled: true
Style/CollectionQuerying: # new in 1.77
  Enabled: true
Style/ComparableClamp: # new in 1.44
  Enabled: true
Style/DataInheritance: # new in 1.49
  Enabled: true
Style/DigChain: # new in 1.69
  Enabled: true
Style/DirEmpty: # new in 1.48
  Enabled: true
Style/DocumentDynamicEvalDefinition: # (new in 1.1)
  Enabled: true
Style/EmptyHeredoc: # new in 1.32
  Enabled: true
Style/EmptyStringInsideInterpolation: # new in 1.76
  Enabled: true
Style/EndlessMethod: # (new in 1.8)
  Enabled: true
Style/EnvHome: # new in 1.29
  Enabled: true
Style/ExactRegexpMatch: # new in 1.51
  Enabled: true
Style/FetchEnvVar: # new in 1.28
  Enabled: true
Style/FileEmpty: # new in 1.48
  Enabled: true
Style/FileNull: # new in 1.69
  Enabled: true
Style/FileRead: # new in 1.24
  Enabled: true
Style/FileTouch: # new in 1.69
  Enabled: true
Style/FileWrite: # new in 1.24
  Enabled: true
Style/HashConversion: # (new in 1.10)
  Enabled: true
Style/HashExcept: # (new in 1.7)
  Enabled: true
Style/HashFetchChain: # new in 1.75
  Enabled: true
Style/HashSlice: # new in 1.71
  Enabled: true
Style/IfWithBooleanLiteralBranches: # (new in 1.9)
  Enabled: true
Style/InPatternThen: # (new in 1.16)
  Enabled: true
Style/ItAssignment: # new in 1.70
  Enabled: true
Style/ItBlockParameter: # new in 1.75
  Enabled: true
Style/KeywordArgumentsMerging: # new in 1.68
  Enabled: true
Style/MagicCommentFormat: # new in 1.35
  Enabled: true
Style/MapCompactWithConditionalBlock: # new in 1.30
  Enabled: true
Style/MapIntoArray: # new in 1.63
  Enabled: true
Style/MapToHash: # new in 1.24
  Enabled: true
Style/MapToSet: # new in 1.42
  Enabled: true
Style/MinMaxComparison: # new in 1.42
  Enabled: true
Style/MultilineInPatternThen: # (new in 1.16)
  Enabled: true
Style/NegatedIfElseCondition: # (new in 1.2)
  Enabled: true
Style/NestedFileDirname: # new in 1.26
  Enabled: true
Style/NilLambda: # (new in 1.3)
  Enabled: true
Style/NumberedParameters: # new in 1.22
  Enabled: true
Style/NumberedParametersLimit: # new in 1.22
  Enabled: true
Style/ObjectThen: # new in 1.28
  Enabled: true
Style/OpenStructUse: # new in 1.23
  Enabled: true
Style/OperatorMethodCall: # new in 1.37
  Enabled: true
Style/QuotedSymbols: # (new in 1.16)
  Enabled: true
Style/RedundantArgument: # (new in 1.4)
  Enabled: true
Style/RedundantArrayConstructor: # new in 1.52
  Enabled: true
Style/RedundantArrayFlatten: # new in 1.76
  Enabled: true
Style/RedundantConstantBase: # new in 1.40
  Enabled: true
Style/RedundantCurrentDirectoryInPath: # new in 1.53
  Enabled: true
Style/RedundantDoubleSplatHashBraces: # new in 1.41
  Enabled: true
Style/RedundantEach: # new in 1.38
  Enabled: true
Style/RedundantFilterChain: # new in 1.52
  Enabled: true
Style/RedundantFormat: # new in 1.72
  Enabled: true
Style/RedundantHeredocDelimiterQuotes: # new in 1.45
  Enabled: true
Style/RedundantInitialize: # new in 1.27
  Enabled: true
Style/RedundantInterpolationUnfreeze: # new in 1.66
  Enabled: true
Style/RedundantLineContinuation: # new in 1.49
  Enabled: true
Style/RedundantRegexpArgument: # new in 1.53
  Enabled: true
Style/RedundantRegexpConstructor: # new in 1.52
  Enabled: true
Style/RedundantSelfAssignmentBranch: # (new in 1.19)
  Enabled: true
Style/RedundantStringEscape: # new in 1.37
  Enabled: true
Style/ReturnNilInPredicateMethodDefinition: # new in 1.53
  Enabled: true
Style/SafeNavigationChainLength: # new in 1.68
  Enabled: true
Style/SelectByRegexp: # new in 1.22
  Enabled: true
Style/SendWithLiteralMethodName: # new in 1.64
  Enabled: true
Style/SingleLineDoEndBlock: # new in 1.57
  Enabled: true
Style/StringChars: # (new in 1.12)
  Enabled: true
Style/SuperArguments: # new in 1.64
  Enabled: true
Style/SuperWithArgsParentheses: # new in 1.58
  Enabled: true
Style/SwapValues: # (new in 1.1)
  Enabled: true
Style/YAMLFileRead: # new in 1.53
  Enabled: true

# At the moment not ready to be used
# https://github.com/bbatsov/rubocop/issues/947
Style/Documentation:
  Enabled: false

#- Jazzy -----------------------------------------------------------------#

# 20 lines is more reasonable than rubocop's default of 10
Metrics/MethodLength:
  Max: 20

Metrics/AbcSize:
  Enabled: false

Metrics/ModuleLength:
  Enabled: false

Metrics/BlockLength:
  Enabled: false

Metrics/ParameterLists:
  CountKeywordArgs: false

Style/NumericPredicate:
  Enabled: false

Layout/HeredocIndentation:
  Enabled: false

# We adopted raise instead of fail.
Style/SignalException:
  EnforcedStyle: only_raise

# They are idiomatic
Lint/AssignmentInCondition:
  Enabled: false

# Allow backticks
Style/AsciiComments:
  Enabled: false

# Indentation clarifies logic branches in implementations
Style/IfUnlessModifier:
  Enabled: false

# No enforced convention here.
Style/SingleLineBlockParams:
  Enabled: false

# We only add the comment when needed.
Style/Encoding:
  Enabled: false

# Having these make it easier to *not* forget to add one when adding a new
# value and you can simply copy the previous line.
Style/TrailingCommaInArrayLiteral:
  EnforcedStyleForMultiline: comma
Style/TrailingCommaInHashLiteral:
  EnforcedStyleForMultiline: comma
Style/TrailingCommaInArguments:
  EnforcedStyleForMultiline: comma

Style/SpecialGlobalVars:
  Enabled: false

Style/MultilineBlockChain:
  Enabled: false

# We prefer explicit `a, _ = arr` to `a, = arr` (which could be misread as a stray comma)
Style/TrailingUnderscoreVariable:
  Enabled: false

# For lambdas nested within certain expressions, this rule forces either ugly
# parens or curly braces that violate the "do/end for multiline blocks" rule.
Style/Lambda:
  Enabled: false

# Disallowing indented "when" clauses destroys readability when using the
# single-line "when/then" style.
Layout/CaseIndentation:
  Enabled: false

# These are both subjective judgements that depend on the situation, and are
# not appropriate as absolute rules.
Style/GuardClause:
  Enabled: false
Style/Next:
  Enabled: false

# Avoid the least-readable varieties of regular expressions.
Style/RegexpLiteral:
  EnforcedStyle: mixed

# Sometimes easier to read either way
Style/AccessorGrouping:
  Enabled: false

# Avoid mandatory wide indentation
Layout/MultilineMethodCallIndentation:
  EnforcedStyle: indented
Layout/LineEndStringConcatenationIndentation:
  Enabled: true
  EnforcedStyle: indented

# Avoid false positives with `Pathname`
Style/StringConcatenation:
  Mode: conservative

# Compatibility with earlier Rubocops
Metrics/CyclomaticComplexity:
  Max: 10
Metrics/PerceivedComplexity:
  Max: 10

# Too much firing on basic arithmetic
Lint/AmbiguousOperatorPrecedence:
  Enabled: false

#- Jazzy specs -----------------------------------------------------------#

# Allow for `should.match /regexp/`.
Lint/AmbiguousRegexpLiteral:
  Exclude:
    - spec/**/*

# Allow `object.should == object` syntax.
Lint/Void:
  Exclude:
    - spec/**/*

Style/ClassAndModuleChildren:
  Exclude:
    - spec/**/*

Lint/BinaryOperatorWithIdenticalOperands:
  Exclude:
    - spec/**/*


================================================
FILE: CHANGELOG.md
================================================
## Master

##### Breaking

* None.

##### Enhancements

* None.

##### Bug Fixes

* None.

## 0.15.4

##### Breaking

* None.

##### Enhancements

* Allow `custom_categories` to specify a regex for a child.  
  [Enrico Zannini](https://github.com/Enricoza)
  [#688](https://github.com/realm/jazzy/issues/688)

* Update Javascript: KaTeX 0.16.25  
  [John Fairhurst](https://github.com/johnfairh)

##### Bug Fixes

* Don't call extension members that do not need documentation
  'undocumented'.  
  [John Fairhurst](https://github.com/johnfairh)

* Work around activesupport vs. concurrent-ruby crash.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1414](https://github.com/realm/jazzy/issues/1414)

* Better identify default implementations.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1420](https://github.com/realm/jazzy/issues/1420)

* Suppress warning on extensions providing default implementations.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1396](https://github.com/realm/jazzy/issues/1396)

## 0.15.3

##### Breaking

* None.

##### Enhancements

* None.

##### Bug Fixes

* Don't crash in SourceKitten when the Swift 6 compiler reports
  educational notes.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1399](https://github.com/realm/jazzy/issues/1399)

## 0.15.2

##### Breaking

* None.

##### Enhancements

* Support Swift 6.0 / Xcode 16.0  
  [John Fairhurst](https://github.com/johnfairh)

##### Bug Fixes

* None.

## 0.15.1

##### Breaking

* None.

##### Enhancements

* None.

##### Bug Fixes

* Restore compatibility with Ruby 2.6  
  [John Fairhurst](https://github.com/johnfairh)
  [#1388](https://github.com/realm/jazzy/issues/1388)

## 0.15.0

##### Breaking

* None.

##### Enhancements

* Update Javascript: typeahead.js 1.3.4, KaTeX 0.16.10  
  [John Fairhurst](https://github.com/johnfairh)

* Support Swift 5.10 with Swift Package Manager projects.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1381](https://github.com/realm/jazzy/issues/1381)

* Support documentation of multiple modules in a single website.  Use
  `--modules` or the config-file `modules` for more control.  See the
  README 'Documenting multiple modules' for more details.  
  [Argjira Mala](https://github.com/argjiramala-tomtom)
  [Pedro Alcobia](https://github.com/PedroAlcobia-TomTom)
  [John Fairhurst](https://github.com/johnfairh)
  [#564](https://github.com/realm/jazzy/issues/564)

* Improve page breadcrumbs to include parent pages and indicate source module
  of extensions from other modules.  
  [John Fairhurst](https://github.com/johnfairh)

* Add `--readme-title` and `--docset-title` to set the titles of the readme
  docs page and the Dash docset independently of the module name.  
  [John Fairhurst](https://github.com/johnfairh)

* Support Swift 5.9 symbolgraph extension symbols.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1368](https://github.com/realm/jazzy/issues/1368)

##### Bug Fixes

* Fix incorrect activesupport usage.  
  [John Fairhurst](https://github.com/johnfairh)

## 0.14.4

##### Breaking

* None.

##### Enhancements

* Update Javascript: jQuery 3.7.1, KaTeX 0.16.8  
  [John Fairhurst](https://github.com/johnfairh)

* Support Swift `package` access control level.  
  [John Fairhurst](https://github.com/johnfairh)

* Initial support for Swift macro declarations.  Requires
  `--swift-build-tool symbolgraph`.  
  [John Fairhurst](https://github.com/johnfairh)

* Support Swift `@_documentation(visibility:)` attribute.  Requires
  `--swift-build-tool spm|xcodebuild`.  
  [John Fairhurst](https://github.com/johnfairh)

##### Bug Fixes

* Issue a warning instead of crashing on declarations without names.  
  [#1325](https://github.com/realm/jazzy/issues/1325)
  [John Fairhurst](https://github.com/johnfairh)

* Fix extension ordering in symbolgraph mode.  
  [John Fairhurst](https://github.com/johnfairh)

* Fix symbolgraph mode crash involving tuple generic constraints.  
  [John Fairhurst](https://github.com/johnfairh)

## 0.14.3

##### Breaking

* None.

##### Enhancements

* Support Swift 5.7 and Xcode 14.  
  [John Fairhurst](https://github.com/johnfairh)

* Update Javascript: jQuery 3.6.1, KaTeX 0.13.5  
  [John Fairhurst](https://github.com/johnfairh)

##### Bug Fixes

* None.

## 0.14.2

##### Breaking

* When building with Swift 5.6 and not passing `—-module` to Jazzy, declarations
  may not be correctly identified as undocumented and docs may include unwanted
  extensions.  Pass `—-module MyModuleName` to fix this.  
  [John Fairhurst](https://github.com/johnfairh)

##### Enhancements

* Support using pre-generated symbolgraph files in Swift symbolgraph mode.  
  [Nathan Wong](https://github.com/esteluk)

* Issue a warning on some combinations of Objective-C flags.  
  [John Fairhurst](https://github.com/johnfairh)
  [#900](https://github.com/realm/jazzy/issues/900)

* Support Swift 5.6.  The bundled `sourcekitten` is a universal binary.  
  [John Fairhurst](https://github.com/johnfairh)

##### Bug Fixes

* In Swift symbolgraph mode, stop including extensions to types that are beneath
  the minimum ACL.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1291](https://github.com/realm/jazzy/issues/1291)

## 0.14.1

##### Breaking

* Support Swift SPI groups.  Swift declarations marked `@_spi` are no longer
  included in docs when `--min-acl` is set to `public` or `open`.  Use
  `--include-spi-declarations` to include docs for these declarations.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1263](https://github.com/realm/jazzy/issues/1263)

##### Enhancements

* Correct line number references with Xcode 13.  
  [John Fairhurst](https://github.com/johnfairh)

* Support `union` declarations in Objective-C headers.  
  [Brian Osborn](https://github.com/bosborn)
  [John Fairhurst](https://github.com/johnfairh)

* Support Swift concurrency features: identify actors and asynchronous
  methods.  
  [John Fairhurst](https://github.com/johnfairh)

##### Bug Fixes

* Improve HTML5 correctness, all themes.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1280](https://github.com/realm/jazzy/issues/1280)

## 0.14.0

##### Breaking

* Require at least Ruby 2.6.3.  

##### Enhancements

* Support DocC-style autolinks and callouts in markdown.  
  [John Fairhurst](https://github.com/johnfairh)

* Add `--source-host` option to support projects hosted on GitLab and
  Bitbucket as well as GitHub.  Options `--source-host-url` and
  `--source-host-files-url` and new Mustache tags replace the 'github' versions
  which remain as back-compatibility aliases.  
  [John Fairhurst](https://github.com/johnfairh)
  [#314](https://github.com/realm/jazzy/issues/314)

* Add `rel="noopener"` to all `target="_blank"` links.  
  [JP Simard](https://github.com/jpsim)

##### Bug Fixes

* Fix source-host line number references in Swift symbolgraph mode, and
  in ObjC mode for references to one-line declarations.  
  [John Fairhurst](https://github.com/johnfairh)

* Fix crash with `` ` ` `` in markdown.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1270](https://github.com/realm/jazzy/issues/1270)

* Fix symbolgraph mode with Xcode 13.  
  [John Fairhurst](https://github.com/johnfairh)

## 0.13.7

The next release of Jazzy will require a minimum of Ruby 2.6.

##### Breaking

* None.

##### Enhancements

* Update JavaScript libraries: jQuery 3.6.0, Lunr 2.3.9,
  KaTeX 0.13.5.  
  [John Fairhurst](https://github.com/johnfairh)

* Support the markdown [footnotes](https://www.markdownguide.org/extended-syntax/#footnotes) extension in all themes.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1246](https://github.com/realm/jazzy/issues/1246)

##### Bug Fixes

* Fix parameter doc comments in Swift symbolgraph mode.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1244](https://github.com/realm/jazzy/issues/1244)

## 0.13.6

##### Breaking

* None.

##### Enhancements

* Support documentation generation from `.swiftmodule` binaries using
  `--swift-build-tool symbolgraph` with Swift 5.3.  
  [John Fairhurst](https://github.com/johnfairh)

##### Bug Fixes

* Always bypass codesigning when building Xcode projects.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1183](https://github.com/realm/jazzy/issues/1183)

## 0.13.5

##### Breaking

* None.

##### Enhancements

* Add search function to `apple` theme.  
  [Giles Payne](https://github.com/komakai)
  [#726](https://github.com/realm/jazzy/issues/726)

* Add option `--[no-]separate-global-declarations` to always create separate
  documentation pages for top-level declarations as well as classes,
  structures, enums etc. even if they don't have members. As part of this,
  improve the main page declaration in all modes.  
  [Nikolay Volosatov](https://github.com/bamx23)
  [John Fairhurst](https://github.com/johnfairh)

##### Bug Fixes

* Style fixes for `apple` and `jony` themes to codeblocks inside lists and
  links.  
  [John Fairhurst](https://github.com/johnfairh)
  [#818](https://github.com/realm/jazzy/issues/818)
  [#1177](https://github.com/realm/jazzy/issues/1177)

## 0.13.4

##### Breaking

* None.

##### Enhancements

* Update JavaScript libraries: jQuery 3.5.1 (all themes), Lunr 2.3.8,
  typeahead.js 1.3.1 (`fullwidth` theme only).  
  [John Fairhurst](https://github.com/johnfairh)

##### Bug Fixes

* Fix warnings from Ruby 2.7.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1185](https://github.com/realm/jazzy/issues/1185)

* Accept `root_url` without trailing slash.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1188](https://github.com/realm/jazzy/issues/1188)

## 0.13.3

##### Breaking

* None.

##### Enhancements

* Added a config option to provide sources of privately hosted pod
  dependencies when using the `--podspec` option.
  `--pod-sources url1,url2,…urlN`.  
  [Jonathan Bailey](https://github.com/jon889)
  [#650](https://github.com/realm/jazzy/issues/650)

* Improve Dash docset support: support online redirection when
  `--root-url` is set, and provide `--docset-playground-url` to
  support docset playground links.  
  [John Fairhurst](https://github.com/johnfairh)

##### Bug Fixes

* Fix module version not being used from podspec.  
  [Jonathan Bailey](https://github.com/jon889)

* Autolink Swift custom attributes/property wrappers.  
  [John Fairhurst](https://github.com/johnfairh)

## 0.13.2

##### Breaking

* None.

##### Enhancements

* Support Xcode 11.4.  Default Objective-C property attributes are now
  stripped from declarations: turn this off with
  `--keep-default-property-attributes`.  
  [John Fairhurst](https://github.com/johnfairh)
  [#829](https://github.com/realm/jazzy/issues/829)

* Render LaTeX expressions written using `$equation$` or `$$equation$$`
  syntax.  
  [Arthur Guiot](https://github.com/arguiot)
  [John Fairhurst](https://github.com/johnfairh)
  [#1156](https://github.com/realm/jazzy/issues/1156)

* Wrap long method names on category pages.  Use `name_html` in custom
  mustache templates to take advantage of this.  
  [John Fairhurst](https://github.com/johnfairh)
  [#995](https://github.com/realm/jazzy/issues/995)

* Support Dash-style `apple_ref` links to specific API items, for more
  stable and human-readable links from external docs.  
  [Paul Cantrell](https://github.com/pcantrell)

##### Bug Fixes

* Don't generate documentation if the `xcodebuild` command fails.  
  [John Fairhurst](https://github.com/johnfairh)
  [jpsim/SourceKitten#643](https://github.com/jpsim/SourceKitten/issues/643)

* Use multi-line parsed declarations in more places including protocol
  methods and typealiases.  
  [John Fairhurst](https://github.com/johnfairh)
  [#896](https://github.com/realm/jazzy/issues/896)

## 0.13.1

##### Breaking

* None.

##### Enhancements

* Allow inline html tags in ObjC doc comments.  
  [Chris Williams](https://github.com/ultramiraculous)
  [#976](https://github.com/realm/jazzy/issues/976)

* Support code formatting in ObjC doc comments with `@c`, `@code` and
  `@endcode`.  
  [Bryce Pauken](https://github.com/brycepauken)
  [jpsim/SourceKitten#631](https://github.com/jpsim/SourceKitten/issues/631)

* Add `custom_categories_unlisted_prefix` configuration setting. This
  is the prefix for navigation section names that aren't explicitly
  listed in `custom_categories`. Defaults to 'Other '.  
  [JP Simard](https://github.com/jpsim)

* Add `hide_unlisted_documentation` configuration setting. Setting this
  to `true` hides documentation entries in the sidebar from the
  `documentation` config value that aren't explicitly listed in
  `custom_categories`.  
  [JP Simard](https://github.com/jpsim)

##### Bug Fixes

* Fix crash when SourceKit returns out of bounds string byte offsets.  
  [JP Simard](https://github.com/jpsim)

* Pick the right version of declarations with type attributes.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1148](https://github.com/realm/jazzy/issues/1148)

## 0.13.0

##### Breaking

* None.

##### Enhancements

* Add section headings for members added by Swift conditional conformances.  
  [John Fairhurst](https://github.com/johnfairh)
  [#717](https://github.com/realm/jazzy/issues/717)

* Parse markdown in MARK comments, make the html available to themes via
  `name_html` mustache tag key for section headings.  
  [John Fairhurst](https://github.com/johnfairh)

* Include protocol conformances added by extensions in Swift docs.  
  [John Fairhurst](https://github.com/johnfairh)

##### Bug Fixes

* Render bullet lists correctly when followed by a callout.  
  [John Fairhurst](https://github.com/johnfairh)
  [#785](https://github.com/realm/jazzy/issues/785)

* Render markup of text inside double quotes.  
  [John Fairhurst](https://github.com/johnfairh)
  [#992](https://github.com/realm/jazzy/issues/992)

* Fix `sourcekitten_sourcefile` used from config file.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1137](https://github.com/realm/jazzy/issues/1137)

## 0.12.0

##### Breaking

* None.

##### Enhancements

* Support for mixed Swift-ObjC modules: generate two sets of SourceKitten
  json and pass them on using `--sourcekitten-sourcefile`.  
  [Joe Susnick](https://github.com/joesus)
  [John Fairhurst](https://github.com/johnfairh)
  [#447](https://github.com/realm/jazzy/issues/447)

##### Bug Fixes

* Stop displaying type attributes on extension declarations.  
  [John Fairhurst](https://github.com/johnfairh)

* Show ObjC and Swift classes (etc.) in the same category.  
  [John Fairhurst](https://github.com/johnfairh)

* Merge Swift extensions into ObjC classes.  
  [John Fairhurst](https://github.com/johnfairh)
  [Joe Susnick](https://github.com/joesus)

## 0.11.2

##### Breaking

* None.

##### Enhancements

* None.

##### Bug Fixes

* Generate Swift docs with Xcode 11 and paths with spaces.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1108](https://github.com/realm/jazzy/issues/1108)

* Reinstate guessing of module name from podspec, broken in 0.11.0.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1109](https://github.com/realm/jazzy/issues/1109)

## 0.11.1

##### Breaking

* None.

##### Enhancements

* None.

##### Bug Fixes

* Don't use SwiftPM if there is an Xcode workspace or project in a non-root
  directory.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1103](https://github.com/realm/jazzy/issues/1103)

## 0.11.0

##### Breaking

* None.

##### Enhancements

* Sass support now provided by `libsass` via `sassc` instead of the
  deprecated Ruby Sass gem.  
  [John Fairhurst](https://github.com/johnfairh)

* Update bundled jQuery to 3.4.1 (all themes).  
  [Paul Idstein](https://github.com/idstein)

* Support Xcode 11 Swift projects that pass a response file to the Swift
  compiler.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1087](https://github.com/realm/jazzy/issues/1087)

* Generate Swift docs from a Swift Package Manager package without
  requiring an Xcode project file.  Add `--swift-build-tool` to choose
  the build method if both `.xcodeproj` and `Package.swift` files are
  present.  Add `--build-tool-flags` as a preferred alias for
  `--xcodebuild-flags`.  
  [John Fairhurst](https://github.com/johnfairh)
  [#487](https://github.com/realm/jazzy/issues/487)

##### Bug Fixes

* Preserve non-latin characters in guide filenames and heading IDs.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1091](https://github.com/realm/jazzy/issues/1091)

* Generate correct html for custom categories containing special
  characters.  
  [John Fairhurst](https://github.com/johnfairh)
  [#945](https://github.com/realm/jazzy/issues/945)

* Fix crash on files with misplaced documentation comments.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1083](https://github.com/realm/jazzy/issues/1083)

## 0.10.0

##### Breaking

* The included `sourcekitten` binary is built with Xcode 10.2.  This means
  it does not run on macOS earlier than 10.14.4 without the *Swift 5 Runtime
  Support for Command Line Tools* being installed.  
  [John Fairhurst](https://github.com/johnfairh)

##### Enhancements

* Support CocoaPods 1.6+.  Use the `swift_version[s]` dsl in `--podspec` mode
  to set the Swift language version.  
  [John Fairhurst](https://github.com/johnfairh)

* Show the extension declaration when documenting Swift extensions.  
  [John Fairhurst](https://github.com/johnfairh)

* Allow docs title customization.  Include `--module-version` when it is set
  and support `--title` to fully customize the title.  Pass `{{module_version}}`
  and `{{docs_title}}` to templates.  
  [Maximilian Alexander](https://github.com/mbalex99)
  [John Fairhurst](https://github.com/johnfairh)
  [#666](https://github.com/realm/jazzy/issues/666)
  [#411](https://github.com/realm/jazzy/issues/411)

##### Bug Fixes

* Unfold member documentation when linked to from current web page.  
  [John Fairhurst](https://github.com/johnfairh)
  [#788](https://github.com/realm/jazzy/issues/788)

* Generate docs when there are unusual characters in source pathnames.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1049](https://github.com/realm/jazzy/issues/1049)

* Generate docs for signed modules with Xcode 10.2.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1057](https://github.com/realm/jazzy/issues/1057)

* Use correct module name when only target name is supplied.  
  [Chris Zielinski](https://github.com/chriszielinski)
  [#422](https://github.com/realm/jazzy/issues/422)

## 0.9.6

This is (probably) the last release to support Ruby earlier than 2.3.
This is due to a change in a dependency.

This is (probably) the last release to support macOS earlier than 10.14.4
without the *Swift 5 Runtime Support for Command Line Tools* package installed.
This is a consequence of Swift 5 ABI stability.

##### Breaking

* None.

##### Enhancements

* Swift 5 support: suppress unwanted newlines and `deinit` declarations.  
  [John Fairhurst](https://github.com/johnfairh)

* Update JavaScript libraries: jQuery 3.3.1 (all themes), Lunr 2.3.5,
  typeahead.js 1.2.1 (`fullwidth` theme only).  
  [John Fairhurst](https://github.com/johnfairh)
  [#901](https://github.com/realm/jazzy/issues/901)

* Avoid `clean build` when using the new Xcode build system.  
  [Norio Nomura](https://github.com/norio-nomura)

##### Bug Fixes

* None.

## 0.9.5

##### Breaking

* None.

##### Enhancements

* Link to documentation pages from contents pages.  
  [John Fairhurst](https://github.com/johnfairh)
  [#730](https://github.com/realm/jazzy/issues/730)

* Call out unavailable and deprecated Objective-C declarations.  
  [Stefan Kieleithner](https://github.com/steviki)
  [John Fairhurst](https://github.com/johnfairh)
  [#843](https://github.com/realm/jazzy/issues/843)

##### Bug Fixes

* Support Swift 4.2 with `--podspec`.  
  [John Fairhurst](https://github.com/johnfairh)
  [#1015](https://github.com/realm/jazzy/issues/1015)

* Fix multiline copyright for `apple` theme.  
  [Fabien Lydoire](https://github.com/fabienlydoire)
  [John Fairhurst](https://github.com/johnfairh)
  [#1016](https://github.com/realm/jazzy/issues/1016)

## 0.9.4

##### Breaking

* None.

##### Enhancements

* None.

##### Bug Fixes

* Fix crash with pre-existing `Docs` directory.  
  [John Fairhurst](https://github.com/johnfairh)
  [#965](https://github.com/realm/jazzy/issues/965)

* Fix crash with unicode scalars in string literals.  
  [John Fairhurst](https://github.com/johnfairh)
  [#972](https://github.com/realm/jazzy/issues/972)

* Fix error compiling a Swift podspec in Xcode 10.  
  [Minh Nguyễn](https://github.com/1ec5)
  [#970](https://github.com/realm/jazzy/issues/970)

## 0.9.3

##### Breaking

* None.

##### Enhancements

* None.

##### Bug Fixes

* Fix crash when specifying empty Swift version. Now correctly uses the default
  Swift version.  
  [JP Simard](https://github.com/jpsim)

* Fix jony theme selection.  
  [John Fairhurst](https://github.com/johnfairh)
  [#962](https://github.com/realm/jazzy/issues/962)

## 0.9.2

##### Breaking

* None.

##### Enhancements

* Add a new 'jony' theme similar to the 2017 Apple documentation style.  
  [Harshil Shah](https://github.com/HarshilShah)

* Add the ability to limit documentation to certain files by passing in an
  `-i`/`--include` argument.  
  [Nick Fox](https://github.com/nicholasffox)
  [#949](https://github.com/realm/jazzy/issues/949)

* Improve Swift declarations to look more like the Xcode Quick Help version,
  for example including `{ get set }`, and include all attributes.  
  [John Fairhurst](https://github.com/johnfairh)
  [#768](https://github.com/realm/jazzy/issues/768)
  [#591](https://github.com/realm/jazzy/issues/591)

##### Bug Fixes

* Preserve `MARK` comment headings associated with extensions and enum cases.  
  [John Fairhurst](https://github.com/johnfairh)

* Fix issue where Overview items were invalidly being referenced with NULL
  types in the generated Dash docset index.  
  [Andrew De Ponte](https://github.com/cyphactor)

* Don't display FIXME or TODO comments as section markers.  
  [John Fairhurst](https://github.com/johnfairh)
  [#658](https://github.com/realm/jazzy/issues/658)

## 0.9.1

##### Breaking

* None.

##### Enhancements

* Added a config option (`--undocumented-text UNDOCUMENTED_TEXT`) to set the
  default text for undocumented symbols.  
  [Akhil Batra](https://github.com/akhillies)
  [#913](https://github.com/realm/jazzy/issues/913)

* Added a config option to hide Objective-C or Swift declarations:
  `--hide-declarations [objc|swift]`.  
  [Ibrahim Ulukaya](https://github.com/ulukaya)
  [#828](https://github.com/realm/jazzy/issues/828)

* Automatically use Swift or Objective-C syntax highlighting for code blocks
  in documentation comments.  Improve Swift highlighting with latest Rouge.  
  [John Fairhurst](https://github.com/johnfairh)
  [#218](https://github.com/realm/jazzy/issues/218)

##### Bug Fixes

* Fix Swift declarations when generating Objective-C docs for generic types.  
  [John Fairhurst](https://github.com/johnfairh)
  [#910](https://github.com/realm/jazzy/issues/910)

* Don't create documentation nodes for generic type parameters.  
  [John Fairhurst](https://github.com/johnfairh)
  [#878](https://github.com/realm/jazzy/issues/878)

## 0.9.0

##### Breaking

* Generate documentation coverage badge locally. Since this avoids the failable
  HTTP request to shields.io previously used to obtain the badge, we've removed
  the `--[no-]download-badge` flag and the corresponding `download_badge`
  YAML configuration key.  
  [Samuel Giddins](https://github.com/segiddins)

##### Enhancements

* None.

##### Bug Fixes

* Fixed issue that prevented Jazzy from running on case sensitive file systems.  
  [Jeremy David Giesbrecht](https://github.com/SDGGiesbrecht)
  [#891](https://github.com/realm/jazzy/issues/891)

* Fixed issue preventing `--podspec` from working with `test_spec`s.  
  [John Fairhurst](https://github.com/johnfairh)
  [#894](https://github.com/realm/jazzy/issues/894)

* Always display correct declaration for undocumented symbols.  
  [John Fairhurst](https://github.com/johnfairh)
  [#864](https://github.com/realm/jazzy/issues/864)

* Trim common indentation in multiline declarations.  
  [John Fairhurst](https://github.com/johnfairh)
  [#836](https://github.com/realm/jazzy/issues/836)

## 0.8.4

##### Breaking

* None.

##### Enhancements

* Align jazzy terminology with Apple usage.  
  [Xiaodi Wu](https://github.com/xwu)
  [John Fairhurst](https://github.com/johnfairh)

* Add `url` attribute that can be more accurate than `{{section}}.html` as a URL
  in custom templates.  
  [John Fairhurst](https://github.com/johnfairh)

##### Bug Fixes

* Fix crash when specifying `swift_version` as a floating point value in
  `.jazzy.yaml` rather than a string.  
  [JP Simard](https://github.com/jpsim)
  [#860](https://github.com/realm/jazzy/issues/860)

* Autolink from parameter documentation and from external markdown documents
  including README.  Autolink to symbols containing & < >.  
  [John Fairhurst](https://github.com/johnfairh)
  [#715](https://github.com/realm/jazzy/issues/715)
  [#789](https://github.com/realm/jazzy/issues/789)
  [#805](https://github.com/realm/jazzy/issues/805)

* Fix Swift 4 declarations containing ampersands (`&`) being truncated.  
  [JP Simard](https://github.com/jpsim)

## 0.8.3

##### Breaking

* None.

##### Enhancements

* Generate Swift declaration for more Objective-C declarations.  
  [Zheng Li](https://github.com/ainopara)

* Improve quality & accuracy of Swift interfaces for Objective-C declarations
  when generating Objective-C docs.  
  [Norio Nomura](https://github.com/norio-nomura)

* Process Swift 3.2/4 doc comments.  
  [John Fairhurst](https://github.com/johnfairh)

##### Bug Fixes

* Fix missing doc comments on some extensions.  
  [John Fairhurst](https://github.com/johnfairh)
  [#454](https://github.com/realm/jazzy/issues/454)

* Fix failure when attempting to download documentation coverage badge with
  jazzy using macOS system Ruby, or a Ruby built with outdated versions of
  OpenSSL.  
  [JP Simard](https://github.com/jpsim)
  [#824](https://github.com/realm/jazzy/issues/824)

* Stop `--skip-undocumented` from skipping documented items nested
  inside extensions of types from other modules.  
  [John Fairhurst](https://github.com/johnfairh)
  [#502](https://github.com/realm/jazzy/issues/502)

* Fix members added to extensions of a nested type showing up in the parent.  
  [John Fairhurst](https://github.com/johnfairh)
  [#333](https://github.com/realm/jazzy/issues/333)

## 0.8.2

##### Breaking

* None.

##### Enhancements

* Report number of included and skipped declarations in CLI output.  
  [John Fairhurst](https://github.com/johnfairh)
  [#238](https://github.com/realm/jazzy/issues/238)

* Build ObjC docs with clang modules enabled by default (`-fmodules` flag).  
  [Maksym Grebenets](https://github.com/mgrebenets)
  [#636](https://github.com/realm/jazzy/issues/636)

* Shave ~1MB from jazzy's gem distribution.  
  [JP Simard](https://github.com/jpsim)

##### Bug Fixes

* Fix support for Ruby 2.2.  
  [John Fairhurst](https://github.com/johnfairh)
  [#801](https://github.com/realm/jazzy/issues/801)

* Fix many cases of incorrect, missing or superfluous docs on Swift
  declarations.  
  [John Fairhurst](https://github.com/johnfairh)

## 0.8.1

##### Breaking

* None.

##### Enhancements

* Allow all markdown in returns and parameter description callouts.  
  [John Fairhurst](https://github.com/johnfairh)
  [#476](https://github.com/realm/jazzy/issues/476)

##### Bug Fixes

* Fix a crash that occurred when a documentation comment ended with an extended
  grapheme cluster.  
  [Lukas Stührk](https://github.com/Lukas-Stuehrk)
  [#794](https://github.com/realm/jazzy/issues/794)
  [SourceKitten#350](https://github.com/jpsim/SourceKitten/issues/350)

## 0.8.0

##### Breaking

* `undocumented.json` is now only in the output directory and is no longer
  copied into docsets.  
  [Jeremy David Giesbrecht](https://github.com/SDGGiesbrecht)
  [#754](https://github.com/realm/jazzy/issues/754)

##### Enhancements

* Add `--[no-]download-badge` flag to skip downloading the documentation
  coverage badge from shields.io. Useful if generating docs offline.  
  [JP Simard](https://github.com/jpsim)
  [#765](https://github.com/realm/jazzy/issues/765)

##### Bug Fixes

* Blank line no longer needed before lists or code blocks.  
  [John Fairhurst](https://github.com/johnfairh)
  [#546](https://github.com/realm/jazzy/issues/546)

* Linking to headers in apple theme gives correct vertical alignment.  
  [John Fairhurst](https://github.com/johnfairh)

* Headers in source code markdown no longer cause corruption.  
  [John Fairhurst](https://github.com/johnfairh)
  [#628](https://github.com/realm/jazzy/issues/628)

## 0.7.5

##### Breaking

* None.

##### Enhancements

* None.

##### Bug Fixes

* Fix issue where using a custom theme would crash jazzy when using Ruby 2.4.  
  [Jason Wray](https://github.com/friedbunny)
  [#752](https://github.com/realm/jazzy/issues/752)

* Fix support for Ruby 2.0.0.  
  [Jason Wray](https://github.com/friedbunny)
  [#747](https://github.com/realm/jazzy/issues/747)

* Fix issue where header files are not found if inside subdirectories of the
  framework_root specified folder.  
  [Christopher Gretzki](https://github.com/gretzki)
  [#518](https://github.com/realm/jazzy/issues/518)

## 0.7.4

##### Breaking

* None.

##### Enhancements

* Generate shields.io badge for documentation coverage, unless
  `hide_documentation_coverage` is set.  
  [Harlan Haskins](https://github.com/harlanhaskins)
  [#723](https://github.com/realm/jazzy/issues/723)

* Add support for searching docs when using the `fullwidth` theme. A new option,
  `--disable-search`, lets you turn this off.  
  [Esad Hajdarevic](https://github.com/esad)
  [Tom MacWright](https://github.com/tmcw)
  [Nadia Barbosa](https://github.com/captainbarbosa)
  [#14](https://github.com/realm/jazzy/issues/14)

* New config option `use_safe_filenames` encodes unsafe characters when
  generating filenames. By default, documentation may receive filenames like
  `/(_:_:).html`. With `use_safe_filenames`, the same file will receive the name
  `_2F_28_5F_3A_5F_3A_29.html` instead.  
  [Jeremy David Giesbrecht](https://github.com/SDGGiesbrecht)
  [#699](https://github.com/realm/jazzy/issues/699)
  [#146](https://github.com/realm/jazzy/issues/146)
  [#361](https://github.com/realm/jazzy/issues/361)
  [#547](https://github.com/realm/jazzy/issues/547)

* References to Objective-C methods are now autolinked.  
  [Minh Nguyễn](https://github.com/1ec5)
  [#362](https://github.com/realm/jazzy/issues/362)

* Print documentation coverage percentage and the number of undocumented
  methods to the command line when running jazzy.  
  [Jason Wray](https://github.com/friedbunny)

##### Bug Fixes

* Fix issue where existing abstracts for non custom sections would be completely
  overwritten when using extra abstract injection with --abstract.  
  [Thibaud Robelain](https://github.com/thibaudrobelain)
  [#600](https://github.com/realm/jazzy/issues/600)

* Fix issue where generic type parameters registered as undocumented symbols.  
  [Jeremy David Giesbrecht](https://github.com/SDGGiesbrecht)
  [#429](https://github.com/realm/jazzy/issues/429)

* Fix issue where parameter and return callouts were duplicated in documentation.  
  [Jeremy David Giesbrecht](https://github.com/SDGGiesbrecht)
  [#673](https://github.com/realm/jazzy/issues/673)

* Fix issue where Objective-C superclass in declaration was unlinked.  
  [Minh Nguyễn](https://github.com/1ec5)
  [#706](https://github.com/realm/jazzy/issues/706)

* Fix issue where multiple Objective-C categories of the same external class
  in different files were merged into one and named after the first category
  found.  
  [Minh Nguyễn](https://github.com/1ec5)
  [#539](https://github.com/realm/jazzy/issues/539)

* String literals in code listings are no longer wrapped in `<q>` tags (`apple`
  and `fullwidth` themes only).  
  [Minh Nguyễn](https://github.com/1ec5)
  [#714](https://github.com/realm/jazzy/issues/714)

* Fix issue where passing a `--podspec` argument would use a malformed
  `SWIFT_VERSION` value, causing compilation to fail.  
  [JP Simard](https://github.com/jpsim)

## 0.7.3

##### Breaking

* None.

##### Enhancements

* Podspec-based documentation will take trunk's `pushed_with_swift_version`
  attribute into account when generating documentation by default.  
  [Orta Therox](https://github.com/orta)

* Podspec-based documentation respects the `swift-version` config option.  
  [Orta Therox](https://github.com/orta)

##### Enhancements

* Support Objective-C class properties.  
  [Jérémie Girault](https://github.com/jeremiegirault)
  [JP Simard](https://github.com/jpsim)

* Support documenting Swift 3 operator precedence groups.  
  [JP Simard](https://github.com/jpsim)

##### Bug Fixes

* Rename Dash typedef type from "Alias" to "Type".  
  [Bogdan Popescu](https://github.com/Kapeli)

* Fix crash when sorting multiple identically named declarations with no USR,
  which is very common when generating docs for podspecs supporting multiple
  platforms.  
  [JP Simard](https://github.com/jpsim)
  [#661](https://github.com/realm/jazzy/issues/661)

* Fix Xcode not being found when specifying a custom Swift version
  (`--swift-version`).  
  [Samuel Giddins](https://github.com/segiddins)
  [Paul Cantrell](https://github.com/pcantrell)
  [#656](https://github.com/realm/jazzy/issues/656)

* Fix crash when generating Objective-C docs for projects with "@" directives in
  documentation comments with Xcode 8.1 or later.  
  [Jérémie Girault](https://github.com/jeremiegirault)

## 0.7.2

##### Breaking

* None.

##### Enhancements

* None.

##### Bug Fixes

* Declarations marked `@available(..., unavailable, ...)` are no longer
  documented.  
  [JP Simard](https://github.com/jpsim)
  [#654](https://github.com/realm/jazzy/issues/654)

* Treat the `open` ACL as more public than `public`.  
  [JP Simard](https://github.com/jpsim)

## 0.7.1

##### Breaking

* None.

##### Enhancements

* Added support for the new access control specifiers of fileprivate and open.  
  [Shmuel Kallner](https://github.com/shmuelk)
  [#645](https://github.com/realm/jazzy/issues/645)
  [#646](https://github.com/realm/jazzy/issues/646)

##### Bug Fixes

* Fix issue where jazzy could not be installed from Gemfile due to
  SourceKitten symlinks already being present.  
  [William Meleyal](https://github.com/meleyal)
  [#438](https://github.com/realm/jazzy/issues/438)

* The lint report in `undocumented.json` is more human-readable: includes fully
  qualified symbol names, pretty printed.  
  [Paul Cantrell](https://github.com/pcantrell)
  [#598](https://github.com/realm/jazzy/issues/598)

* The `exclude` option now properly supports wildcards.  
  [Paul Cantrell](https://github.com/pcantrell)
  [#640](https://github.com/realm/jazzy/issues/640)

## 0.7.0

##### Breaking

* The `docset_platform` option is no longer available. The module name will
  now be used instead of `jazzy`.  
  [JP Simard](https://github.com/jpsim)
  [#423](https://github.com/realm/jazzy/issues/423)

##### Enhancements

* Improved auto-linking behavior to link declarations within declarations and
  fix cases where declarations would link to themselves or their current page.  
  [Esad Hajdarevic](https://github.com/esad)
  [#483](https://github.com/realm/jazzy/issues/483)

##### Bug Fixes

* Fix issue where single-line declaration + bodies in Swift would include the
  body in the parsed declaration.  
  [JP Simard](https://github.com/jpsim)
  [#226](https://github.com/realm/jazzy/issues/226)

* Fix issue where some sections would become empty when using custom groups.  
  [JP Simard](https://github.com/jpsim)
  [#475](https://github.com/realm/jazzy/issues/475)

* Fix issue where directories ending with `.swift` would be considered Swift
  source files.  
  [JP Simard](https://github.com/jpsim)
  [#586](https://github.com/realm/jazzy/issues/586)

## 0.6.3

##### Breaking

* None.

##### Enhancements

* `--exclude` flag now supports excluding directories in addition to files.  
  [Gurrinder](https://github.com/gurrinder)
  [#503](https://github.com/realm/jazzy/issues/503)

* The `cocoapods` gem was updated to 1.0.1 and `rouge` to 1.11.0.  
  [Samuel Giddins](https://github.com/segiddins)
  [#568](https://github.com/realm/jazzy/issues/568)

* Extra markdown documentation can now be included as their own pages in the
  sidebar using the `--documentation` option and in the generated Dash docset
  as Guides.  
  [Karl Bowden](https://github.com/agentk)
  [#435](https://github.com/realm/jazzy/issues/435)

* Section headings can now include additional markdown content using the
  `--abstract` option.  
  [Karl Bowden](https://github.com/agentk)
  [#435](https://github.com/realm/jazzy/issues/435)

* If Swift version is not specified, look for Swift toolchain or clang location
  in the following order:

    * `$XCODE_DEFAULT_TOOLCHAIN_OVERRIDE`
    * `$TOOLCHAIN_DIR`
    * `xcrun -find swift`
    * `/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain`
    * `/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain`
    * `~/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain`
    * `~/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain`

  This will be especially useful once jazzy supports generating docs for
  Swift Package Manager modules with a toolchain not tied to an Xcode release.  
  [JP Simard](https://github.com/jpsim)

##### Bug Fixes

* Don't document clang-unexposed Objective-C declarations.  
  [JP Simard](https://github.com/jpsim)
  [#573](https://github.com/realm/jazzy/issues/573)

## 0.6.2

##### Breaking

* None.

##### Enhancements

* Include one level of nested classes, structs, protocols and enums in the
  navigation bar.  
  [JP Simard](https://github.com/jpsim)
  [#64](https://github.com/realm/jazzy/issues/64)

##### Bug Fixes

* None.

## 0.6.1

##### Breaking

* None.

##### Enhancements

* Objective-C documentation now also includes Swift declarations.  
  [JP Simard](https://github.com/jpsim)
  [#136](https://github.com/realm/jazzy/issues/136)

* Default to the Xcode version selected in `xcode-select` if no Swift version is
  specified.  
  [Samuel Giddins](https://github.com/segiddins)
  [#427](https://github.com/realm/jazzy/issues/427)

##### Bug Fixes

* Uses GitHub-Flavored Markdown syntax for anchors when rendering README pages.  
  [Zachary Waldowski](https://github.com/zwaldowski)
  [#524](https://github.com/realm/jazzy/issues/524)

* Fix crash when using unexposed declarations in Objective-C.  
  [JP Simard](https://github.com/jpsim)
  [#543](https://github.com/realm/jazzy/issues/543)

* No longer document Swift extensions on types with an ACL lower than `min-acl`
  when they contain `MARK`s.  
  [JP Simard](https://github.com/jpsim)
  [#544](https://github.com/realm/jazzy/issues/544)

## 0.6.0

##### Breaking

* Config files now use the same option names as the command line. If you are
  using one of the keys that has changed in your `.jazzy.yaml`, you will receive
  a warning. See the [pull request](https://github.com/realm/jazzy/pull/456) for
  a complete list of changed options. As always, you can get a list of all
  options with `jazzy --help config`.  
  [Paul Cantrell](https://github.com/pcantrell)

* Jazzy's undocumented.txt has been replaced with undocumented.json. This new
  format includes contextual information that one might use to lint
  documentation in an automated fashion.  
  [Jeff Verkoeyen](https://github.com/jverkoey)

* `--swift-version` now defaults to 2.2 instead of 2.1.1.  
  [Tamar Nachmany](https://github.com/tamarnachmany)

##### Enhancements

* Add `--skip-documentation` flag. Skips site generation phase. `undocumented.json`
  is still generated.  
  [Jeff Verkoeyen](https://github.com/jverkoey)

* Merge Objective-C categories into their parent type documentation to match
  Swift behavior.  
  [Esad Hajdarevic](https://github.com/esad)
  [#457](https://github.com/realm/jazzy/issues/457)

* Add support for documenting Swift 2.2 `associatedtype`s and infix, postfix &
  prefix operators.  
  [JP Simard](https://github.com/jpsim)

##### Bug Fixes

* Add support for Objective-C module imports.  
  [JP Simard](https://github.com/jpsim)
  [#452](https://github.com/realm/jazzy/issues/452)

* Workaround for an apparent SourceKit bug which sometimes caused extensions
  to be merged into the wrong type.  
  [Paul Cantrell](https://github.com/pcantrell)
  [#459](https://github.com/realm/jazzy/issues/459)
  [#460](https://github.com/realm/jazzy/issues/460)

## 0.5.0

##### Breaking

* `--swift-version` now defaults to 2.1.1 instead of 2.1.  
  [Nikita Lutsenko](https://github.com/nlutsenko)
  [#416](https://github.com/realm/jazzy/pull/416)

* Swift 1.x is no longer supported.

* `--templates-directory` and `--assets-directory` have been deprecated in favor
  of `--theme`. Specify either 'apple' (default), 'fullwidth' or the path to
  your mustache templates and other assets for a custom theme.  
  [Karl Bowden](https://github.com/agentk)
  [JP Simard](https://github.com/jpsim)
  [#130](https://github.com/realm/jazzy/issues/130)

##### Enhancements

* Add `--sdk [iphone|watch|appletv][os|simulator]|macosx` option for Objective-C
  projects.  
  [Jeff Verkoeyen](https://github.com/jverkoey)

* Add `--head` option to inject custom HTML into `<head></head>`.  
  [JP Simard](https://github.com/jpsim)

##### Bug Fixes

* Fix an issue where extension documentation would use the original type
  documentation block rather than the comment immediately preceding the
  extension.  
  [JP Simard](https://github.com/jpsim)
  [#230](https://github.com/realm/jazzy/issues/230)
  [#313](https://github.com/realm/jazzy/issues/313)
  [#334](https://github.com/realm/jazzy/issues/334)

* Fix multi-byte documentation issues.  
  [Norio Nomura](https://github.com/norio-nomura)
  [#403](https://github.com/realm/jazzy/issues/403)


## 0.4.1

*Note: this is the last official release of jazzy supporting Swift 1.x.*

##### Breaking

* None.

##### Enhancements

* Support "wall of asterisk" documentation comments.  
  [Jeff Verkoeyen](https://github.com/jverkoey)
  [#347](https://github.com/realm/jazzy/issues/347)

* Expanding a token no longer causes the document to 'jump' to the hash.  
  [Jeff Verkoeyen](https://github.com/jverkoey)
  [#352](https://github.com/realm/jazzy/issues/352)

* Autolinking improvements:
  - Autolinks only match `` `ThingsInBackticks` ``, and must match the entire
    string. This prevents spurious matching in prose and sample code.
  - Autolinks supports siblings, ancestors, top-level elements, and
    dot-separated chains starting with any of the above: `someProperty`,
    `SomeType.NestedType.someMethod(_:)`.
  - New `...` wildcard prevents you from having to list all method parameters:
    `someMethod(...)`

  [Paul Cantrell](https://github.com/pcantrell)
  [#327](https://github.com/realm/jazzy/issues/327)
  [#329](https://github.com/realm/jazzy/issues/329)
  [#359](https://github.com/realm/jazzy/issues/359)

* Miscellaneous minor font size, weight, and color adjustments.  
  [Jeff Verkoeyen](https://github.com/jverkoey)

* In-page anchors now appear below the header.  
  [Jeff Verkoeyen](https://github.com/jverkoey)

##### Bug Fixes

* Fix an out-of-bounds exception when generating pragma marks.  
  [JP Simard](https://github.com/jpsim)
  [#370](https://github.com/realm/jazzy/issues/370)

* Add support for C/C++ struct, field & ivar types.  
  [JP Simard](https://github.com/jpsim)
  [#374](https://github.com/realm/jazzy/issues/374)
  [#387](https://github.com/realm/jazzy/issues/387)

* Links to source files on GitHub are no longer broken when `source_directory`
  does not point to the current working directory.  
  [Paul Cantrell](https://github.com/pcantrell)

* When `excluded_files` is specified in a config file, it is now resolved
  relative to the file (like other options) instead of relative to the working
  directory.  
  [Paul Cantrell](https://github.com/pcantrell)


## 0.4.0

##### Breaking

* `--swift-version` now defaults to 2.1 instead of 2.0.  
  [JP Simard](https://github.com/jpsim)

##### Enhancements

* Support for documenting Objective-C projects! 🎉
  Pass `--objc`, `--umbrella-header ...` and `-framework-root ...`.  
  [JP Simard](https://github.com/jpsim)
  [#56](https://github.com/realm/jazzy/issues/56)

* Mentions of top-level declarations in documentation comments are now
  automatically hyperlinked to their reference.  
  [JP Simard](https://github.com/jpsim)

* Jazzy can now read options from a configuration file. The command line
  provides comprehensive help for available options via `jazzy -h config`.  
  [Paul Cantrell](https://github.com/pcantrell)
  [#310](https://github.com/realm/jazzy/pull/310)

* Render special list items (e.g. Throws, See, etc.). See
  https://ericasadun.com/2015/06/14/swift-header-documentation-in-xcode-7/ for
  a complete list.  
  [JP Simard](https://github.com/jpsim)
  [#317](https://github.com/realm/jazzy/issues/317)

* Support for Swift 2.1.  
  [JP Simard](https://github.com/jpsim)

* Swift extensions are now merged with their extended type, rendering a note
  to describe extension default implementations and extension methods.  
  [Paul Cantrell](https://github.com/pcantrell)

##### Bug Fixes

* None.


## 0.3.2

##### Breaking

* None.

##### Enhancements

* None.

##### Bug Fixes

* Fixed an issue that prevented building projects with different schema & module
  names.  
  [JP Simard](https://github.com/jpsim)
  [#259](https://github.com/realm/jazzy/issues/259)

* Hide documentation coverage from header using `--hide-documentation-coverage`.  
  [mbogh](https://github.com/mbogh)
  [#129](https://github.com/realm/jazzy/issues/297)

* Print a more informative error when unable to find an Xcode that has the
  requested Swift version.  
  [Samuel Giddins](https://github.com/segiddins)


## 0.3.1

##### Breaking

* None.

##### Enhancements

* None.

##### Bug Fixes

* Added missing Swift 2 declaration types.  
  [JP Simard](https://github.com/jpsim)


## 0.3.0

##### Breaking

* `--swift-version` now defaults to 2.0 instead of 1.2.  
  [JP Simard](https://github.com/jpsim)

##### Enhancements

* Now supports Swift 2.0 (previous Swift versions are still supported).  
  [JP Simard](https://github.com/jpsim)
  [Samuel Giddins](https://github.com/segiddins)

* Declarations can now be grouped by custom categories defined in a JSON or YAML
  file passed to `--categories`.  
  [Paul Cantrell](https://github.com/pcantrell)

##### Bug Fixes

* "View on GitHub" is now only generated if a GitHub URL is specified.  
  [mbogh](https://github.com/mbogh)
  [#244](https://github.com/realm/jazzy/issues/244)

* Empty extensions are no longer documented.  
  [Paul Cantrell](https://github.com/pcantrell)

* Undocumented enum cases are now supported.  
  [JP Simard](https://github.com/jpsim)
  [#74](https://github.com/realm/jazzy/issues/74)


## 0.2.4

##### Breaking

* None.

##### Enhancements

* Improved how SourceKitten is vendored.  
  [JP Simard](https://github.com/jpsim)

* Show type declaration under its title.  
  [Paul Cantrell](https://github.com/pcantrell)

* Added support for custom assets: pass `--assets-directory` to jazzy.  
  [gurkendoktor](https://github.com/gurkendoktor)

* Added support for custom copyright text: pass `--copyright` to jazzy.  
  [emaloney](https://github.com/emaloney)

##### Bug Fixes

* Fixed a crash when parsing an empty documentation comment.  
  [JP Simard](https://github.com/jpsim)
  [#236](https://github.com/realm/jazzy/issues/236)

* `--exclude` now works properly if its argument is a relative path.  
  [Paul Cantrell](https://github.com/pcantrell)


## 0.2.3

##### Breaking

* None.

##### Enhancements

* The `jazzy` CLI now accepts a `--swift-version` option (defaulting to 1.2),
  and will automatically find an appropriate Xcode installation.  
  [Samuel Giddins](https://github.com/segiddins)
  [#214](https://github.com/realm/jazzy/issues/214)

##### Bug Fixes

* Declarations with no USR will no longer be documented.  
  [JP Simard](https://github.com/jpsim)


## 0.2.2

##### Breaking

* None.

##### Enhancements

* Added support for custom templates: use the `-t`/`--template-directory`
  argument to jazzy.  
  [JP Simard](https://github.com/jpsim)
  [#20](https://github.com/realm/jazzy/issues/20)

##### Bug Fixes

* None.


## 0.2.1

##### Breaking

* None.

##### Enhancements

* Added the ability to ignore certain files by passing in an `-e`/`--exclude`
  argument to jazzy.  
  [JP Simard](https://github.com/jpsim)
  [#173](https://github.com/realm/jazzy/issues/173)

##### Bug Fixes

* None.


## 0.2.0

##### Breaking

* Jazzy now only supports projects using Swift 1.2.  
  [JP Simard](https://github.com/jpsim)
  [#170](https://github.com/realm/jazzy/issues/170)

* Increase default minimum ACL to public.  
  [JP Simard](https://github.com/jpsim)
  [#186](https://github.com/realm/jazzy/issues/186)

##### Enhancements

* Use `key.accessibility` to determine ACL (value coming from SourceKit, which
  is generally more accurate than parsing the declaration for an accessibility
  keyword).  
  [JP Simard](https://github.com/jpsim)
  [#185](https://github.com/realm/jazzy/issues/185)

##### Bug Fixes

* None.


## 0.1.6

##### Breaking

* None.

##### Enhancements

* None.

##### Bug Fixes

* Make the gem installable.  
  [Samuel Giddins](https://github.com/segiddins)


## 0.1.5

##### Breaking

* None.

##### Enhancements

* Added `--readme` command line option.  
  [segiddins](https://github.com/segiddins)
  [#196](https://github.com/realm/jazzy/issues/196)

* Cleaned up front end HTML & CSS.  
  [JP Simard](https://github.com/jpsim)
  [#95](https://github.com/realm/jazzy/issues/95)

* "Show on GitHub" links now link to line-ranges for multi-line definitions.  
  [JP Simard](https://github.com/jpsim)
  [#198](https://github.com/realm/jazzy/issues/198)

##### Bug Fixes

* Fixed issue where docset would contain duplicate files.  
  [JP Simard](https://github.com/jpsim)
  [#204](https://github.com/realm/jazzy/issues/204)

* Fixed installation issues on case-sensitive file systems.  
  [kishikawakatsumi](https://github.com/kishikawakatsumi)

* Fixed out-of-bounds exception when parsing the declaration in files starting
  with a declaration.  
  [JP Simard](https://github.com/jpsim)
  [#30](https://github.com/jpsim/SourceKitten/issues/30)

* Fixed out-of-bounds exception and inaccurate parsed declarations when using
  multibyte characters.  
  [JP Simard](https://github.com/jpsim)
  [#35](https://github.com/jpsim/SourceKitten/issues/35)

* Fixed parsing issues with keyword functions such as `subscript`, `init` and
  `deinit`.  
  [JP Simard](https://github.com/jpsim)
  [#27](https://github.com/jpsim/SourceKitten/issues/27)

* Fixed issues where USR wasn't accurate because dependencies couldn't be
  resolved.  
  [JP Simard](https://github.com/jpsim)

* Allow using a version of Xcode that is symlinked to
  `/Applications/Xcode.app`.  
  [Samuel Giddins](https://github.com/segiddins)


## 0.1.4

##### Breaking

* None.

##### Enhancements

* None.

##### Bug Fixes

* No longer count undocumented externally declared tokens as undocumented.  
  [JP Simard](https://github.com/jpsim)
  [#188](https://github.com/realm/jazzy/issues/188)


## 0.1.3

##### Breaking

* None.

##### Enhancements

* Improve the styling of `dl` elements (parsed key-value pairs).  
  [segiddins](https://github.com/segiddins)

* Raise exceptions if Xcode requirements aren't met.  
  [JP Simard](https://github.com/jpsim)

##### Bug Fixes

* No longer count initializers with parameters as undocumented.  
  [JP Simard](https://github.com/jpsim)
  [#183](https://github.com/realm/jazzy/issues/183)

* No longer crash when a token is missing a USR.  
  [JP Simard](https://github.com/jpsim)
  [#171](https://github.com/realm/jazzy/issues/171)

* Fixed encoding issues in some environments.  
  [James Barrow](https://github.com/Baza207)
  [#152](https://github.com/realm/jazzy/issues/152)

* No longer count undocumented externally declared tokens as undocumented.  
  [JP Simard](https://github.com/jpsim)
  [#188](https://github.com/realm/jazzy/issues/188)

* Fixed `--source-directory` CLI option.  
  [JP Simard](https://github.com/jpsim)
  [#177](https://github.com/realm/jazzy/issues/177)


## 0.1.2

##### Breaking

* None.

##### Enhancements

* Use Menlo for code everywhere.  
  [beltex](https://github.com/beltex)
  [#137](https://github.com/realm/jazzy/issues/137)

##### Bug Fixes

* (Really) fixes installation as a RubyGem.  
  [beltex](https://github.com/beltex)
  [#159](https://github.com/realm/jazzy/issues/159)


## 0.1.1

##### Breaking

* None.

##### Enhancements

* None.

##### Bug Fixes

* Fixes installation as a RubyGem.  
  [Samuel Giddins](https://github.com/segiddins)
  [#159](https://github.com/realm/jazzy/issues/159)


## 0.1.0

[sourcekitten](https://github.com/jpsim/sourcekitten/compare/0.2.7...0.3.1)

##### Breaking

* None.

##### Enhancements

* Add the ability to document a Pod from just a podspec, which allows jazzy to
  run on cocoadocs.org.  
  [Samuel Giddins](https://github.com/segiddins)
  [#58](https://github.com/realm/jazzy/issues/58)

##### Bug Fixes

* De-duplicate the sidebar list of extensions and show all children for an
  extension, regardless of how many extensions on a type there are.  
  [Samuel Giddins](https://github.com/segiddins)


## 0.0.20

[sourcekitten](https://github.com/jpsim/sourcekitten/compare/0.2.6...0.2.7)

##### Breaking

* Don't skip declarations with no documentation comments by default.
  Allow skipping using `--skip-undocumented`.  
  [JP Simard](https://github.com/jpsim)
  [#129](https://github.com/realm/jazzy/issues/129)

##### Enhancements

* Combine abstract and discussion in page overview.  
  [JP Simard](https://github.com/jpsim)
  [#115](https://github.com/realm/jazzy/issues/115)

##### Bug Fixes

* Don't show 'Show in Github' link for types declared in system frameworks.  
  [JP Simard](https://github.com/jpsim)
  [#110](https://github.com/realm/jazzy/issues/110)

## 0.0.19

[sourcekitten](https://github.com/jpsim/sourcekitten/compare/0.2.3...0.2.6)

##### Breaking

None.

##### Enhancements

* Added CHANGELOG.md.  
  [JP Simard](https://github.com/jpsim)
  [#125](https://github.com/realm/jazzy/issues/125)

* Include parse errors in the JSON output & print to STDERR.  
  [JP Simard](https://github.com/jpsim)
  [jpsim/sourcekitten#16](https://github.com/jpsim/sourcekitten/issues/16)

##### Bug Fixes

* Fixed crash when files contained a declaration on the first line.  
  [JP Simard](https://github.com/jpsim)
  [jpsim/sourcekitten#14](https://github.com/jpsim/sourcekitten/issues/14)

* Fixed invalid JSON issue when last file in an Xcode project failed to parse.  
  [JP Simard](https://github.com/jpsim)

* Fixed crash when attempting to parse the declaration of `extension Array`.  
  [JP Simard](https://github.com/jpsim)
  [#126](https://github.com/realm/jazzy/issues/126)


================================================
FILE: CONTRIBUTING.md
================================================
## Code of Conduct

This project adheres to the [Contributor Covenant Code of Conduct](https://realm.io/conduct).
By participating, you are expected to uphold this code. Please report
unacceptable behavior to [info@realm.io](mailto:info@realm.io).

## Tracking changes

All changes should be made via pull requests on GitHub.

When issuing a pull request, please add a summary of your changes to
the `CHANGELOG.md` file.

We follow the same syntax as CocoaPods' CHANGELOG.md:

1. One Markdown unnumbered list item describing the change.
2. Two trailing spaces on the last line describing the change.
3. A list of Markdown hyperlinks to the contributors to the change. One entry
   per line (and there's usually just one contributor).
4. A list of Markdown hyperlinks to the issues the change addresses. One entry
   per line (and there's usually just one hyperlink). Don't link to PRs here.
5. All CHANGELOG.md content is hard-wrapped at 80 characters.

## Updating the integration specs

Jazzy heavily relies on integration tests, but since they're considerably large
and noisy, we keep them in a separate repo
([realm/jazzy-integration-specs](https://github.com/realm/jazzy-integration-specs)).

If you're making a PR towards jazzy that affects the generated docs, please
update the integration specs using the following process:

```shell
git checkout master
git pull
git checkout -
git rebase master
rake bootstrap
bundle exec rake rebuild_integration_fixtures
cd spec/integration_specs
git checkout -b $jazzy_branch_name
git commit -a -m "update for $jazzy_branch_name"
git push
cd ../../
git commit -a -m "update integration specs"
git push
```

You'll need push access to the integration specs repo to do this. You can
request access from one of the maintainers when filing your PR.

You must have Xcode 26.1 beta 1 installed to build the integration specs.

## Making changes to SourceKitten

When changes are landed in the https://github.com/jpsim/SourceKitten repo the
SourceKitten framework located in jazzy must be updated.

The following may be executed from your `jazzy/` directory.

```
cd SourceKitten
git checkout master
git pull
cd ..
rake sourcekitten
git add .
git commit -m "..."
```


================================================
FILE: Dangerfile
================================================
# frozen_string_literal: true

# Warn when there is a big PR
warn('Big PR') if git.lines_of_code > 500

# Don't let testing shortcuts get into master by accident
(git.modified_files + git.added_files - %w[Dangerfile]).each do |file|
  next unless File.file?(file)

  contents = File.read(file)
  if file.start_with?('spec')
    failure("`xit` or `fit` left in tests (#{file})") if contents =~ /^\w*[xf]it/
    failure("`fdescribe` left in tests (#{file})") if contents =~ /^\w*fdescribe/
  end
end

# Sometimes its a README fix, or something like that - which isn't relevant for
# including in a CHANGELOG for example
has_app_changes = !git.modified_files.grep(/lib/).empty?
has_test_changes = !git.modified_files.grep(/spec/).empty?

# Add a CHANGELOG entry for app changes
if !git.modified_files.include?('CHANGELOG.md') && has_app_changes
  failure "Please include a CHANGELOG entry. \nYou can find it at [CHANGELOG.md](https://github.com/realm/jazzy/blob/master/CHANGELOG.md)."
  message 'Note, we hard-wrap at 80 chars and use 2 spaces after the last line.'
end

# Non-trivial amounts of app changes without tests
if git.lines_of_code > 50 && has_app_changes && !has_test_changes
  warn 'This PR may need tests.'
end


================================================
FILE: Gemfile
================================================
# frozen_string_literal: true

source 'https://rubygems.org'

gemspec

group :development do
  # Code style
  gem 'rubocop', '~> 1.18'

  # Tests
  gem 'bacon'
  gem 'mocha'
  gem 'mocha-on-bacon'
  gem 'prettybacon'
  gem 'webmock'

  # Integration tests
  gem 'clintegracon', git: 'https://github.com/mrackwitz/CLIntegracon.git'
  gem 'diffy'

  # Code Review
  gem 'danger'
end


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2014 Realm Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

================================================
FILE: ObjectiveC.md
================================================
This document is about Jazzy's Objective-C documentation generation.

It's intended for users who are having problems after trying to follow the 
examples in the [README](README.md#objective-c). It gives some solutions to
common problems and explains how the system works to help users work through
uncommon problems.

* [How it works](#how-objective-c-docs-generation-works)
* Common problems:
    * [Apple SDK include failure](#problem-apple-sdk-importinclude-failure)
    * [Non-SDK include failure](#problem-non-sdk-include-failure)
    * [Argument list too long](#problem-argument-list-too-long-e2big-and-more)
    * [Enum cases with wrong doc comment](#problem-enum-cases-have-the-wrong-doc-comment)
    * [Swift API versions missing](#problem-swift-api-versions-are-all-missing)
    * [Swift API versions use `Any`](#problem-swift-api-versions-have-any-instead-of-type-name)
    * [Structural `NS_SWIFT_NAME` not working](#problem-structural-ns_swift_name-not-working)

# How Objective-C docs generation works

Jazzy uses `libclang` to generate docs for Objective-C projects. You can think
of this as running some parts of the `clang` compiler against a header file.
Jazzy refers to this header file as the _umbrella header_ but it does not have
to be the umbrella header from a Clang module: it's just the header file that
includes everything to be documented.

This means there are two problems to solve:
1. What `clang` flags are required; and
2. How to pass them to the tools.

Jazzy has two modes here: a smart mode that covers 90% of projects and a direct mode where the user provides all the flags.

> *Important*: Jazzy does _not_ use any Objective-C build settings from your
  Xcode project or `Package.swift`. If your project needs special settings
  such as `#define`s then you need to repeat those in the Jazzy invocation.

## Direct mode

Passing a basic set of `clang` flags looks like this:

```shell
jazzy ...
      --objc
      --build-tool-arguments
          --objc,MyProject/MyProject.h,--,-x,objective-c,
          -isysroot,$(xcrun --show-sdk-path),
          -I,$(pwd),
          -fmodules
```
The `--build-tool-arguments` are arguments to `sourcekitten`. Everything after
the `--` are the `clang` flags that will be used with the header file given 
before the `--`.

You can try these flags outside of Jazzy's environment:
```shell
clang -c -x objective-c -isysroot $(xcrun --show-sdk-path) -I $(pwd) MyProject/MyProject.h -fmodules
```
(The `-c` stops `clang` from trying to link an executable.)

This is a good method of experimenting with compiler flags to get a working
build without getting bogged down in the Jazzy and SourceKitten layers.

## Smart mode

The smart mode takes the variable parts of the basic set of flags and maps
them from Jazzy flags:
```shell
jazzy ...
      --objc
      --umbrella-header MyProject/MyProject.h
      --framework-root $(pwd)
     [--sdk <sdk name>]
```

The `--umbrella-header` maps directly to the file passed to `sourcekitten`.

The `--framework-root` is used for the `-I` include path, as well as every
directory beneath it, recursively. So if your project structure looks like:
```
MyProject/
         Sources/
                Main/
                Extension/
```
... and you pass `--framework-root MyProject`, then the `-I` flags passed to
`clang` are `-I MyProject -I MyProject/Sources -I MyProject/Sources/Main -I
MyProject/Sources/Extension`. This feature helps some projects resolve
`#include` directives.

Finally the `--sdk` option is passed through instead of the default `macosx` to
find the SDK.

## Mixing modes

Do not mix modes. For example do not set both `--umbrella-header` and
`--build-tool-arguments`. Jazzy does not flag this as an error for
historical compatibility reasons, but the results are at best confusing.

# Problem: Apple SDK import/include failure

For example `fatal error: module 'UIKit' not found`.

This means Jazzy is using the wrong SDK: the default is for macOS which does
not have `UIKit`. Use `--sdk iphonesimulator`.

# Problem: Non-SDK include failure

For example `fatal error: 'MyModule/SomeHeader.h' file not found`.

This means `clang` is not being passed the right flags to resolve a `#include` /
`#import`.

Start by finding the header file in the filesystem. You might be able to fix
the problem just by adding extra `-I <path>` flags.

Usually though the problem is that Xcode has done something clever that needs
to be worked around or replicated.

Xcode uses technology including Clang header maps to let files be found using
lines like `#import <ModuleName/Header.h>` even when there is no such
filesystem directory.

To make the Jazzy build work you need to make these `#include`s work. The
solution depends on your project structure. Some suggestions in rough order
of complexity:
* Use symlinks to create an equivalent directory tree. For example if
  `Header.h` is inside `Sources/include` then symlink that directory to
  `ModuleName` and pass `-I $(pwd)`.

* Copy/link your header files into a throwaway directory tree that matches
  the required structure and is used just for building docs.

* Create a 'docs header file' separate to the framework's regular umbrella
  header that contains only filesystem-correct `#import`s.

* If you are happy to build the framework project before generating docs and
  all the problematic paths have the form `ModuleName/PublicHeader.h` then
  have `clang` resolve those includes to the built framework by passing
  `-F <path of directory containing ModuleName.framework>`.

* If you are happy to build the project before generating docs then you may
  be able to use the header maps Xcode has generated. Check the build log in
  Xcode to find them and the invocation syntax.

* Manually construct an equivalent header map. This is complex not least
  because Apple does not make tools or proper documentation available.
  [An open-source starting point](https://milen.me/writings/swift-module-maps-vfs-overlays-header-maps/).

# Problem: Argument list too long `E2BIG` (and more...)

For example ``...open4.rb:49:in `exec': Argument list too long - [...]/bin/sourcekitten (Errno::E2BIG)``

Can also manifest as 'generally weird' errors such as `sourcekitten` just
crashing and `fatal error: could not build module 'Foundation'`.

This means `--framework-root` is trying to add too many include directories:
there are too many subdirectories of its parameter. If you cannot change this
to something more specific that works then you need to use Jazzy's
[direct mode](#direct-mode) to pass in the correct directories.

# Problem: Enum cases have the wrong doc comment

If you write an enum case with a doc comment followed by an enum case without
a doc comment, then both get the same doc comment.

This seems to be a bug in `libclang`. The only workaround is to add the missing
doc comment.

# Problem: Swift API versions are all missing

This usually means the `clang` flags are malformed in a way that is ignored by
`libclang` but not by the Swift Objective-C importer.

One easy way to accidentally do this is passing `-I` without a path, for
example `--build-tool-flags ...,-I,-I,Headers`,....

This also sometimes happens if you are frequently switching back and forth
between some Swift / Xcode versions -- it's a bug somewhere in the Apple tools.
The bad state goes away with time / reboot.

# Problem: Swift API versions have `Any` instead of type name

Jazzy finds the Swift version of an Objective-C API using the SourceKit
`source.request.editor.open.interface.header` request on the header file that
contains the declaration, passing in the same `clang` flags used for the
umbrella header. [See the code](https://github.com/jpsim/SourceKitten/blob/bed112c313ca8c3c149f8cb84069f1c080e86a7e/Source/SourceKittenFramework/Clang%2BSourceKitten.swift#L202).

This means that each header file needs to compile standalone, without
any implicit dependencies. For example:
```
 MyModule.h      // umbrella, includes MyClass.h then Utils.h
    MyClass.h    // @interface MyClass ... @end
    Utils.h      // void my_function( MyClass * myClass);
```
Here, `Utils.h` has an implicit dependency on `MyClass.h` that is normally
satisfied by the include order of `MyModule.h`. One fix that allows `Utils.h`
to compile standalone is to add `@class MyClass;`.

# Problem: Structural `NS_SWIFT_NAME` not working

The `NS_SWIFT_NAME` macro is mostly used to give an Objective-C API a
different name in Swift. There are no known problems with this part.

The macro can also be used to change the 'structure' of an API, for example
make a C global function appear as a member function in Swift, or make a C
class appear as a nested type in Swift.

Jazzy doesn't understand or communicate these structural changes: you'll need
to explain it in doc comments.


================================================
FILE: README.md
================================================
![jazzy](images/logo.jpg)

[![Build Status](https://github.com/realm/jazzy/actions/workflows/Tests.yml/badge.svg)](https://github.com/realm/jazzy/actions/workflows/Tests.yml)

*jazzy is a command-line utility that generates documentation for Swift or Objective-C*

## About

Both Swift and Objective-C projects are supported.

Instead of parsing your source files, `jazzy` hooks into [Clang][clang] and
[SourceKit][sourcekit] to use the [AST][ast] representation of your code and
its comments for more accurate results. The output matches the look and feel
of Apple’s official reference documentation, post WWDC 2014.

Jazzy can also generate documentation from compiled Swift modules [using their
symbol graph](#docs-from-swiftmodules-or-frameworks) instead of source code.

![Screenshot](images/screenshot.jpg)

This project adheres to the [Contributor Covenant Code of Conduct](https://realm.io/conduct).
By participating, you are expected to uphold this code. Please report
unacceptable behavior to [info@realm.io](mailto:info@realm.io).

## Requirements

You need development tools to build the project you wish to document.  Jazzy supports
both [Xcode][xcode] and [Swift Package Manager][spm] projects.

Jazzy expects to be running on __macOS__.  See [below](#linux) for tips to run Jazzy
on Linux.

## Installation

```shell
[sudo] gem install jazzy
```

See [Installation Problems](#installation-problems) for solutions to some
common problems.

## Usage

Run `jazzy` from your command line. Run `jazzy -h` for a list of additional options.

If your Swift module is the first thing to build, and it builds fine when running
`xcodebuild` or `swift build` without any arguments from the root of your project, then
just running `jazzy` (without any arguments) from the root of your project should
succeed too!

If Jazzy generates docs for the wrong module then use `--module` to tell it which
one you'd prefer.  If this doesn't help, and you're using Xcode, then try passing
extra arguments to `xcodebuild`, for example
`jazzy --build-tool-arguments -scheme,MyScheme,-target,MyTarget`.

If you want to generate docs for several modules at once then see [Documenting multiple
modules](#documenting-multiple-modules).

You can set options for your project’s documentation in a configuration file,
`.jazzy.yaml` by default. For a detailed explanation and an exhaustive list of
all available options, run `jazzy --help config`.

### Supported documentation keywords

Swift documentation is written in markdown and supports a number of special keywords.
Here are some resources with tutorials and examples, starting with the most modern:
* Apple's [Writing Symbol Documentation in Your Source Files](https://developer.apple.com/documentation/xcode/writing-symbol-documentation-in-your-source-files) article.
* Apple's [Formatting Your Documentation Content](https://developer.apple.com/documentation/xcode/formatting-your-documentation-content) article.
* Apple's [Xcode Markup Formatting Reference](https://developer.apple.com/library/content/documentation/Xcode/Reference/xcode_markup_formatting_ref/).
* Erica Sadun's [Swift header documentation in Xcode 7](https://ericasadun.com/2015/06/14/swift-header-documentation-in-xcode-7/) post and her [book on Swift Documentation Markup](https://itunes.apple.com/us/book/swift-documentation-markup/id1049010423).

For Objective-C documentation the same keywords are supported, but note that the format
is slightly different. In Swift you would write `- returns:`, but in Objective-C you write `@return`. See Apple's [*HeaderDoc User Guide*](https://developer.apple.com/legacy/library/documentation/DeveloperTools/Conceptual/HeaderDoc/tags/tags.html) for more details. **Note: `jazzy` currently does not support _all_ Objective-C keywords listed in this document, only @param, @return, @warning, @see, @note, @code, @endcode, and @c.**

Jazzy can also generate cross-references within your documentation. A symbol name in
backticks generates a link, for example:
* \`MyClass\` - a link to documentation for `MyClass`.
* \`MyClass.method(param1:)\` - a link to documentation for that method.
* \`MyClass.method(...)\` - shortcut syntax for the same thing.
* \`method(...)\` - shortcut syntax to link to `method` from the documentation of another
  method or property in the same class.
* \`[MyClass method1]\` - a link to an Objective-C method.
* \`-[MyClass method2:param1]\` - a link to another Objective-C method.

Jazzy understands Apple's DocC-style links too, for example:
* \`\`MyClass/method(param1:)\`\` - a link to the documentation for that method
  that appears as just `method(param1:)` in the rendered page.
* \`\`\<doc:method(_:)-e873\>\`\` - a link to a specific overload of `method(_:)`.
  Jazzy can't tell which overload you intend and links to the first one.

If your documentation is for multiple modules then symbol name resolution works
approximately as though all the modules have been imported: you can use \`TypeName\`
to refer to a top-level type in any of the modules, or \`ModuleName.TypeName\` to
be specific.  If there is an ambiguity then you can use a leading slash to
indicate that the first part of the name should be read as a module name:
\`/ModuleName.TypeName\`.

### Math

Jazzy can render math equations written in LaTeX embedded in your markdown:
* `` `$equation$` `` renders the equation in an inline style.
* `` `$$equation$$` `` renders the equation in a display style, centered on a
  line of its own.

For example, the markdown:
```markdown
Inline: `$ax^2+bx+c=0$`

Block: `$$x={\frac {-b\pm {\sqrt {b^{2}-4ac}}}{2a}}$$`
```
..renders as:

![math](images/math.png)

Math support is provided by [KaTeX](https://katex.org).

### Swift

Swift documentation is generated by default.

##### Example

This is how Realm Swift docs are generated:

```shell
jazzy \
  --clean \
  --author Realm \
  --author_url https://realm.io \
  --source-host github \
  --source-host-url https://github.com/realm/realm-cocoa \
  --source-host-files-url https://github.com/realm/realm-cocoa/tree/v0.96.2 \
  --module-version 0.96.2 \
  --build-tool-arguments -scheme,RealmSwift \
  --module RealmSwift \
  --root-url https://realm.io/docs/swift/0.96.2/api/ \
  --output docs/swift_output \
  --theme docs/themes
```

This is how docs are generated for a project that uses the Swift Package Manager:

```shell
jazzy \
  --module DeckOfPlayingCards \
  --swift-build-tool spm \
  --build-tool-arguments -Xswiftc,-swift-version,-Xswiftc,5
```

### Objective-C

To generate documentation for a simple Objective-C project, you must pass the
following parameters:
* `--objc`
* `--umbrella-header ...`
* `--framework-root ...`

...and optionally:
* `--sdk [iphone|watch|appletv][os|simulator]|macosx` (default value
   of `macosx`)
* `--hide-declarations [objc|swift]` (hides the selected language declarations)

For example, this is how the `AFNetworking` docs are generated:

```shell
jazzy \
  --objc \
  --author AFNetworking \
  --author_url http://afnetworking.com \
  --source-host github \
  --source-host-url https://github.com/AFNetworking/AFNetworking \
  --source-host-files-url https://github.com/AFNetworking/AFNetworking/tree/2.6.2 \
  --module-version 2.6.2 \
  --umbrella-header AFNetworking/AFNetworking.h \
  --framework-root . \
  --module AFNetworking
```

For a more complicated Objective-C project, instead use `--build-tool-arguments`
to pass arbitrary compiler flags.  For example, this is how Realm Objective-C
docs are generated:

```shell
jazzy \
  --objc \
  --clean \
  --author Realm \
  --author_url https://realm.io \
  --source-host github \
  --source-host-url https://github.com/realm/realm-cocoa \
  --source-host-files-url https://github.com/realm/realm-cocoa/tree/v2.2.0 \
  --module-version 2.2.0 \
  --build-tool-arguments --objc,Realm/Realm.h,--,-x,objective-c,-isysroot,$(xcrun --show-sdk-path),-I,$(pwd) \
  --module Realm \
  --root-url https://realm.io/docs/objc/2.2.0/api/ \
  --output docs/objc_output \
  --head "$(cat docs/custom_head.html)"
```

See [the Objective-C docs](ObjectiveC.md) for more information and some tips
on troubleshooting.

### Mixed Objective-C / Swift

*This feature has some rough edges.*

To generate documentation for a mixed Swift and Objective-C project you must first
generate two [SourceKitten][sourcekitten] files: one for Swift and one for Objective-C.

Then pass these files to Jazzy together using `--sourcekitten-sourcefile`.

#### Example

This is how docs are generated from an Xcode project for a module containing both
Swift and Objective-C files:

```shell
# Generate Swift SourceKitten output
sourcekitten doc -- -workspace MyProject.xcworkspace -scheme MyScheme > swiftDoc.json

# Generate Objective-C SourceKitten output
sourcekitten doc --objc $(pwd)/MyProject/MyProject.h \
      -- -x objective-c  -isysroot $(xcrun --show-sdk-path --sdk iphonesimulator) \
      -I $(pwd) -fmodules > objcDoc.json

# Feed both outputs to Jazzy as a comma-separated list
jazzy --module MyProject --sourcekitten-sourcefile swiftDoc.json,objcDoc.json
```

### Docs from `.swiftmodule`s or frameworks

Swift 5.3 added support for symbol graph generation from `.swiftmodule` files.

Jazzy can use this to generate API documentation.  This is faster than using
the source code directly but does have limitations: for example documentation
comments are available only for `public` declarations, and the presentation of
Swift extensions may not match the way they are written in code.

Some examples:

1. Generate docs for the Apple Combine framework for macOS:
   ```shell
   jazzy --module Combine --swift-build-tool symbolgraph
   ```
   The SDK's library directories are included in the search path by
   default.
2. Same but for iOS:
   ```shell
   jazzy --module Combine --swift-build-tool symbolgraph
         --sdk iphoneos
         --build-tool-arguments -target,arm64-apple-ios14.1
   ```
   The `target` is the LLVM target triple and needs to match the SDK.  The
   default here is the target of the host system that Jazzy is running on,
   something like `x86_64-apple-darwin19.6.0`.
3. Generate docs for a personal `.swiftmodule`:
   ```shell
   jazzy --module MyMod --swift-build-tool symbolgraph
         --build-tool-arguments -I,/Build/Products
   ```
   This implies that `/Build/Products/MyMod.swiftmodule` exists.  Jazzy's
   `--source-directory` (default current directory) is searched by default,
   so you only need the `-I` override if that's not enough.
4. For a personal framework:
   ```shell
   jazzy --module MyMod --swift-build-tool symbolgraph
         --build-tool-arguments -F,/Build/Products
   ```
   This implies that `/Build/Products/MyMod.framework` exists and contains
   a `.swiftmodule`.  Again the `--source-directory` is searched by default
   if `-F` is not passed in.
5. With pre-generated symbolgraph files:
    ```shell
    jazzy --module MyMod --swift-build-tool symbolgraph
          --symbolgraph-directory Build/symbolgraphs
    ```
    If you've separately generated symbolgraph files by the use of 
    `-emit-symbol-graph`, you can pass the location of these files using
    `--symbolgraph-directory` from where they can be parsed directly.

See `swift symbolgraph-extract -help` for all the things you can pass via
`--build-tool-arguments`: if your module has dependencies then you may need
to add various search path options to let Swift load it.

### Documenting multiple modules

*This feature is new, bugs and feedback welcome*

Sometimes it's useful to document multiple modules together in the same site,
for example an app and its extensions, or an SDK that happens to be implemented
as several modules.

Jazzy can build docs for all these together and create a single site with
search, cross-module linking, and navigation.

#### Build configuration

If all the modules share the same build flags then the easiest way to do this
is with `--modules`, for example `jazzy --modules ModuleA,ModuleB,ModuleC`.

If your modules have different build flags then you have to use the config file.
For example:
```yaml
modules:
  - module: ModuleA
  - module: ModuleB
    build_tool_arguments:
      - -scheme
      - SpecialScheme
      - -target
      - ModuleB
    source_directory: ModuleBProject
  - module: ModuleC
    objc: true
    umbrella_header: ModuleC/ModuleC.h
    framework_root: ModuleC
    sdk: appletvsimulator
  - module: ModuleD
    sourcekitten_sourcefile: [ModuleD1.json, ModuleD2.json]
```
This describes a four-module project of which one is 'normal', one requires
special Xcode treatment, one is Objective-C, and one has prebuilt SourceKitten
JSON.

Per-module options set at the top level are inherited by each module unless
also set locally -- but you can't set both `--module` and `--modules`.

Jazzy doesn't support `--podspec` mode in conjunction with the multiple
modules feature.

#### Presentation

The `--merge-modules` flag controls how declarations from multiple modules
are arranged into categories.

The default of `all` has Jazzy combine declarations from the modules so there
is one category of classes, one of structures, and so on.  To the user this means
they do not worry about which module exports a particular type, although that
information remains available in the type's page.

Setting `--merge-modules none` changes this so each module is a top-level
category, with the module's symbols listed under it.  

Setting `--merge-modules extensions` is like `none` except cross-module
extensions are shown as part of their extended type.  For example if `ModuleA`
extends `ModuleB.SomeType` then those extension members from `ModuleA` are shown
on the `ModuleB.SomeType` page along with the rest of `SomeType`.

You can use `--documentation` to include guides, `custom_categories` to customize
the layout with types from whichever modules you want, and `--abstract` to add
additional markdown content to the per-module category pages.

Use the `--title`, `--readme-title`, and `--docset-title` flags to control the
top-level names of your documentation.  Without these, Jazzy uses the name of one
of the modules being documented.

### Themes

Three themes are provided with jazzy: `apple` (default), `fullwidth` and `jony`.

* `apple` example: <https://johnfairh.github.io/demo-jazzy-apple-theme/>
* `fullwidth` example: <https://reduxkit.github.io/ReduxKit/>
* `jony` example: <https://harshilshah.github.io/IGListKit/>

You can specify which theme to use by passing in the `--theme` option. You can
also provide your own custom theme by passing in the path to your theme
directory.

### Guides

| Description | Command |
| ---         | ---     |
| Command line option | `--documentation={file pattern}` |
| Example             | `--documentation=Docs/*.md` |
| jazzy.yaml example  | `documentation: Docs/*.md` |

By default, jazzy looks for one of README.md, README.markdown, README.mdown or README (in that order) in the directory from where it runs to render the index page at the root of the docs output directory.
Using the `--documentation` option, extra markdown files can be integrated into the generated docs and sidebar navigation.

Any files found matching the file pattern will be parsed and included as a document with the type 'Guide' when generated. If the files are not included using the `custom_categories` config option, they will be grouped under 'Other Guides' in the sidebar navigation.

There are a few limitations:
- File names must be unique from source files.
- Readme should be specified separately using the `readme` option.

You can link to a guide from other guides or doc comments using the name of the page
as it appears in the site.  For example, to link to the guide generated from a file
called `My Guide.md` you would write \`My Guide\`.

### Section description abstracts

| Description | Command |
| ---         | ---     |
| Command line option | `--abstract={file pattern}` |
| Example             | `--abstract=Docs/Sections/*.md` |
| jazzy.yaml example  | `abstract: Docs/Sections/*.md` |

Using the `--abstract` options, extra markdown can be included after the heading of section overview pages. Think of it as a template include.

The list of files matching the pattern is compared against the list of sections generated and if a match is found, it's contents will be included in that section before listing source output.

Unlike the `--documentation` option, these files are not included in navigation and if a file does not match a section title, it is not included at all.

This is very helpful when using `custom_categories` for grouping types and including relevant documentation in those sections.

For an example of a project using both `--documentation` and `--abstract` see: [https://reswift.github.io/ReSwift/](https://reswift.github.io/ReSwift/)

### Controlling what is documented

In Swift mode, Jazzy by default documents only `public` and `open` declarations. To
include declarations with a lower access level, set the `--min-acl` flag to `internal`,
`fileprivate`, or `private`.

By default, Jazzy does not document declarations marked `@_spi` when `--min-acl` is
set to `public` or `open`.  Set the `--include-spi-declarations` flag to include them.

In Objective-C mode, Jazzy documents all declarations found in the `--umbrella-header`
header file and any other header files included by it.

You can control exactly which declarations should be documented using `--exclude`,
`--include`, or `:nodoc:`.

The `--include` and `--exclude` flags list source files that should be included/excluded
respectively in the documentation. Entries in the list can be absolute pathnames beginning
with `/` or relative pathnames. Relative pathnames are interpreted relative to the
directory from where you run `jazzy` or, if the flags are set in the config file, relative
to the directory containing the config file. Entries in the list can match multiple files
using `*` to match any number of characters including `/`.  For example:
* `jazzy --include=/Users/fred/project/Sources/Secret.swift` -- include a specific file
* `jazzy --exclude=/*/Internal*` -- exclude all files with names that begin with *Internal*
  and any files under any directory with a name beginning *Internal*.
* `jazzy --exclude=Impl1/*,Impl2/*` -- exclude all files under the directories *Impl1* and
  *Impl2* found in the current directory.

Note that the `--include` option is applied before the `--exclude` option. For example:

* `jazzy --include=/*/Internal* --exclude=Impl1/*,Impl2/*` -- include all files with names
  that begin with *Internal* and any files under any directory with a name beginning
  *Internal*, **except** for those under the directories *Impl1* and *Impl2* found in the
  current directory

Declarations with a documentation comment containing `:nodoc:` are excluded from the
documentation.

Declarations with the `@_documentation(visibility:)` attribute are treated as though they
are written with the given visibility.  You can use this as a replacement for `:nodoc:` as
part of a transition to Apple's DocC but it is not compatible with Jazzy's symbolgraph mode.

### Documentation structure

Jazzy arranges documentation into categories.  The default categories are things
like _Classes_ and _Structures_ corresponding to programming-language concepts,
as well as _Guides_ if `--documentation` is set.

You can customize the categories and their contents using `custom_categories` in
the config file. `custom_categories` is an array of objects.  Each category must contain two properties:
- `name`: A string with the name you want to give to this category
- `children`: An array used to specify the root level declarations that you want to add to
this category. 

Each child, then, can be one of the following:
- A string, containing either the exact name of one root level declaration you want to
match, or the fully qualified name (`ModuleName.DeclarationName`)
- An object, containing the property:
  - `regex`: a string which will be used to match multiple root level declarations from
all of the modules.

See the ReSwift [docs](https://reswift.github.io/ReSwift/) and
[config file](https://github.com/ReSwift/ReSwift/blob/e94737282850fa038b625b4e351d1608a3d02cee/.jazzy.json)
for an example.

Within each category the items are ordered first alphabetically by source
filename, and then by declaration order within the file.  You can use
`// MARK:` comments within the file to create subheadings on the page, for
example to split up properties and methods.  There’s no way to customize this
order short of editing either the generated web page or the SourceKitten JSON.

Swift extensions and Objective-C categories allow type members to be declared
across multiple source files.  In general, extensions follow the main type
declaration: first extensions from the same source file, then extensions from
other files ordered alphabetically by filename.  Swift conditional extensions
(`extension A where …`) always appear beneath unconditional extensions.

Use this pattern to add or customize the subheading before extension members:
```swift
extension MyType {
  // MARK: Subheading for this group of methods
  …
}
```

When Jazzy is using `--swift-build-tool symgraph` the source file names and
line numbers may not be available. In this case the ordering is approximately
alphabetical by symbol name and USR; the order is stable for the same input.

Jazzy does not normally create separate web pages for declarations that do not
have any members -- instead they are entirely nested into their parent page.  Use
the `--separate-global-declarations` flag to change this and create pages for
these empty types.

### Choosing the Swift language version

Jazzy normally uses the Swift compiler from the Xcode currently configured by
`xcode-select`.  Use the `--swift-version` flag or the `DEVELOPER_DIR` environment
variable to compile with a different Xcode.

The value you pass to `--swift-version` must be the Swift language version given
by `swift --version` in the Xcode you want to use. Jazzy uses
[xcinvoke](https://github.com/segiddins/xcinvoke) to find a suitable Xcode
installation on your system. This can be slow: if you know where Xcode is
installed then it's faster to set `DEVELOPER_DIR` directly.

For example to use Xcode 14:
```shell
jazzy --swift-version 5.7
```
...or:
```shell
DEVELOPER_DIR=/Applications/Xcode_14.app/Contents/Developer jazzy
```

### Dash Docset Support

As well as the browsable HTML documentation, Jazzy creates a _docset_ for use
with the [Dash][dash] app.

By default the docset is created at `docs/docsets/ModuleName.tgz`.  Use
`--docset-path` to create it somewhere else; use `--docset-title` to change
the docset's title.

Use `--docset-playground-url` and `--docset-icon` to further customize the
docset.

If you set both `--root-url` to be the (https://) URL where you plan to deploy
your documentation and `--version` to give your documentation a version number
then Jazzy also creates a docset feed XML file and includes an "Install in Dash"
button on the site.  This lets users who are browsing your documentation on the
web install and start using the docs in Dash locally.

## Linux

Jazzy uses [SourceKitten][sourcekitten] to communicate with the Swift build
environment and compiler.  The `sourcekitten` binary included in the Jazzy gem
is built for macOS and so does not run on other operating systems.

To use Jazzy on Linux you first need to install and build `sourcekitten`
following instructions from [SourceKitten's GitHub repository][sourcekitten].

Then to generate documentation for a SwiftPM project, instead of running just
`jazzy` do:
```shell
sourcekitten doc --spm > doc.json
jazzy --sourcekitten-sourcefile doc.json
```

We hope to improve this process in the future.

## Troubleshooting

### Swift

**Only extensions are listed in the documentation?**

Check the `--min-acl` setting -- see [above](#controlling-what-is-documented).

**Unable to find an Xcode with swift version X**

1. The value passed with `--swift-version` must exactly match the version
   number from `swiftc --version`.  For example Xcode 10.1 needs
   `--swift-version 4.2.1`.  See [the flag documentation](#choosing-the-swift-language-version).
2. The Xcode you want to use must be in the Spotlight index.  You can check
   this using `mdfind 'kMDItemCFBundleIdentifier == com.apple.dt.Xcode'`.
   Some users have reported this issue being fixed by a reboot; `mdutil -E`
   may also help.  If none of these work then you can set the `DEVELOPER_DIR`
   environment variable to point to the Xcode you want before running Jazzy
   without the `--swift-version` flag.

### Objective-C

See [this document](ObjectiveC.md).

### Miscellaneous

**Missing docset**

Jazzy only builds a docset when you set the `--module` or `--modules` flag.

**Unable to pass --build-tool-arguments containing commas**

If you want Jazzy to run something like `xcodebuild -scheme Scheme -destination 'a=x,b=y,c=z'`
then you must use the config file instead of the CLI flag because the CLI parser
that Jazzy uses cannot handle arguments that themselves contain commas.

The example config file here would be:
```yaml
build_tool_arguments:
  - "-scheme"
  - "Scheme"
  - "-destination"
  - "a=x,b=y,c=z"
```

**Errors running in an Xcode Run Script phase**

Running Jazzy from an Xcode build phase can go wrong in cryptic ways when Jazzy
has to run `xcodebuild`.

Users [have reported](https://github.com/realm/jazzy/issues/1012) that error
messages about symbols lacking USRs can be fixed by unsetting
`LLVM_TARGET_TRIPLE_SUFFIX` as part of the run script.

**Warnings about matches and leftovers when using globs and wildcards**

Some flags such as `--include` and `--documentation` support '*' characters as
wildcards.  If you are using the CLI then you must make sure that your shell
does not itself try to interpret them, for example by quoting the token: use
`jazzy --documentation '*.md'` instead of `jazzy --documentation *.md`.

### Installation Problems

**Can't find header files / clang**

Some of the Ruby gems that Jazzy depends on have native C extensions.  This
means you need the Xcode command-line developer tools installed to build
them: run `xcode-select --install` to install the tools.

**/Applications/Xcode: No such file or directory**

The path of your active Xcode installation must not contain spaces.  So
`/Applications/Xcode.app/` is fine, `/Applications/Xcode-10.2.app/` is fine,
but `/Applications/Xcode 10.2.app/` is not.  This restriction applies only
when *installing* Jazzy, not running it.

### MacOS Before 10.14.4

Starting with Jazzy 0.10.0, if you see an error similar to `dyld: Symbol not found: _$s11SubSequenceSlTl` then you need to install the [Swift 5 Runtime Support for Command Line Tools](https://support.apple.com/kb/DL1998).

Alternatively, you can:
* Update to macOS 10.14.4 or later; or
* Install Xcode 10.2 or later at `/Applications/Xcode.app`.

## Development

Please review jazzy's [contributing guidelines](https://github.com/realm/jazzy/blob/master/CONTRIBUTING.md) when submitting pull requests.

jazzy is composed of two parts:

1. The parser, [SourceKitten][SourceKitten] (written in Swift)
2. The site generator (written in ruby)

To build and run jazzy from source:

1. Install [bundler][bundler].
2. Run `bundle install` from the root of this repo.
3. Run jazzy from source by running `bin/jazzy`.

Instructions to build SourceKitten from source can be found at
[SourceKitten's GitHub repository][SourceKitten].

## Design Goals

- Generate source code docs matching Apple's official reference documentation
- Support for standard Objective-C and Swift documentation comment syntax
- Leverage modern HTML templating ([Mustache][mustache])
- Leverage the power and accuracy of the [Clang AST][ast] and [SourceKit][sourcekit]
- Support for Dash docsets
- Support Swift and Objective-C

## License

This project is released under the [MIT license](https://github.com/realm/jazzy/blob/master/LICENSE).

## About

<img src="images/realm.png" width="184" />

Jazzy is maintained and funded by Realm Inc. The names and logos for
Realm are trademarks of Realm Inc.

We :heart: open source software!
See [our other open source projects](https://github.com/realm),
read [our blog](https://realm.io/news) or say hi on twitter
([@realm](https://twitter.com/realm)).

[clang]: https://clang.llvm.org "Clang"
[sourcekit]: https://www.jpsim.com/uncovering-sourcekit "Uncovering SourceKit"
[ast]: https://clang.llvm.org/docs/IntroductionToTheClangAST.html "Introduction To The Clang AST"
[xcode]: https://developer.apple.com/xcode "Xcode"
[SourceKitten]: https://github.com/jpsim/SourceKitten "SourceKitten"
[bundler]: https://rubygems.org/gems/bundler
[mustache]: https://mustache.github.io "Mustache"
[spm]: https://swift.org/package-manager/ "Swift Package Manager"
[dash]: https://kapeli.com/dash/ "Dash"


================================================
FILE: Rakefile
================================================
# frozen_string_literal: true

#-- Bootstrap --------------------------------------------------------------#

desc 'Initializes your working copy to run the specs'
task :bootstrap do
  if system('which bundle')
    title 'Installing gems'
    sh 'bundle install'

    title 'Updating submodules'
    sh 'git submodule update --init --recursive'
  else
    warn "\033[0;31m" \
      "[!] Please install the bundler gem manually:\n" \
      '    $ [sudo] gem install bundler' \
      "\e[0m"
    exit 1
  end
end

begin
  require 'bundler/gem_tasks'
  require 'fileutils'

  task default: :spec

  #-- Specs ------------------------------------------------------------------#

  desc 'Run specs'
  task :spec do
    title 'Running Tests'
    Rake::Task['unit_spec'].invoke
    Rake::Task['objc_spec'].invoke
    Rake::Task['swift_spec'].invoke
    Rake::Task['cocoapods_spec'].invoke
    Rake::Task['rubocop'].invoke
  end

  desc 'Run unit specs'
  task :unit_spec do
    files = FileList['spec/*_spec.rb']
      .exclude('spec/integration_spec.rb').shuffle.join(' ')
    sh "bundle exec bacon #{files}"
  end

  desc 'Run objc integration specs'
  task :objc_spec do
    sh 'JAZZY_SPEC_SUBSET=objc bundle exec bacon spec/integration_spec.rb'
  end

  desc 'Run swift integration specs'
  task :swift_spec do
    sh 'JAZZY_SPEC_SUBSET=swift bundle exec bacon spec/integration_spec.rb'
  end

  desc 'Run cocoapods integration specs'
  task :cocoapods_spec do
    sh 'JAZZY_SPEC_SUBSET=cocoapods bundle exec bacon spec/integration_spec.rb'
  end

  desc 'Rebuilds integration fixtures'
  task :rebuild_integration_fixtures do
    title 'Running Integration tests'
    sh 'rm -rf spec/integration_specs/tmp'
    puts `bundle exec bacon spec/integration_spec.rb`

    title 'Storing fixtures'
    # Copy the files to the files produced by the specs to the after folders
    FileList['tmp/*'].each do |source|
      destination = "spec/integration_specs/#{source.gsub('tmp/', '')}/after"
      if File.exist?(destination)
        sh "rm -rf #{destination}"
        sh "mv #{source}/transformed #{destination}"
      end
    end

    # Remove files not used for the comparison
    # To keep the git diff clean
    specs_root = 'spec/integration_specs/*/after'
    files_glob = "#{specs_root}/{*,.*}"
    files_to_delete = FileList[files_glob]
      .exclude('**/.', '**/..')
      .exclude("#{specs_root}/*docs",
               "#{specs_root}/execution_output.txt")
      .include("#{specs_root}/**/*.dsidx")
      .include("#{specs_root}/**/*.tgz")
    files_to_delete.each do |file_to_delete|
      sh "rm -rf '#{file_to_delete}'"
    end

    puts
    puts 'Integration fixtures updated, see `spec/integration_specs`'
  end

  #-- RuboCop ----------------------------------------------------------------#

  desc 'Runs RuboCop linter on Ruby files'
  task :rubocop do
    sh 'bundle exec rubocop'
  end

  #-- SourceKitten -----------------------------------------------------------#

  desc 'Vendors SourceKitten'
  task :sourcekitten do
    sk_dir = 'SourceKitten'
    bin_path = Dir.chdir(sk_dir) do
      build_cmd = 'swift build -c release --arch arm64 --arch x86_64'
      `#{build_cmd}`
      `#{build_cmd} --show-bin-path`.chomp
    end
    FileUtils.cp_r "#{bin_path}/sourcekitten", 'bin'
  end

  #-- Theme Dependencies -----------------------------------------------------#

  THEME_FILES = {
    'jquery/dist/jquery.min.js' => [
      'themes/apple/assets/js',
      'themes/fullwidth/assets/js',
      'themes/jony/assets/js',
    ],
    'lunr/lunr.min.js' => [
      'themes/apple/assets/js',
      'themes/fullwidth/assets/js',
    ],
    'corejs-typeahead/dist/typeahead.jquery.js' => [
      'themes/apple/assets/js',
      'themes/fullwidth/assets/js',
    ],
    'katex/dist/katex.min.css' => ['extensions/katex/css'],
    'katex/dist/fonts' => ['extensions/katex/css'],
    'katex/dist/katex.min.js' => ['extensions/katex/js'],
  }.freeze

  desc 'Copies theme dependencies (`npm update/install` by hand first)'
  task :theme_deps do
    THEME_FILES.each_pair do |src, dsts|
      dsts.each do |dst|
        FileUtils.cp_r "js/node_modules/#{src}", "lib/jazzy/#{dst}"
      end
    end
  end
rescue LoadError, NameError => e
  warn "\033[0;31m" \
    '[!] Some Rake tasks haven been disabled because the environment' \
    ' couldn’t be loaded. Be sure to run `rake bootstrap` first.' \
    "\e[0m"
  warn e.message
  warn e.backtrace
  warn ''
end

#-- Helpers ------------------------------------------------------------------#

def title(title)
  cyan_title = "\033[0;36m#{title}\033[0m"
  puts
  puts '-' * 80
  puts cyan_title
  puts '-' * 80
  puts
end


================================================
FILE: bin/jazzy
================================================
#!/usr/bin/env ruby
# frozen_string_literal: true

if $PROGRAM_NAME == __FILE__ && !ENV['JAZZY_NO_BUNDLER']
  ENV['BUNDLE_GEMFILE'] = File.expand_path('../Gemfile', __dir__)
  require 'rubygems'
  require 'bundler/setup'
  $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
elsif ENV['JAZZY_NO_BUNDLER']
  require 'rubygems'
  gem 'jazzy'
end

require 'jazzy'

Jazzy::DocBuilder.build(Jazzy::Config.instance = Jazzy::Config.parse!)


================================================
FILE: jazzy.gemspec
================================================
# coding: utf-8
# frozen_string_literal: true

require File.expand_path('lib/jazzy/gem_version.rb', File.dirname(__FILE__))

Gem::Specification.new do |spec|
  spec.name          = 'jazzy'
  spec.version       = Jazzy::VERSION
  spec.authors       = ['JP Simard', 'Tim Anglade', 'Samuel Giddins', 'John Fairhurst']
  spec.email         = ['jp@jpsim.com']
  spec.summary       = 'Soulful docs for Swift & Objective-C.'
  spec.description   = 'Soulful docs for Swift & Objective-C. ' \
    "Run in your SPM or Xcode project's root directory for " \
    'instant HTML docs.'
  spec.homepage      = 'https://github.com/realm/jazzy'
  spec.license       = 'MIT'

  spec.files         = `git ls-files`.split($/)
  spec.executables << 'jazzy'

  spec.add_dependency 'activesupport', '>= 5.0', '< 8'
  spec.add_dependency 'cocoapods', '~> 1.5'
  spec.add_dependency 'logger'
  spec.add_dependency 'mustache', '~> 1.1'
  spec.add_dependency 'open4', '~> 1.3'
  spec.add_dependency 'redcarpet', '~> 3.4'
  spec.add_dependency 'rexml', ['>= 3.2.7', '< 4.0']
  spec.add_dependency 'rouge', ['>= 2.0.6', '< 5.0']
  spec.add_dependency 'sassc', '~> 2.1'
  spec.add_dependency 'sqlite3', '~> 1.3'
  spec.add_dependency 'xcinvoke', '~> 0.3.0'

  spec.add_development_dependency 'bundler', '~> 2.1'
  spec.add_development_dependency 'rake', '~> 13.0'

  spec.required_ruby_version = '>= 2.6.3'
  spec.metadata['rubygems_mfa_required'] = 'true'
end


================================================
FILE: js/package.json
================================================
{
  "name": "jazzy-js",
  "version": "1.0.0",
  "description": "Jazzy theme dependencies",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "MIT",
  "dependencies": {
    "corejs-typeahead": "^1.3.1",
    "jquery": "^3.7.1",
    "katex": "^0.16.8",
    "lunr": "^2.3.9"
  }
}


================================================
FILE: lib/jazzy/config.rb
================================================
# frozen_string_literal: true

require 'optparse'
require 'pathname'
require 'uri'

require 'jazzy/podspec_documenter'
require 'jazzy/source_declaration/access_control_level'

module Jazzy
  # rubocop:disable Metrics/ClassLength
  class Config
    # rubocop:disable Naming/AccessorMethodName
    class Attribute
      attr_reader :name, :description, :command_line, :config_file_key,
                  :default, :parse, :per_module

      def initialize(name, description: nil, command_line: nil,
                     default: nil, parse: ->(x) { x }, per_module: false)
        @name = name.to_s
        @description = Array(description)
        @command_line = Array(command_line)
        @default = default
        @parse = parse
        @config_file_key = full_command_line_name || @name
        @per_module = per_module
      end

      def get(config)
        config.method(name).call
      end

      def set_raw(config, val)
        config.method("#{name}=").call(val)
      end

      def set(config, val, mark_configured: true)
        set_raw(config, config.instance_exec(val, &parse))
        config.method("#{name}_configured=").call(true) if mark_configured
      end

      def set_to_default(config)
        set(config, default, mark_configured: false) if default
      end

      def set_if_unconfigured(config, val)
        set(config, val) unless configured?(config)
      end

      def configured?(config)
        config.method("#{name}_configured").call
      end

      def attach_to_option_parser(config, opt)
        return if command_line.empty?

        opt.on(*command_line, *description) do |val|
          set(config, val)
        end
      end

      private

      def full_command_line_name
        long_option_names = command_line.map do |opt|
          Regexp.last_match(1) if opt.to_s =~ %r{
            ^--           # starts with double dash
            (?:\[no-\])?  # optional prefix for booleans
            ([^\s]+)      # long option name
          }x
        end
        if long_option_name = long_option_names.compact.first
          long_option_name.tr('-', '_')
        end
      end
    end
    # rubocop:enable Naming/AccessorMethodName

    def self.config_attr(name, **opts)
      attr_accessor name
      attr_accessor "#{name}_configured"

      @all_config_attrs ||= []
      @all_config_attrs << Attribute.new(name, **opts)
    end

    def self.alias_config_attr(name, forward, **opts)
      alias_method name.to_s, forward.to_s
      alias_method "#{name}=", "#{forward}="
      alias_method "#{name}_configured", "#{forward}_configured"
      alias_method "#{name}_configured=", "#{forward}_configured="
      @all_config_attrs << Attribute.new(name, **opts)
    end

    class << self
      attr_reader :all_config_attrs
    end

    attr_accessor :base_path

    def expand_glob_path(path)
      Pathname(path).expand_path(base_path) # nil means Pathname.pwd
    end

    def expand_path(path)
      abs_path = expand_glob_path(path)
      Pathname(Dir[abs_path][0] || abs_path) # Use existing filesystem spelling
    end

    def hide_swift?
      hide_declarations == 'swift'
    end

    def hide_objc?
      hide_declarations == 'objc'
    end

    # ──────── Build ────────

    # rubocop:disable Layout/ArgumentAlignment

    config_attr :output,
      description: 'Folder to output the HTML docs to',
      command_line: ['-o', '--output FOLDER'],
      default: 'docs',
      parse: ->(o) { expand_path(o) }

    config_attr :clean,
      command_line: ['-c', '--[no-]clean'],
      description: ['Delete contents of output directory before running. ',
                    'WARNING: If --output is set to ~/Desktop, this will ' \
                      'delete the ~/Desktop directory.'],
      default: false

    config_attr :objc_mode,
      command_line: '--[no-]objc',
      description: 'Generate docs for Objective-C.',
      default: false,
      per_module: true

    config_attr :umbrella_header,
      command_line: '--umbrella-header PATH',
      description: 'Umbrella header for your Objective-C framework.',
      parse: ->(uh) { expand_path(uh) },
      per_module: true

    config_attr :framework_root,
      command_line: '--framework-root PATH',
      description: 'The root path to your Objective-C framework.',
      parse: ->(fr) { expand_path(fr) },
      per_module: true

    config_attr :sdk,
      command_line: '--sdk [iphone|watch|appletv][os|simulator]|macosx',
      description: 'The SDK for which your code should be built.',
      default: 'macosx',
      per_module: true

    config_attr :hide_declarations,
      command_line: '--hide-declarations [objc|swift] ',
      description: 'Hide declarations in the specified language. Given that ' \
        'generating Swift docs only generates Swift declarations, ' \
        'this is useful for hiding a specific interface for ' \
        'either Objective-C or mixed Objective-C and Swift ' \
        'projects.',
      default: ''

    config_attr :keep_property_attributes,
      command_line: '--[no-]keep-property-attributes',
      description: 'Include the default Objective-C property attributes.',
      default: false

    config_attr :config_file,
      command_line: '--config PATH',
      description: ['Configuration file (.yaml or .json)',
                    'Default: .jazzy.yaml in source directory or ancestor'],
      parse: ->(cf) { expand_path(cf) }

    config_attr :build_tool_arguments,
      command_line: ['-b', '--build-tool-arguments arg1,arg2,…argN', Array],
      description: 'Arguments to forward to xcodebuild, swift build, or ' \
        'sourcekitten.',
      default: [],
      per_module: true

    config_attr :modules,
      command_line: ['--modules Mod1,Mod2,…ModN', Array],
      description: 'List of modules to document.  Use the config file to set per-module ' \
        "build flags, see 'Documenting multiple modules' in the README.",
      default: []

    alias_config_attr :xcodebuild_arguments, :build_tool_arguments,
      command_line: ['-x', '--xcodebuild-arguments arg1,arg2,…argN', Array],
      description: 'Back-compatibility alias for build_tool_arguments.'

    config_attr :sourcekitten_sourcefile,
      command_line: ['-s', '--sourcekitten-sourcefile filepath1,…filepathN',
                     Array],
      description: 'File(s) generated from sourcekitten output to parse',
      parse: ->(paths) { [paths].flatten.map { |path| expand_path(path) } },
      default: [],
      per_module: true

    config_attr :source_directory,
      command_line: '--source-directory DIRPATH',
      description: 'The directory that contains the source to be documented',
      default: Pathname.pwd,
      parse: ->(sd) { expand_path(sd) },
      per_module: true

    config_attr :symbolgraph_directory,
      command_line: '--symbolgraph-directory DIRPATH',
      description: 'A directory containing a set of Swift Symbolgraph files ' \
        'representing the module to be documented',
      parse: ->(sd) { expand_path(sd) },
      per_module: true

    config_attr :excluded_files,
      command_line: ['-e', '--exclude filepath1,filepath2,…filepathN', Array],
      description: 'Source file pathnames to be excluded from documentation. ' \
        'Supports wildcards.',
      default: [],
      parse: ->(files) do
        Array(files).map { |f| expand_glob_path(f).to_s }
      end

    config_attr :included_files,
      command_line: ['-i', '--include filepath1,filepath2,…filepathN', Array],
      description: 'Source file pathnames to be included in documentation. ' \
        'Supports wildcards.',
      default: [],
      parse: ->(files) do
        Array(files).map { |f| expand_glob_path(f).to_s }
      end

    config_attr :swift_version,
      command_line: '--swift-version VERSION',
      default: nil,
      parse: ->(v) do
        if v.to_s.empty?
          nil
        elsif v.to_f < 2
          raise 'jazzy only supports Swift 2.0 or later.'
        else
          v
        end
      end

    SWIFT_BUILD_TOOLS = %w[spm xcodebuild symbolgraph].freeze

    config_attr :swift_build_tool,
      command_line: "--swift-build-tool #{SWIFT_BUILD_TOOLS.join(' | ')}",
      description: 'Control whether Jazzy uses Swift Package Manager, ' \
        'xcodebuild, or swift-symbolgraph to build the module ' \
        'to be documented.  By default it uses xcodebuild if ' \
        'there is a .xcodeproj file in the source directory.',
      parse: ->(tool) do
        return tool.to_sym if SWIFT_BUILD_TOOLS.include?(tool)

        raise "Unsupported swift_build_tool #{tool}, " \
          "supported values: #{SWIFT_BUILD_TOOLS.join(', ')}"
      end

    # ──────── Metadata ────────

    config_attr :author_name,
      command_line: ['-a', '--author AUTHOR_NAME'],
      description: 'Name of author to attribute in docs (e.g. Realm)',
      default: ''

    config_attr :author_url,
      command_line: ['-u', '--author_url URL'],
      description: 'Author URL of this project (e.g. https://realm.io)',
      default: '',
      parse: ->(u) { URI(u) }

    config_attr :module_name,
      command_line: ['-m', '--module MODULE_NAME'],
      description: 'Name of module being documented. (e.g. RealmSwift)',
      default: '',
      per_module: true

    config_attr :version,
      command_line: '--module-version VERSION',
      description: 'Version string to use as part of the default docs ' \
        'title and inside the docset.',
      default: '1.0'

    config_attr :title,
      command_line: '--title TITLE',
      description: 'Title to display at the top of each page, overriding the ' \
        'default generated from module name and version.',
      default: ''

    config_attr :copyright,
      command_line: '--copyright COPYRIGHT_MARKDOWN',
      description: 'copyright markdown rendered at the bottom of the docs pages'

    config_attr :readme_path,
      command_line: '--readme FILEPATH',
      description: 'The path to a markdown README file',
      parse: ->(rp) { expand_path(rp) }

    config_attr :readme_title,
      command_line: '--readme-title TITLE',
      description: 'The title for the README in the generated documentation'

    config_attr :documentation_glob,
      command_line: '--documentation GLOB',
      description: 'Glob that matches available documentation',
      parse: ->(dg) { Pathname.glob(dg) }

    config_attr :abstract_glob,
      command_line: '--abstract GLOB',
      description: 'Glob that matches available abstracts for categories',
      parse: ->(ag) { Pathname.glob(ag) }

    config_attr :podspec,
      command_line: '--podspec FILEPATH',
      description: 'A CocoaPods Podspec that describes the Swift library to ' \
        'document',
      parse: ->(ps) { PodspecDocumenter.create_podspec(Pathname(ps)) if ps },
      default: Dir['*.podspec{,.json}'].first

    config_attr :pod_sources,
      command_line: ['--pod-sources url1,url2,…urlN', Array],
      description: 'A list of sources to find pod dependencies. Used only ' \
        'with --podspec when the podspec contains references to ' \
        'privately hosted pods. You must include the default pod ' \
        'source if public pods are also used.',
      default: []

    config_attr :docset_icon,
      command_line: '--docset-icon FILEPATH',
      parse: ->(di) { expand_path(di) }

    config_attr :docset_path,
      command_line: '--docset-path DIRPATH',
      description: 'The relative path for the generated docset'

    config_attr :docset_title,
      command_line: '--docset-title TITLE',
      description: 'The title of the generated docset.  A simplified version ' \
        'is used for the filenames associated with the docset.  If the ' \
        'option is not set then the name of the module being documented is ' \
        'used as the docset title.'

    # ──────── URLs ────────

    config_attr :root_url,
      command_line: ['-r', '--root-url URL'],
      description: 'Absolute URL root where these docs will be stored',
      # ensure trailing slash for correct URI.join()
      parse: ->(r) { URI(r.sub(%r{/?$}, '/')) }

    config_attr :dash_url,
      command_line: ['-d', '--dash_url URL'],
      description: 'Location of the dash XML feed ' \
        'e.g. https://realm.io/docsets/realm.xml)',
      parse: ->(d) { URI(d) }

    SOURCE_HOSTS = %w[github gitlab bitbucket].freeze

    config_attr :source_host,
      command_line: "--source-host #{SOURCE_HOSTS.join(' | ')}",
      description: ['The source-code hosting site to be linked from documentation.',
                    'This setting affects the logo image and link format.',
                    "Default: 'github'"],
      default: 'github',
      parse: ->(host) do
        return host.to_sym if SOURCE_HOSTS.include?(host)

        raise "Unsupported source_host '#{host}', " \
          "supported values: #{SOURCE_HOSTS.join(', ')}"
      end

    config_attr :source_host_url,
      command_line: ['--source-host-url URL'],
      description: ["URL to link from the source host's logo.",
                    'For example https://github.com/realm/realm-cocoa'],
      parse: ->(g) { URI(g) }

    alias_config_attr :github_url, :source_host_url,
      command_line: ['-g', '--github_url URL'],
      description: 'Back-compatibility alias for source_host_url.'

    config_attr :source_host_files_url,
      command_line: '--source-host-files-url PREFIX',
      description: [
        "The base URL on the source host of the project's files, to link " \
          'from individual declarations.',
        'For example https://github.com/realm/realm-cocoa/tree/v0.87.1',
      ]

    alias_config_attr :github_file_prefix, :source_host_files_url,
      command_line: '--github-file-prefix PREFIX',
      description: 'Back-compatibility alias for source_host_files_url'

    config_attr :docset_playground_url,
      command_line: '--docset-playground-url URL',
      description: 'URL of an interactive playground to demonstrate the ' \
        'framework, linked to from the docset.'

    # ──────── Doc generation options ────────
    config_attr :disable_search,
      command_line: '--disable-search',
      description: 'Avoid generating a search index. ' \
        'Search is available in some themes.',
      default: false

    config_attr :skip_documentation,
      command_line: '--skip-documentation',
      description: 'Will skip the documentation generation phase.',
      default: false

    config_attr :min_acl,
      command_line:
         '--min-acl [private | fileprivate | internal | package | public | open]',
      description: 'minimum access control level to document',
      default: 'public',
      parse: ->(acl) do
        SourceDeclaration::AccessControlLevel.from_human_string(acl)
      end

    config_attr :skip_undocumented,
      command_line: '--[no-]skip-undocumented',
      description: "Don't document declarations that have no documentation " \
        'comments.',
      default: false

    config_attr :hide_documentation_coverage,
      command_line: '--[no-]hide-documentation-coverage',
      description: 'Hide "(X% documented)" from the generated documents',
      default: false

    config_attr :custom_categories,
      description: 'Custom navigation categories to replace the standard ' \
        "'Classes', 'Protocols', etc. Types not explicitly named " \
        'in a custom category appear in generic groups at the ' \
        'end.  Example: https://git.io/v4Bcp',
      default: []

    config_attr :custom_categories_unlisted_prefix,
      description: "Prefix for navigation section names that aren't " \
        'explicitly listed in `custom_categories`.',
      default: 'Other '

    config_attr :hide_unlisted_documentation,
      command_line: '--[no-]hide-unlisted-documentation',
      description: "Don't include documentation in the sidebar from the " \
        "`documentation` config value that aren't explicitly " \
        'listed in `custom_categories`.',
      default: false

    config_attr :custom_head,
      command_line: '--head HTML',
      description: 'Custom HTML to inject into <head></head>.',
      default: ''

    BUILTIN_THEME_DIR = Pathname(__dir__) + 'themes'
    BUILTIN_THEMES = BUILTIN_THEME_DIR.children(false).map(&:to_s)

    config_attr :theme_directory,
      command_line: "--theme [#{BUILTIN_THEMES.join(' | ')} | DIRPATH]",
      description: "Which theme to use. Specify either 'apple' (default), " \
        'one of the other built-in theme names, or the path to ' \
        'your mustache templates and other assets for a custom ' \
        'theme.',
      default: 'apple',
      parse: ->(t) do
        if BUILTIN_THEMES.include?(t)
          BUILTIN_THEME_DIR + t
        else
          expand_path(t)
        end
      end

    config_attr :use_safe_filenames,
      command_line: '--use-safe-filenames',
      description: 'Replace unsafe characters in filenames with an encoded ' \
        'representation. This will reduce human readability of ' \
        'some URLs, but may be necessary for projects that ' \
        'expose filename-unfriendly functions such as /(_:_:)',
      default: false

    config_attr :template_directory,
      command_line: ['-t', '--template-directory DIRPATH'],
      description: 'DEPRECATED: Use --theme instead.',
      parse: ->(_) do
        raise '--template-directory (-t) is deprecated: use --theme instead.'
      end

    config_attr :assets_directory,
      command_line: '--assets-directory DIRPATH',
      description: 'DEPRECATED: Use --theme instead.',
      parse: ->(_) do
        raise '--assets-directory is deprecated: use --theme instead.'
      end

    config_attr :undocumented_text,
      command_line: '--undocumented-text UNDOCUMENTED_TEXT',
      description: 'Default text for undocumented symbols. The default ' \
        'is "Undocumented", put "" if no text is required',
      default: 'Undocumented'

    config_attr :separate_global_declarations,
      command_line: '--[no-]separate-global-declarations',
      description: 'Create separate pages for all global declarations ' \
        "(classes, structures, enums etc.) even if they don't " \
        'have children.',
      default: false

    config_attr :include_spi_declarations,
      command_line: '--[no-]include-spi-declarations',
      description: 'Include Swift declarations marked `@_spi` even if ' \
        '--min-acl is set to `public` or `open`.',
      default: false

    MERGE_MODULES = %w[all extensions none].freeze

    config_attr :merge_modules,
      command_line: "--merge-modules #{MERGE_MODULES.join(' | ')}",
      description: 'Control how to display declarations from multiple ' \
        'modules.  `all`, the default, places all declarations of the ' \
        "same kind together.  `none` keeps each module's declarations " \
        'separate.  `extensions` is like `none` but merges ' \
        'cross-module extensions into their extended type.',
      default: 'all',
      parse: ->(merge) do
        return merge.to_sym if MERGE_MODULES.include?(merge)

        raise "Unsupported merge_modules #{merge}, " \
          "supported values: #{MERGE_MODULES.join(', ')}"
      end

    # rubocop:enable Layout/ArgumentAlignment

    def initialize
      self.class.all_config_attrs.each do |attr|
        attr.set_to_default(self)
      end
    end

    def theme_directory=(theme_directory)
      @theme_directory = theme_directory
      Doc.template_path = theme_directory + 'templates'
    end

    def self.parse!
      config = new
      config.parse_command_line
      config.parse_config_file
      PodspecDocumenter.apply_config_defaults(config.podspec, config)

      config.set_module_configs

      config.validate

      config
    end

    def warning(message)
      warn "WARNING: #{message}"
    end

    # rubocop:disable Metrics/MethodLength
    def parse_command_line
      OptionParser.new do |opt|
        opt.banner = 'Usage: jazzy'
        opt.separator ''
        opt.separator 'Options'

        self.class.all_config_attrs.each do |attr|
          attr.attach_to_option_parser(self, opt)
        end

        opt.on('-v', '--version', 'Print version number') do
          puts "jazzy version: #{Jazzy::VERSION}"
          exit
        end

        opt.on('-h', '--help [TOPIC]', 'Available topics:',
               '  usage   Command line options (this help message)',
               '  config  Configuration file options',
               '...or an option keyword, e.g. "dash"') do |topic|
          case topic
          when 'usage', nil
            puts opt
          when 'config'
            print_config_file_help
          else
            print_option_help(topic)
          end
          exit
        end
      end.parse!

      unless ARGV.empty?
        warning "Leftover unused command-line text: #{ARGV}"
      end
    end

    def parse_config_file
      config_path = locate_config_file
      return unless config_path

      self.base_path = config_path.parent

      puts "Using config file #{config_path}"
      config_file = read_config_file(config_path)

      attrs_by_conf_key, attrs_by_name = grouped_attributes

      parse_config_hash(config_file, attrs_by_conf_key, attrs_by_name)
    end

    def parse_config_hash(hash, attrs_by_conf_key, attrs_by_name, override: false)
      hash.each do |key, value|
        unless attr = attrs_by_conf_key[key]
          message = "Unknown config file attribute #{key.inspect}"
          if matching_name = attrs_by_name[key]
            message +=
              " (Did you mean #{matching_name.first.config_file_key.inspect}?)"
          end
          warning message
          next
        end
        setter = override ? :set : :set_if_unconfigured
        attr.first.method(setter).call(self, value)
      end
    end

    # Find keyed versions of the attributes, by config file key and then name-in-code
    # Optional block allows filtering/overriding of attribute list.
    def grouped_attributes
      attrs = self.class.all_config_attrs
      attrs = yield attrs if block_given?
      %i[config_file_key name].map do |property|
        attrs.group_by(&property)
      end
    end

    def validate
      if source_host_configured &&
         source_host_url.nil? &&
         source_host_files_url.nil?
        warning 'Option `source_host` is set but has no effect without either ' \
          '`source_host_url` or `source_host_files_url`.'
      end

      if modules_configured && module_name_configured
        raise 'Options `modules` and `module` are both set which is not supported. ' \
          'To document multiple modules, use just `modules`.'
      end

      if modules_configured && podspec_configured
        raise 'Options `modules` and `podspec` are both set which is not supported.'
      end

      module_configs.each(&:validate_module)
    end

    def validate_module
      if objc_mode &&
         build_tool_arguments_configured &&
         (framework_root_configured || umbrella_header_configured)
        warning 'Option `build_tool_arguments` is set: values passed to ' \
          '`framework_root` or `umbrella_header` may be ignored.'
      end
    end

    # rubocop:enable Metrics/MethodLength

    # Module Configs
    #
    # The user can enter module information in three different ways.  This
    # consolidates them into one view for the rest of the code.
    #
    # 1) Single module, back-compatible
    #    --module Foo etc etc (or not given at all)
    #
    # 2) Multiple modules, simple, sharing build params
    #    --modules Foo,Bar,Baz --source-directory Xyz
    #
    # 3) Multiple modules, custom, different build params but
    #    inheriting others from the top level.
    #    This is config-file only.
    #    - modules
    #      - module: Foo
    #        source_directory: Xyz
    #        build_tool_arguments: [a, b, c]
    #
    # After this we're left with `config.module_configs` that is an
    # array of `Config` objects.

    attr_reader :module_configs
    attr_reader :module_names

    def set_module_configs
      @module_configs = parse_module_configs
      @module_names = module_configs.map(&:module_name)
      @module_names_set = Set.new(module_names)
    end

    def module_name?(name)
      @module_names_set.include?(name)
    end

    def multiple_modules?
      @module_names.count > 1
    end

    def parse_module_configs
      return [self] unless modules_configured

      raise 'Config file key `modules` must be an array' unless modules.is_a?(Array)

      if modules.first.is_a?(String)
        # Massage format (2) into (3)
        self.modules = modules.map { |mod| { 'module' => mod } }
      end

      # Allow per-module overrides of only some config options
      attrs_by_conf_key, attrs_by_name =
        grouped_attributes { |attr| attr.select(&:per_module) }

      modules.map do |module_hash|
        mod_name = module_hash['module'] || ''
        raise 'Missing `modules.module` config key' if mod_name.empty?

        dup.tap do |module_config|
          module_config.parse_config_hash(
            module_hash, attrs_by_conf_key, attrs_by_name, override: true
          )
        end
      end
    end

    # For podspec query
    def module_name_known?
      module_name_configured || modules_configured
    end

    def locate_config_file
      return config_file if config_file

      source_directory.ascend do |dir|
        candidate = dir.join('.jazzy.yaml')
        return candidate if candidate.exist?
      end
      nil
    end

    def read_config_file(file)
      case File.extname(file)
        when '.json'
          JSON.parse(File.read(file))
        when '.yaml', '.yml'
          YAML.safe_load(File.read(file))
        else raise "Config file must be .yaml or .json, but got #{file.inspect}"
      end
    end

    def print_config_file_help
      puts <<-_EOS_

        By default, jazzy looks for a file named ".jazzy.yaml" in the source
        directory and its ancestors. You can override the config file location
        with --config.

        (The source directory is the current working directory by default.
        You can override that with --source-directory.)

        The config file can be in YAML or JSON format. Available options are:

      _EOS_
        .gsub(/^ +/, '')

      print_option_help
    end

    def print_option_help(topic = '')
      found = false
      self.class.all_config_attrs.each do |attr|
        match = ([attr.name] + attr.command_line).any? do |opt|
          opt.to_s.include?(topic)
        end
        if match
          found = true
          puts
          puts attr.name.to_s.tr('_', ' ').upcase
          puts
          puts "  Config file:   #{attr.config_file_key}"
          cmd_line_forms = attr.command_line.select { |opt| opt.is_a?(String) }
          if cmd_line_forms.any?
            puts "  Command line:  #{cmd_line_forms.join(', ')}"
          end
          puts
          print_attr_description(attr)
        end
      end
      warn "Unknown help topic #{topic.inspect}" unless found
    end

    def print_attr_description(attr)
      attr.description.each { |line| puts "  #{line}" }
      if attr.default && attr.default != ''
        puts "  Default: #{attr.default}"
      end
    end

    #-------------------------------------------------------------------------#

    # @!group Singleton

    # @return [Config] the current config instance creating one if needed.
    #
    def self.instance
      @instance ||= new
    end

    # Sets the current config instance. If set to nil the config will be
    # recreated when needed.
    #
    # @param  [Config, Nil] the instance.
    #
    # @return [void]
    #
    class << self
      attr_writer :instance
    end

    # Provides support for accessing the configuration instance in other
    # scopes.
    #
    module Mixin
      def config
        Config.instance
      end
    end
  end
  # rubocop:enable Metrics/ClassLength
end


================================================
FILE: lib/jazzy/doc.rb
================================================
# frozen_string_literal: true

require 'date'
require 'pathname'
require 'mustache'

require 'jazzy/config'
require 'jazzy/gem_version'
require 'jazzy/jazzy_markdown'

module Jazzy
  class Doc < Mustache
    include Config::Mixin

    self.template_name = 'doc'

    def copyright
      copyright = config.copyright || (
        # Fake date is used to keep integration tests consistent
        date = ENV['JAZZY_FAKE_DATE'] || DateTime.now.strftime('%Y-%m-%d')
        year = date[0..3]
        "&copy; #{year} [#{config.author_name}](#{config.author_url}). " \
          "All rights reserved. (Last updated: #{date})"
      )
      Markdown.render_copyright(copyright).chomp
    end

    def jazzy_version
      # Fake version is used to keep integration tests consistent
      ENV['JAZZY_FAKE_VERSION'] || Jazzy::VERSION
    end

    def objc_first?
      config.objc_mode && config.hide_declarations != 'objc'
    end

    def language_stub
      objc_first? ? 'objc' : 'swift'
    end

    def module_version
      config.version_configured ? config.version : nil
    end

    def docs_title
      if config.title_configured
        config.title
      elsif config.version_configured
        # Fake version for integration tests
        version = ENV['JAZZY_FAKE_MODULE_VERSION'] || config.version
        "#{config.module_configs.first.module_name} #{version} Docs"
      else
        "#{config.module_configs.first.module_name} Docs"
      end
    end

    def enable_katex
      Markdown.has_math
    end
  end
end


================================================
FILE: lib/jazzy/doc_builder.rb
================================================
# frozen_string_literal: true

require 'fileutils'
require 'mustache'
require 'pathname'
require 'sassc'

require 'jazzy/config'
require 'jazzy/doc'
require 'jazzy/docset_builder'
require 'jazzy/documentation_generator'
require 'jazzy/search_builder'
require 'jazzy/jazzy_markdown'
require 'jazzy/podspec_documenter'
require 'jazzy/source_declaration'
require 'jazzy/source_document'
require 'jazzy/source_module'
require 'jazzy/sourcekitten'
require 'jazzy/symbol_graph'

module Jazzy
  # This module handles HTML generation, file writing, asset copying,
  # and generally building docs given sourcekitten output
  module DocBuilder
    # mkdir -p output directory and clean if option is set
    def self.prepare_output_dir(output_dir, clean)
      FileUtils.rm_r output_dir if clean && output_dir.directory?
      FileUtils.mkdir_p output_dir
    end

    # Generate doc structure to be used in sidebar navigation
    # @return [Array] doc structure comprised of
    #                     section names & child names & URLs
    def self.doc_structure_for_docs(docs)
      docs
        .map do |doc|
          children = children_for_doc(doc)
          {
            section: doc.name,
            url: doc.url,
            children: children,
          }
        end
        .select do |structure|
          if Config.instance.hide_unlisted_documentation
            unlisted_prefix = Config.instance.custom_categories_unlisted_prefix
            structure[:section] != "#{unlisted_prefix}Guides"
          else
            true
          end
        end
    end

    def self.children_for_doc(doc)
      doc.children
        .sort_by { |c| [c.nav_order, c.name, c.usr || ''] }
        .flat_map do |child|
        # FIXME: include arbitrarily nested extensible types
        [{ name: child.name, url: child.url }] +
          Array(child.children.select do |sub_child|
            sub_child.type.swift_extensible? || sub_child.type.extension?
          end).map do |sub_child|
            { name: "– #{sub_child.name}", url: sub_child.url }
          end
      end
    end

    # Build documentation from the given options
    # @param [Config] options
    def self.build(options)
      module_jsons = options.module_configs.map do |module_config|
        if module_config.podspec_configured
          # Config#validate guarantees not multi-module here
          pod_documenter = PodspecDocumenter.new(options.podspec)
          pod_documenter.sourcekitten_output(options)
        elsif !module_config.sourcekitten_sourcefile.empty?
          "[#{module_config.sourcekitten_sourcefile.map(&:read).join(',')}]"
        elsif module_config.swift_build_tool == :symbolgraph
          SymbolGraph.build(module_config)
        else
          Dir.chdir(module_config.source_directory) do
            arguments = SourceKitten.arguments_from_options(module_config)
            SourceKitten.run_sourcekitten(arguments)
          end
        end
      end

      build_docs_for_sourcekitten_output(module_jsons, options)
    end

    # Build & write HTML docs to disk from structured docs array
    # @param [String] output_dir Root directory to write docs
    # @param [SourceModule] source_module All info to generate docs
    def self.build_docs(output_dir, source_module)
      each_doc(output_dir, source_module.docs) do |doc, path|
        prepare_output_dir(path.parent, false)
        depth = path.relative_path_from(output_dir).each_filename.count - 1
        path_to_root = '../' * depth
        path.open('w') do |file|
          file.write(document(source_module, doc, path_to_root))
        end
      end
    end

    def self.each_doc(output_dir, docs, &block)
      docs.each do |doc|
        next unless doc.render_as_page?

        # Filepath is relative to documentation root:
        path = output_dir + doc.filepath
        block.call(doc, path)
        each_doc(
          output_dir,
          doc.children,
          &block
        )
      end
    end

    def self.build_site(docs, coverage, options)
      warn 'building site'

      structure = doc_structure_for_docs(docs)

      docs << SourceDocument.make_index(options.readme_path)

      output_dir = options.output

      docset_builder = DocsetBuilder.new(output_dir)

      source_module = SourceModule.new(docs, structure, coverage, docset_builder)

      build_docs(output_dir, source_module)

      unless options.disable_search
        warn 'building search index'
        SearchBuilder.build(source_module, output_dir)
      end

      copy_extensions(source_module, output_dir)
      copy_theme_assets(output_dir)

      docset_builder.build!(source_module.all_declarations)

      generate_badge(source_module.doc_coverage, options)

      friendly_path = relative_path_if_inside(output_dir, Pathname.pwd)
      puts "jam out ♪♫ to your fresh new docs in `#{friendly_path}`"

      source_module
    end

    # Build docs given sourcekitten output
    # @param [Array<String>] sourcekitten_output Output of sourcekitten command for each module
    # @param [Config] options Build options
    def self.build_docs_for_sourcekitten_output(sourcekitten_output, options)
      (docs, stats) = SourceKitten.parse(
        sourcekitten_output,
        options,
        DocumentationGenerator.source_docs,
      )

      prepare_output_dir(options.output, options.clean)

      stats.report

      unless options.skip_documentation
        build_site(docs, stats.doc_coverage, options)
      end

      write_lint_report(stats.undocumented_decls, options)
    end

    def self.relative_path_if_inside(path, base_path)
      relative = path.relative_path_from(base_path)
      if relative.to_path =~ %r{/^..(/|$)/}
        path
      else
        relative
      end
    end

    def self.undocumented_warnings(decls)
      decls.map do |decl|
        {
          file: decl.file,
          line: decl.start_line || decl.line,
          symbol: decl.fully_qualified_name,
          symbol_kind: decl.type.kind,
          warning: 'undocumented',
        }
      end
    end

    def self.write_lint_report(undocumented, options)
      (options.output + 'undocumented.json').open('w') do |f|
        warnings = undocumented_warnings(undocumented)

        lint_report = {
          warnings: warnings.sort_by do |w|
            [w[:file] || Pathname(''),
             w[:line] || 0,
             w[:symbol],
             w[:symbol_kind]]
          end,
          source_directory: options.source_directory,
        }
        f.write(JSON.pretty_generate(lint_report))
      end
    end

    def self.copy_theme_assets(destination)
      assets_directory = Config.instance.theme_directory + 'assets'
      FileUtils.cp_r(assets_directory.children, destination)
      Pathname.glob(destination + 'css/**/*.scss').each do |scss|
        css = SassC::Engine.new(scss.read).render
        css_filename = scss.sub(/\.scss$/, '')
        css_filename.open('w') { |f| f.write(css) }
        FileUtils.rm scss
      end
    end

    def self.copy_extensions(source_module, destination)
      if source_host = source_module.host&.extension
        copy_extension(source_host, destination)
      end
      copy_extension('katex', destination) if Markdown.has_math
    end

    def self.copy_extension(name, destination)
      ext_directory = Pathname(__dir__) / 'extensions' / name
      FileUtils.cp_r(ext_directory.children, destination)
    end

    def self.render(doc_model, markdown)
      html = Markdown.render(markdown)
      SourceKitten.autolink_document(html, doc_model)
    end

    def self.render_inline(doc_model, markdown)
      html = Markdown.render_inline(markdown)
      SourceKitten.autolink_document(html, doc_model)
    end

    # Build Mustache document - common fields between page types
    def self.new_document(source_module, doc_model)
      Doc.new.tap do |doc|
        doc[:custom_head] = Config.instance.custom_head
        doc[:disable_search] = Config.instance.disable_search
        doc[:doc_coverage] = source_module.doc_coverage unless
          Config.instance.hide_documentation_coverage
        doc[:structure] = source_module.doc_structure
        doc[:readme_title] = source_module.readme_title
        doc[:module_name] = doc[:readme_title]
        doc[:author_name] = source_module.author_name
        if source_host = source_module.host
          doc[:source_host_name] = source_host.name
          doc[:source_host_url] = source_host.url
          doc[:source_host_image] = source_host.image
          doc[:source_host_item_url] = source_host.item_url(doc_model)
          doc[:github_url] = doc[:source_host_url]
          doc[:github_token_url] = doc[:source_host_item_url]
        end
        doc[:dash_url] = source_module.dash_feed_url
        doc[:breadcrumbs] = make_breadcrumbs(doc_model)
      end
    end

    # Build Mustache document from a markdown source file
    # @param [SourceModule] module-wide settings
    # @param [Hash] doc_model Parsed doc. @see SourceKitten.parse
    # @param [String] path_to_root
    def self.document_markdown(source_module, doc_model, path_to_root)
      doc = new_document(source_module, doc_model)
      name = doc_model.readme? ? source_module.readme_title : doc_model.name
      doc[:name] = name
      doc[:overview] = render(doc_model, doc_model.content(source_module))
      doc[:path_to_root] = path_to_root
      doc[:hide_name] = true
      doc.render.gsub(ELIDED_AUTOLINK_TOKEN, path_to_root)
    end

    # Returns the appropriate color for the provided percentage,
    # used for generating a badge on shields.io
    # @param [Number] coverage The documentation coverage percentage
    def self.color_for_coverage(coverage)
      if coverage < 10
        'e05d44' # red
      elsif coverage < 30
        'fe7d37' # orange
      elsif coverage < 60
        'dfb317' # yellow
      elsif coverage < 85
        'a4a61d' # yellowgreen
      elsif coverage < 90
        '97CA00' # green
      else
        '4c1' # brightgreen
      end
    end

    # rubocop:disable Metrics/MethodLength

    # Generates an SVG similar to those from shields.io displaying the
    # documentation percentage
    # @param [Number] coverage The documentation coverage percentage
    # @param [Config] options Build options
    def self.generate_badge(coverage, options)
      return if options.hide_documentation_coverage

      coverage_length = coverage.to_s.size.succ
      percent_string_length = coverage_length * 80 + 10
      percent_string_offset = coverage_length * 40 + 975
      width = coverage_length * 8 + 104
      svg = <<-SVG.gsub(/^ {8}/, '')
        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="#{width}" height="20">
          <linearGradient id="b" x2="0" y2="100%">
            <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
            <stop offset="1" stop-opacity=".1"/>
          </linearGradient>
          <clipPath id="a">
            <rect width="#{width}" height="20" rx="3" fill="#fff"/>
          </clipPath>
          <g clip-path="url(#a)">
            <path fill="#555" d="M0 0h93v20H0z"/>
            <path fill="##{color_for_coverage(coverage)}" d="M93 0h#{percent_string_length / 10 + 10}v20H93z"/>
            <path fill="url(#b)" d="M0 0h#{width}v20H0z"/>
          </g>
          <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110">
            <text x="475" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="830">
              documentation
            </text>
            <text x="475" y="140" transform="scale(.1)" textLength="830">
              documentation
            </text>
            <text x="#{percent_string_offset}" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="#{percent_string_length}">
              #{coverage}%
            </text>
            <text x="#{percent_string_offset}" y="140" transform="scale(.1)" textLength="#{percent_string_length}">
              #{coverage}%
            </text>
          </g>
        </svg>
      SVG

      badge_output = options.output + 'badge.svg'
      File.open(badge_output, 'w') { |f| f << svg }
    end
    # rubocop:enable Metrics/MethodLength

    # Build mustache item for a top-level doc
    # @param [Hash] item Parsed doc child item
    # @param [Config] options Build options
    # rubocop:disable Metrics/MethodLength
    def self.render_item(item, source_module)
      # Combine abstract and discussion into abstract
      abstract = (item.abstract || '') + (item.discussion || '')
      source_host_item_url = source_module.host&.item_url(item)
      {
        name: item.name,
        name_html: item.name.gsub(':', ':<wbr>'),
        abstract: abstract,
        declaration: item.display_declaration,
        language: item.display_language,
        other_language_declaration: item.display_other_language_declaration,
        usr: item.usr,
        dash_type: item.type.dash_type,
        source_host_item_url: source_host_item_url,
        github_token_url: source_host_item_url,
        default_impl_abstract: item.default_impl_abstract,
        from_protocol_extension: item.from_protocol_extension,
        return: item.return,
        parameters: (item.parameters if item.parameters.any?),
        url: (item.url if item.render_as_page?),
        start_line: item.start_line,
        end_line: item.end_line,
        direct_link: item.omit_content_from_parent?,
        deprecation_message: item.deprecation_message,
        unavailable_message: item.unavailable_message,
        usage_discouraged: item.usage_discouraged?,
        async: item.async,
        declaration_note: item.declaration_note,
      }
    end
    # rubocop:enable Metrics/MethodLength

    def self.make_task(mark, uid, items, doc_model)
      {
        name: mark.name,
        name_html: (render_inline(doc_model, mark.name) if mark.name),
        uid: ERB::Util.url_encode(uid),
        items: items,
        pre_separator: mark.has_start_dash,
        post_separator: mark.has_end_dash,
      }
    end

    # Render tasks for Mustache document
    # @param [Config] options Build options
    # @param [Hash] doc_model Parsed doc. @see SourceKitten.parse
    def self.render_tasks(source_module, children)
      marks = children.map(&:mark).uniq.compact
      mark_names_counts = {}
      marks.map do |mark|
        mark_children = children.select { |child| child.mark == mark }
        items = mark_children.map { |child| render_item(child, source_module) }
        uid = (mark.name || 'Unnamed').to_s
        if mark_names_counts.key?(uid)
          mark_names_counts[uid] += 1
          uid += mark_names_counts[uid].to_s
        else
          mark_names_counts[uid] = 1
        end
        make_task(mark, uid, items, mark_children.first)
      end
    end

    # rubocop:disable Metrics/MethodLength
    # Build Mustache document from single parsed decl
    # @param [SourceModule] module-wide settings
    # @param [Hash] doc_model Parsed doc. @see SourceKitten.parse
    # @param [String] path_to_root
    def self.document(source_module, doc_model, path_to_root)
      if doc_model.type.markdown?
        return document_markdown(source_module, doc_model, path_to_root)
      end

      overview = (doc_model.abstract || '') + (doc_model.discussion || '')
      alternative_abstract = doc_model.alternative_abstract
      if alternative_abstract
        overview = render(doc_model, alternative_abstract) + overview
      end

      doc = new_document(source_module, doc_model)
      doc[:name] = doc_model.name
      doc[:kind] = doc_model.type.name
      doc[:dash_type] = doc_model.type.dash_type
      doc[:declaration] = doc_model.display_declaration
      doc[:language] = doc_model.display_language
      doc[:other_language_declaration] =
        doc_model.display_other_language_declaration
      doc[:overview] = overview
      doc[:parameters] = doc_model.parameters
      doc[:return] = doc_model.return
      doc[:tasks] = render_tasks(source_module, doc_model.children)
      doc[:path_to_root] = path_to_root
      doc[:deprecation_message] = doc_model.deprecation_message
      doc[:unavailable_message] = doc_model.unavailable_message
      doc[:usage_discouraged] = doc_model.usage_discouraged?
      doc.render.gsub(ELIDED_AUTOLINK_TOKEN, path_to_root)
    end
    # rubocop:enable Metrics/MethodLength

    # Breadcrumbs for a page - doesn't include the top 'readme' crumb
    def self.make_breadcrumbs(doc_model)
      return [] if doc_model.readme?

      docs_path = doc_model.docs_path
      breadcrumbs = docs_path.map do |doc|
        {
          name: doc.name,
          url: doc.url,
          last: doc == doc_model,
        }
      end

      return breadcrumbs if breadcrumbs.one?

      # Add the module name to the outer type if not clear from context
      if docs_path[1].ambiguous_module_name?(docs_path[0].name)
        breadcrumbs[1][:name] = docs_path[1].fully_qualified_module_name
      end

      breadcrumbs
    end
  end
end


================================================
FILE: lib/jazzy/doc_index.rb
================================================
# frozen_string_literal: true

module Jazzy
  # This class stores an index of symbol names for doing name lookup
  # when resolving custom categories and autolinks.
  class DocIndex
    # A node in the index tree.  The root has no decl; its children are
    # per-module indexed by module names.  The second level, where each
    # scope is a module, also has no decl; its children are scopes, one
    # for each top-level decl in the module.  From the third level onwards
    # the decl is valid.
    class Scope
      attr_reader :decl # SourceDeclaration
      attr_reader :children # String:Scope

      def initialize(decl, children)
        @decl = decl
        @children = children
      end

      def self.new_root(module_decls)
        new(nil,
            module_decls.transform_values do |decls|
              Scope.new_decl(nil, decls)
            end)
      end

      # Decl names in a scope are usually unique.  The exceptions
      # are (1) methods and (2) typealias+extension, which historically
      # jazzy does not merge.  The logic here and in `merge()` below
      # preserves the historical ambiguity-resolution of (1) and tries
      # to do the best for (2).
      def self.new_decl(decl, child_decls)
        child_scopes = {}
        child_decls.flat_map do |child_decl|
          child_scope = Scope.new_decl(child_decl, child_decl.children)
          child_decl.index_names.map do |name|
            if curr = child_scopes[name]
              curr.merge(child_scope)
            else
              child_scopes[name] = child_scope
            end
          end
        end
        new(decl, child_scopes)
      end

      def merge(new_scope)
        return unless type = decl&.type
        return unless new_type = new_scope.decl&.type

        if type.swift_typealias? && new_type.swift_extension?
          @children = new_scope.children
        elsif type.swift_extension? && new_type.swift_typealias?
          @decl = new_scope.decl
        end
      end

      # Lookup of a name like `Mod.Type.method(arg:)` requires passing
      # an array of name 'parts' eg. ['Mod', 'Type', 'method(arg:)'].
      def lookup(parts)
        return decl if parts.empty?

        children[parts.first]&.lookup(parts[1...])
      end

      # Look up of a regex matching all children for current level only.
      def lookup_regex(regex)
        children.select { |name, _| name.match(regex) }
          .map { |_, scope| scope.decl }.compact
      end

      # Get an array of scopes matching the name parts.
      def lookup_path(parts)
        [self] +
          (children[parts.first]&.lookup_path(parts[1...]) || [])
      end
    end

    attr_reader :root_scope

    def initialize(all_decls)
      @root_scope = Scope.new_root(all_decls.group_by(&:module_name))
    end

    # Look up a name and return the matching SourceDeclaration or nil.
    #
    # `context` is an optional SourceDeclaration indicating where the text
    # was found, affects name resolution - see `lookup_context()` below.
    def lookup(name, context = nil)
      lookup_name = LookupName.new(name)

      return lookup_fully_qualified(lookup_name) if lookup_name.fully_qualified?
      return lookup_guess(lookup_name) if context.nil?

      lookup_context(lookup_name, context)
    end

    # Look up a regex and return all matching top level SourceDeclaration.
    def lookup_regex(regex)
      root_scope.children.map { |_, scope| scope.lookup_regex(regex) }.flatten
    end

    private

    # Look up a fully-qualified name, ie. it starts with the module name.
    def lookup_fully_qualified(lookup_name)
      root_scope.lookup(lookup_name.parts)
    end

    # Look up a top-level name best-effort, searching for a module that
    # has it before trying the first name-part as a module name.
    def lookup_guess(lookup_name)
      root_scope.children.each_value do |module_scope|
        if result = module_scope.lookup(lookup_name.parts)
          return result
        end
      end

      lookup_fully_qualified(lookup_name)
    end

    # Look up a name from a declaration context, approximately how
    # Swift resolves names.
    #
    # 1 - try and resolve with a common prefix, eg. 'B' from 'T.A'
    #     can match 'T.B', or 'R' from 'S.T.A' can match 'S.R'.
    # 2 - try and resolve as a top-level symbol from a different module
    # 3 - (affordance for docs writers) resolve as a child of the context,
    #     eg. 'B' from 'T.A' can match 'T.A.B' *only if* (1,2) fail.
    #     Currently disabled for Swift for back-compatibility.
    def lookup_context(lookup_name, context)
      context_scope_path =
        root_scope.lookup_path(context.fully_qualified_module_name_parts)

      context_scope = context_scope_path.pop
      context_scope_path.reverse.each do |scope|
        if decl = scope.lookup(lookup_name.parts)
          return decl
        end
      end

      lookup_guess(lookup_name) ||
        (lookup_name.objc? && context_scope.lookup(lookup_name.parts))
    end

    # Helper for name lookup, really a cache for information as we
    # try various strategies.
    class LookupName
      attr_reader :name

      def initialize(name)
        @name = name
      end

      def fully_qualified?
        name.start_with?('/')
      end

      def objc?
        name.start_with?('-', '+')
      end

      def parts
        @parts ||= find_parts
      end

      private

      # Turn a name as written into a list of components to
      # be matched.
      # Swift: Strip out odd characters and split
      # ObjC: Compound names look like '+[Class(Category) method:]'
      #       and need to become ['Class(Category)', '+method:']
      def find_parts
        if name =~ /([+-])\[(\w+(?: ?\(\w+\))?) ([\w:]+)\]/
          [Regexp.last_match[2],
           Regexp.last_match[1] + Regexp.last_match[3]]
        else
          name
            .sub(%r{^[@/]}, '') # ignore custom attribute reference, fully-qualified
            .gsub(/<.*?>/, '') # remove generic parameters
            .split(%r{(?<!\.)[/.](?!\.)}) # dot or slash, but not '...'
            .reject(&:empty?)
        end
      end
    end
  end

  class SourceDeclaration
    # Names for a symbol.  Permits function parameters to be omitted.
    def index_names
      [name, name.sub(/\(.*\)/, '(...)')].uniq
    end
  end
end


================================================
FILE: lib/jazzy/docset_builder/info_plist.mustache
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>CFBundleIdentifier</key>
      <string>com.jazzy.{{lowercase_safe_name}}</string>
    <key>CFBundleName</key>
      <string>{{name}}</string>
    <key>DocSetPlatformFamily</key>
      <string>{{lowercase_name}}</string>
    <key>isDashDocset</key>
      <true/>
    <key>dashIndexFilePath</key>
      <string>index.html</string>
    <key>isJavaScriptEnabled</key>
      <true/>
    <key>DashDocSetFamily</key>
      <string>dashtoc</string>
    {{#root_url}}
    <key>DashDocSetFallbackURL</key>
      <string>{{{.}}}</string>
    {{/root_url}}
    {{#playground_url}}
    <key>DashDocSetPlayURL</key>
      <string>{{{.}}}</string>
    {{/playground_url}}
  </dict>
</plist>


================================================
FILE: lib/jazzy/docset_builder.rb
================================================
# frozen_string_literal: true

require 'mustache'
require 'sqlite3'

module Jazzy
  module DocBuilder
    # Follows the instructions found at https://kapeli.com/docsets#dashDocset.
    class DocsetBuilder
      include Config::Mixin

      attr_reader :output_dir
      attr_reader :generated_docs_dir
      attr_reader :source_module
      attr_reader :docset_dir
      attr_reader :documents_dir
      attr_reader :name

      def initialize(generated_docs_dir)
        @name = config.docset_title || config.module_names.first
        docset_path = config.docset_path ||
                      "docsets/#{safe_name}.docset"
        @docset_dir = generated_docs_dir + docset_path
        @generated_docs_dir = generated_docs_dir
        @output_dir = docset_dir.parent
        @documents_dir = docset_dir + 'Contents/Resources/Documents/'
      end

      def build!(all_declarations)
        docset_dir.rmtree if docset_dir.exist?
        copy_docs
        copy_icon if config.docset_icon
        write_plist
        create_index(all_declarations)
        create_archive
        create_xml if config.version && config.root_url
      end

      private

      def safe_name
        name.gsub(/[^a-z0-9_-]+/i, '_')
      end

      def write_plist
        info_plist_path = docset_dir + 'Contents/Info.plist'
        info_plist_path.open('w') do |plist|
          template = Pathname(__dir__) + 'docset_builder/info_plist.mustache'
          plist << Mustache.render(
            template.read,
            lowercase_name: name.downcase,
            lowercase_safe_name: safe_name.downcase,
            name: name,
            root_url: config.root_url,
            playground_url: config.docset_playground_url,
          )
        end
      end

      def create_archive
        target  = "#{safe_name}.tgz"
        source  = docset_dir.basename.to_s
        options = {
          chdir: output_dir.to_s,
          [1, 2] => '/dev/null', # silence all output from `tar`
        }
        system('tar', "--exclude='.DS_Store'", '-cvzf', target, source, options)
      end

      def copy_docs
        files_to_copy = Pathname.glob(generated_docs_dir + '*') -
                        [docset_dir, output_dir]

        FileUtils.mkdir_p documents_dir
        FileUtils.cp_r files_to_copy, documents_dir
      end

      def copy_icon
        FileUtils.cp config.docset_icon, docset_dir + 'icon.png'
      end

      def create_index(all_declarations)
        search_index_path = docset_dir + 'Contents/Resources/docSet.dsidx'
        SQLite3::Database.new(search_index_path.to_s) do |db|
          db.execute('CREATE TABLE searchIndex(' \
            'id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT);')
          db.execute('CREATE UNIQUE INDEX anchor ON ' \
            'searchIndex (name, type, path);')
          all_declarations.select(&:type).each do |doc|
            db.execute('INSERT OR IGNORE INTO searchIndex(name, type, path) ' \
              'VALUES (?, ?, ?);', [doc.name, doc.type.dash_type, doc.filepath])
          end
        end
      end

      def create_xml
        (output_dir + "#{safe_name}.xml").open('w') do |xml|
          url = URI.join(config.root_url, "docsets/#{safe_name}.tgz")
          xml << "<entry><version>#{config.version}</version><url>#{url}" \
            "</url></entry>\n"
        end
      end

      # The web URL where the user intends to place the docset XML file.
      def dash_url
        return nil unless config.dash_url || config.root_url

        config.dash_url ||
          URI.join(
            config.root_url,
            "docsets/#{safe_name}.xml",
          )
      end

      public

      # The dash-feed:// URL that links from the Dash icon in generated
      # docs.  This is passed to the Dash app and encodes the actual web
      # `dash_url` where the user has placed the XML file.
      #
      # Unfortunately for historical reasons this is *also* called the
      # 'dash_url' where it appears in mustache templates and so on.
      def dash_feed_url
        dash_url&.then do |url|
          "dash-feed://#{ERB::Util.url_encode(url.to_s)}"
        end
      end
    end
  end
end


================================================
FILE: lib/jazzy/documentation_generator.rb
================================================
# frozen_string_literal: true

require 'pathname'

require 'jazzy/jazzy_markdown'
require 'jazzy/source_document'

module Jazzy
  module DocumentationGenerator
    extend Config::Mixin

    def self.source_docs
      documentation_entries.map do |file_path|
        SourceDocument.new.tap do |sd|
          sd.name = File.basename(file_path, '.md')
          sd.overview = overview Pathname(file_path)
          sd.usr = "documentation.#{sd.name}"
        end
      end
    end

    def self.overview(file_path)
      return '' unless file_path&.exist?

      file_path.read
    end

    def self.documentation_entries
      return [] unless
        config.documentation_glob_configured && config.documentation_glob

      config.documentation_glob.select { |e| File.file? e }
    end
  end
end


================================================
FILE: lib/jazzy/executable.rb
================================================
# frozen_string_literal: true

module Jazzy
  module Executable
    class IO < Array
      def initialize(io = nil)
        super()
        @io = io
      end

      def <<(value)
        super
      ensure
        @io << value.to_s if @io
      end

      def to_s
        join("\n")
      end
    end

    class << self
      def execute_command(executable, args, raise_on_failure, env: {})
        require 'shellwords'
        bin = `which #{executable.to_s.shellescape}`.strip
        raise "Unable to locate the executable `#{executable}`" if bin.empty?

        require 'open4'

        stdout = IO.new
        stderr = IO.new($stderr)

        options = { stdout: stdout, stderr: stderr, status: true }
        status  = Open4.spawn(env, bin, *args, options)
        unless status.success?
          full_command = "#{bin.shellescape} #{args.map(&:shellescape)}"
          output = stdout.to_s << stderr.to_s
          if raise_on_failure
            raise "#{full_command}\n\n#{output}"
          else
            warn("[!] Failed: #{full_command}")
          end
        end
        [stdout.to_s, status]
      end
    end
  end
end


================================================
FILE: lib/jazzy/gem_version.rb
================================================
# frozen_string_literal: true

module Jazzy
  VERSION = '0.15.4' unless defined? Jazzy::VERSION
end


================================================
FILE: lib/jazzy/grouper.rb
================================================
# frozen_string_literal: true

module Jazzy
  # This module deals with arranging top-level declarations and guides into
  # groups automatically and/or using a custom list.
  module Grouper
    extend Config::Mixin

    # Group root-level docs by custom categories (if any) and type or module
    def self.group_docs(docs, doc_index)
      custom_categories, docs = group_custom_categories(docs, doc_index)
      unlisted_prefix = config.custom_categories_unlisted_prefix
      type_category_prefix = custom_categories.any? ? unlisted_prefix : ''
      all_categories =
        custom_categories +
        if config.merge_modules == :all
          group_docs_by_type(docs, type_category_prefix)
        else
          group_docs_by_module(docs, type_category_prefix)
        end
      merge_consecutive_marks(all_categories)
    end

    # Group root-level docs by type
    def self.group_docs_by_type(docs, type_category_prefix)
      type_groups = SourceDeclaration::Type.all.map do |type|
        children, docs = docs.partition { |doc| doc.type == type }
        make_type_group(children, type, type_category_prefix)
      end
      merge_categories(type_groups.compact) + docs
    end

    # Group root-level docs by module name
    def self.group_docs_by_module(docs, type_category_prefix)
      guide_categories, docs = group_guides(docs, type_category_prefix)

      module_categories = docs
        .group_by(&:doc_module_name)
        .map do |name, module_docs|
          make_group(
            module_docs,
            name,
            "The following declarations are provided by module #{name}.",
          )
        end

      guide_categories + module_categories
    end

    def self.group_custom_categories(docs, doc_index)
      group = config.custom_categories.map do |category|
        children = category['children'].map do |selector|
          selected = select_docs(doc_index, selector)
          selected.map do |doc|
            unless doc.parent_in_code.nil?
              warn "WARNING: Declaration \"#{doc.fully_qualified_module_name}\" " \
                'specified in categories file exists but is not top-level and ' \
                'cannot be included here'
              next nil
            end
            docs.delete(doc)
          end
        end.flatten.compact
        # Category config overrides alphabetization
        children.each.with_index { |child, i| child.nav_order = i }
        make_group(children, category['name'], '')
      end
      [group.compact, docs]
    end

    def self.select_docs(doc_index, selector)
      if selector.is_a?(String)
        unless single_doc = doc_index.lookup(selector)
          warn 'WARNING: No documented top-level declarations match ' \
            "name \"#{selector}\" specified in categories file"
          return []
        end
        [single_doc]
      else
        doc_index.lookup_regex(selector['regex'])
          .sort_by(&:name)
      end
    end

    def self.group_guides(docs, prefix)
      guides, others = docs.partition { |doc| doc.type.markdown? }
      return [[], others] unless guides.any?

      [[make_type_group(guides, guides.first.type, prefix)], others]
    end

    def self.make_type_group(docs, type, type_category_prefix)
      make_group(
        docs,
        type_category_prefix + type.plural_name,
        "The following #{type.plural_name.downcase} are available globally.",
        type_category_prefix + type.plural_url_name,
      )
    end

    # Join categories with the same name (eg. ObjC and Swift classes)
    def self.merge_categories(categories)
      merged = []
      categories.each do |new_category|
        if existing = merged.find { |cat| cat.name == new_category.name }
          existing.children += new_category.children
        else
          merged.append(new_category)
        end
      end
      merged
    end

    def self.make_group(group, name, abstract, url_name = nil)
      group.reject! { |decl| decl.name.empty? }
      unless group.empty?
        SourceDeclaration.new.tap do |sd|
          sd.type     = SourceDeclaration::Type.overview
          sd.name     = name
          sd.url_name = url_name
          sd.abstract = Markdown.render(abstract)
          sd.children = group
        end
      end
    end

    # Merge consecutive sections with the same mark into one section
    # Needed because of pulling various decls into groups
    def self.merge_consecutive_marks(docs)
      prev_mark = nil
      docs.each do |doc|
        if prev_mark&.can_merge?(doc.mark)
          doc.mark = prev_mark
        end
        prev_mark = doc.mark
        merge_consecutive_marks(doc.children)
      end
    end
  end
end


================================================
FILE: lib/jazzy/highlighter.rb
================================================
# frozen_string_literal: true

require 'rouge'

module Jazzy
  # This module helps highlight code
  module Highlighter
    SWIFT = 'swift'
    OBJC = 'objective_c'

    class Formatter < Rouge::Formatters::HTML
      def initialize(language)
        @language = language
        super()
      end

      def stream(tokens, &block)
        yield "<pre class=\"highlight #{@language}\"><code>"
        super
        yield "</code></pre>\n"
      end
    end

    def self.highlight_swift(source)
      highlight(source, SWIFT)
    end

    def self.highlight_objc(source)
      highlight(source, OBJC)
    end

    def self.highlight(source, language)
      source && Rouge.highlight(source, language, Formatter.new(language))
    end
  end
end


================================================
FILE: lib/jazzy/jazzy_markdown.rb
================================================
# frozen_string_literal: true

require 'redcarpet'
require 'rouge'
require 'rouge/plugins/redcarpet'

module Jazzy
  module Markdown
    # Publish if generated HTML needs math support
    class << self; attr_accessor :has_math; end

    module Footnotes
      # Global unique footnote ID
      def self.next_footnote
        @next_footnote ||= 0
        @next_footnote += 1
      end

      # Per-render map from user to global ID
      attr_accessor :footnotes_hash

      def reset
        @footnotes_hash = {}
      end

      def map_footnote(user_num)
        footnotes_hash.fetch(user_num) do
          footnotes_hash[user_num] = Footnotes.next_footnote
        end
      end

      def footnote_ref(num)
        mapped = map_footnote(num)
        "<span class='footnote-ref' id=\"fnref#{mapped}\">" \
          "<sup><a href=\"#fn#{mapped}\">#{num}</a></sup></span>"
      end

      # follow native redcarpet: backlink goes before the first </p> tag
      def footnote_def(text, num)
        mapped = map_footnote(num)
        "\n<li><div class='footnote-def' id=\"fn#{mapped}\">" +
          text.sub(%r{(?=</p>)},
                   "&nbsp;<a href=\"#fnref#{mapped}\">&#8617;</a>") +
          '</div></li>'
      end
    end

    # rubocop:disable Metrics/ClassLength
    class JazzyHTML < Redcarpet::Render::HTML
      include Redcarpet::Render::SmartyPants
      include Rouge::Plugins::Redcarpet
      include Footnotes

      attr_accessor :default_language

      def header(text, header_level)
        text_slug = text.gsub(/[^[[:word:]]]+/, '-')
          .downcase
          .sub(/^-/, '')
          .sub(/-$/, '')

        "<h#{header_level} id='#{text_slug}' class='heading'>" \
          "#{text}" \
          "</h#{header_level}>\n"
      end

      def codespan(text)
        case text
        when /^\$\$(.*)\$\$$/m
          o = ["</p><div class='math m-block'>",
               Regexp.last_match[1],
               '</div><p>']
          Markdown.has_math = true
        when /^\$(.*)\$$/m
          o = ["<span class='math m-inline'>", Regexp.last_match[1], '</span>']
          Markdown.has_math = true
        else
          o = ['<code>', text.to_s, '</code>']
        end

        o[0] + CGI.escapeHTML(o[1]) + o[2]
      end

      # List from
      # https://github.com/apple/swift/blob/master/include/swift/Markup/SimpleFields.def
      UNIQUELY_HANDLED_CALLOUTS = %w[parameters
                                     parameter
                                     returns].freeze
      GENERAL_CALLOUTS = %w[attention
                            author
                            authors
                            bug
                            complexity
                            copyright
                            date
                            experiment
                            important
                            invariant
                            keyword
                            mutatingvariant
                            nonmutatingvariant
                            note
                            postcondition
                            precondition
                            recommended
                            recommendedover
                            remark
                            remarks
                            requires
                            see
                            seealso
                            since
                            todo
                            throws
                            version
                            warning].freeze
      SPECIAL_LIST_TYPES = (UNIQUELY_HANDLED_CALLOUTS + GENERAL_CALLOUTS).freeze

      SPECIAL_LIST_TYPE_REGEX = %r{
        \A\s* # optional leading spaces
        (<p>\s*)? # optional opening p tag
        # any one of our special list types
        (#{SPECIAL_LIST_TYPES.map(&Regexp.method(:escape)).join('|')})
        [\s:] # followed by either a space or a colon
        }ix.freeze

      ELIDED_LI_TOKEN =
        '7wNVzLB0OYPL2eGlPKu8q4vITltqh0Y6DPZf659TPMAeYh49o'

      def list_item(text, _list_type)
        if text =~ SPECIAL_LIST_TYPE_REGEX
          type = Regexp.last_match(2)
          if UNIQUELY_HANDLED_CALLOUTS.include? type.downcase
            return ELIDED_LI_TOKEN
          end

          return render_list_aside(type,
                                   text.sub(/#{Regexp.escape(type)}:\s+/, ''))
        end
        "<li>#{text.strip}</li>\n"
      end

      def render_list_aside(type, text)
        "</ul>#{render_aside(type, text).chomp}<ul>\n"
      end

      def render_aside(type, text)
        <<-HTML
<div class="aside aside-#{type.underscore.tr('_', '-')}">
    <p class="aside-title">#{type.underscore.humanize}</p>
    #{text}
</div>
        HTML
      end

      def list(text, list_type)
        elided = text.gsub!(ELIDED_LI_TOKEN, '')
        return if text =~ /\A\s*\Z/ && elided

        tag = list_type == :ordered ? 'ol' : 'ul'
        "\n<#{tag}>\n#{text}</#{tag}>\n"
          .gsub(%r{\n?<ul>\n?</ul>}, '')
      end

      # List from
      # https://developer.apple.com/documentation/xcode/formatting-your-documentation-content#Add-Notes-and-Other-Asides
      DOCC_CALLOUTS = %w[note
                         important
                         warning
                         tip
                         experiment].freeze

      DOCC_CALLOUT_REGEX = %r{
        \A\s* # optional leading spaces
        (?:<p>\s*)? # optional opening p tag
        # any one of the callout names
        (#{DOCC_CALLOUTS.map(&Regexp.method(:escape)).join('|')})
        : # followed directly by a colon
      }ix.freeze

      def block_quote(html)
        if html =~ DOCC_CALLOUT_REGEX
          type = Regexp.last_match[1]
          render_aside(type, html.sub(/#{Regexp.escape(type)}:\s*/, ''))
        else
          "\n<blockquote>\n#{html}</blockquote>\n"
        end
      end

      def block_code(code, language)
        super(code, language || default_language)
      end

      def rouge_formatter(lexer)
        Highlighter::Formatter.new(lexer.tag)
      end
    end
    # rubocop:enable Metrics/ClassLength

    REDCARPET_OPTIONS = {
      autolink: true,
      fenced_code_blocks: true,
      no_intra_emphasis: true,
      strikethrough: true,
      space_after_headers: false,
      tables: true,
      lax_spacing: true,
      footnotes: true,
    }.freeze

    # Spot and capture returns & param HTML for separate display.
    class JazzyDeclarationHTML < JazzyHTML
      attr_reader :returns, :parameters

      def reset
        @returns = nil
        @parameters = {}
        super
      end

      INTRO_PAT = '\A(?<intro>\s*(<p>\s*)?)'
      OUTRO_PAT = '(?<outro>.*)\z'

      RETURNS_REGEX = /#{INTRO_PAT}returns:#{OUTRO_PAT}/im.freeze

      IDENT_PAT = '(?<param>\S+)'

      # Param formats: normal swift, objc via sourcekitten, and
      # possibly inside 'Parameters:'
      PARAM_PAT1 = "(parameter +#{IDENT_PAT}\\s*:)"
      PARAM_PAT2 = "(parameter:\\s*#{IDENT_PAT}\\s+)"
      PARAM_PAT3 = "(#{IDENT_PAT}\\s*:)"

      PARAM_PAT = "(?:#{PARAM_PAT1}|#{PARAM_PAT2}|#{PARAM_PAT3})"

      PARAM_REGEX = /#{INTRO_PAT}#{PARAM_PAT}#{OUTRO_PAT}/im.freeze

      def list_item(text, _list_type)
        if text =~ RETURNS_REGEX
          @returns = render_param_returns(Regexp.last_match)
        elsif text =~ PARAM_REGEX
          @parameters[Regexp.last_match(:param)] =
            render_param_returns(Regexp.last_match)
        end
        super
      end

      def render_param_returns(matches)
        body = matches[:intro].strip + matches[:outro].strip
        body = "<p>#{body}</p>" unless body.start_with?('<p>')
        # call smartypants for pretty quotes etc.
        postprocess(body)
      end
    end

    def self.renderer
      @renderer ||= JazzyDeclarationHTML.new
    end

    def self.markdown
      @markdown ||= Redcarpet::Markdown.new(renderer, REDCARPET_OPTIONS)
    end

    # Produces <p>-delimited block content
    def self.render(markdown_text, default_language = nil)
      renderer.reset
      renderer.default_language = default_language
      markdown.render(markdown_text)
    end

    # Produces <span>-delimited inline content
    def self.render_inline(markdown_text, default_language = nil)
      render(markdown_text, default_language)
        .sub(%r{^<p>(.*)</p>$}, '<span>\1</span>')
    end

    def self.rendered_returns
      renderer.returns
    end

    def self.rendered_parameters
      renderer.parameters
    end

    class JazzyCopyright < Redcarpet::Render::HTML
      def link(link, _title, content)
        %(<a class="link" href="#{link}" target="_blank" \
rel="external noopener">#{content}</a>)
      end
    end

    def self.copyright_markdown
      @copyright_markdown ||= Redcarpet::Markdown.new(
        JazzyCopyright,
        REDCARPET_OPTIONS,
      )
    end

    def self.render_copyright(markdown_text)
      copyright_markdown.render(markdown_text)
    end
  end
end


================================================
FILE: lib/jazzy/podspec_documenter.rb
================================================
# frozen_string_literal: true

require 'tmpdir'
require 'json'

module Jazzy
  # rubocop:disable Metrics/ClassLength
  class PodspecDocumenter
    attr_reader :podspec

    def initialize(podspec)
      @podspec = podspec
    end

    # Build documentation from the given options
    # @param [Config] options
    def sourcekitten_output(config)
      installation_root = Pathname(Dir.mktmpdir(['jazzy', podspec.name]))
      installation_root.rmtree if installation_root.exist?
      Pod::Config.instance.with_changes(installation_root: installation_root,
                                        verbose: false) do
        sandbox = Pod::Sandbox.new(Pod::Config.instance.sandbox_root)
        installer = Pod::Installer.new(sandbox, podfile(config))
        installer.install!
        stdout = Dir.chdir(sandbox.root) do
          targets = installer.pod_targets
            .select { |pt| pt.pod_name == podspec.root.name }
            .map(&:label)

          targets.map do |t|
            args = %W[doc --module-name #{podspec.module_name} -- -target #{t}]
            SourceKitten.run_sourcekitten(args)
          end
        end
        stdout.reduce([]) { |a, s| a + JSON.parse(s) }.to_json
      end
    end

    def self.create_podspec(podspec_path)
      case podspec_path
      when Pathname, String
        require 'cocoapods'
        Pod::Specification.from_file(podspec_path)
      end
    end

    # rubocop:disable Metrics/MethodLength
    def self.apply_config_defaults(podspec, config)
      return unless podspec

      unless config.author_name_configured
        config.author_name = author_name(podspec)
        config.author_name_configured = true
      end
      unless config.module_name_known?
        config.module_name = podspec.module_name
        config.module_name_configured = true
      end
      unless config.author_url_configured
        config.author_url = podspec.homepage || github_file_prefix(podspec)
        config.author_url_configured = true
      end
      unless config.version_configured
        config.version = podspec.version.to_s
        config.version_configured = true
      end
      unless config.source_host_files_url_configured
        config.source_host_files_url = github_file_prefix(podspec)
        config.source_host_files_url_configured = true
      end
      unless config.swift_version_configured
        trunk_swift_build = podspec.attributes_hash['pushed_with_swift_version']
        config.swift_version = trunk_swift_build if trunk_swift_build
        config.swift_version_configured = true
      end
    end
    # rubocop:enable Metrics/MethodLength

    private

    # @!group Config helper methods

    def self.author_name(podspec)
      if podspec.authors.respond_to? :to_hash
        podspec.authors.keys.to_sentence || ''
      elsif podspec.authors.respond_to? :to_ary
        podspec.authors.to_sentence
      end || podspec.authors || ''
    end

    private_class_method :author_name

Download .txt
gitextract_xj36c4n0/

├── .github/
│   └── workflows/
│       └── Tests.yml
├── .gitignore
├── .gitmodules
├── .rubocop.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Dangerfile
├── Gemfile
├── LICENSE
├── ObjectiveC.md
├── README.md
├── Rakefile
├── bin/
│   ├── jazzy
│   └── sourcekitten
├── images/
│   └── logo.sketch
├── jazzy.gemspec
├── js/
│   └── package.json
├── lib/
│   ├── jazzy/
│   │   ├── config.rb
│   │   ├── doc.rb
│   │   ├── doc_builder.rb
│   │   ├── doc_index.rb
│   │   ├── docset_builder/
│   │   │   └── info_plist.mustache
│   │   ├── docset_builder.rb
│   │   ├── documentation_generator.rb
│   │   ├── executable.rb
│   │   ├── gem_version.rb
│   │   ├── grouper.rb
│   │   ├── highlighter.rb
│   │   ├── jazzy_markdown.rb
│   │   ├── podspec_documenter.rb
│   │   ├── search_builder.rb
│   │   ├── source_declaration/
│   │   │   ├── access_control_level.rb
│   │   │   └── type.rb
│   │   ├── source_declaration.rb
│   │   ├── source_document.rb
│   │   ├── source_host.rb
│   │   ├── source_mark.rb
│   │   ├── source_module.rb
│   │   ├── sourcekitten.rb
│   │   ├── stats.rb
│   │   ├── symbol_graph/
│   │   │   ├── constraint.rb
│   │   │   ├── ext_key.rb
│   │   │   ├── ext_node.rb
│   │   │   ├── graph.rb
│   │   │   ├── relationship.rb
│   │   │   ├── sym_node.rb
│   │   │   └── symbol.rb
│   │   ├── symbol_graph.rb
│   │   └── themes/
│   │       ├── apple/
│   │       │   ├── assets/
│   │       │   │   ├── css/
│   │       │   │   │   ├── highlight.css.scss
│   │       │   │   │   └── jazzy.css.scss
│   │       │   │   └── js/
│   │       │   │       ├── jazzy.js
│   │       │   │       ├── jazzy.search.js
│   │       │   │       └── typeahead.jquery.js
│   │       │   └── templates/
│   │       │       ├── deprecation.mustache
│   │       │       ├── doc.mustache
│   │       │       ├── footer.mustache
│   │       │       ├── header.mustache
│   │       │       ├── nav.mustache
│   │       │       ├── parameter.mustache
│   │       │       ├── task.mustache
│   │       │       └── tasks.mustache
│   │       ├── fullwidth/
│   │       │   ├── assets/
│   │       │   │   ├── css/
│   │       │   │   │   ├── highlight.css.scss
│   │       │   │   │   └── jazzy.css.scss
│   │       │   │   └── js/
│   │       │   │       ├── jazzy.js
│   │       │   │       ├── jazzy.search.js
│   │       │   │       └── typeahead.jquery.js
│   │       │   └── templates/
│   │       │       ├── deprecation.mustache
│   │       │       ├── doc.mustache
│   │       │       ├── footer.mustache
│   │       │       ├── header.mustache
│   │       │       ├── nav.mustache
│   │       │       ├── parameter.mustache
│   │       │       ├── task.mustache
│   │       │       └── tasks.mustache
│   │       └── jony/
│   │           ├── assets/
│   │           │   ├── css/
│   │           │   │   ├── highlight.css.scss
│   │           │   │   └── jazzy.css.scss
│   │           │   └── js/
│   │           │       └── jazzy.js
│   │           └── templates/
│   │               ├── deprecation.mustache
│   │               ├── doc.mustache
│   │               ├── footer.mustache
│   │               ├── header.mustache
│   │               ├── nav.mustache
│   │               ├── parameter.mustache
│   │               ├── task.mustache
│   │               └── tasks.mustache
│   └── jazzy.rb
└── spec/
    ├── Moya.podspec
    ├── integration_spec.rb
    ├── spec_helper/
    │   └── pre_flight.rb
    └── spec_helper.rb
Download .txt
SYMBOL INDEX (656 symbols across 40 files)

FILE: lib/jazzy/config.rb
  type Jazzy (line 10) | module Jazzy
    class Config (line 12) | class Config
      class Attribute (line 14) | class Attribute
        method initialize (line 18) | def initialize(name, description: nil, command_line: nil,
        method get (line 29) | def get(config)
        method set_raw (line 33) | def set_raw(config, val)
        method set (line 37) | def set(config, val, mark_configured: true)
        method set_to_default (line 42) | def set_to_default(config)
        method set_if_unconfigured (line 46) | def set_if_unconfigured(config, val)
        method configured? (line 50) | def configured?(config)
        method attach_to_option_parser (line 54) | def attach_to_option_parser(config, opt)
        method full_command_line_name (line 64) | def full_command_line_name
      method config_attr (line 79) | def self.config_attr(name, **opts)
      method alias_config_attr (line 87) | def self.alias_config_attr(name, forward, **opts)
      method expand_glob_path (line 101) | def expand_glob_path(path)
      method expand_path (line 105) | def expand_path(path)
      method hide_swift? (line 110) | def hide_swift?
      method hide_objc? (line 114) | def hide_objc?
      method initialize (line 538) | def initialize
      method theme_directory= (line 544) | def theme_directory=(theme_directory)
      method parse! (line 549) | def self.parse!
      method warning (line 562) | def warning(message)
      method parse_command_line (line 567) | def parse_command_line
      method parse_config_file (line 603) | def parse_config_file
      method parse_config_hash (line 617) | def parse_config_hash(hash, attrs_by_conf_key, attrs_by_name, overri...
      method grouped_attributes (line 635) | def grouped_attributes
      method validate (line 643) | def validate
      method validate_module (line 663) | def validate_module
      method set_module_configs (line 699) | def set_module_configs
      method module_name? (line 705) | def module_name?(name)
      method multiple_modules? (line 709) | def multiple_modules?
      method parse_module_configs (line 713) | def parse_module_configs
      method module_name_known? (line 740) | def module_name_known?
      method locate_config_file (line 744) | def locate_config_file
      method read_config_file (line 754) | def read_config_file(file)
      method print_config_file_help (line 764) | def print_config_file_help
      method print_option_help (line 782) | def print_option_help(topic = '')
      method print_attr_description (line 805) | def print_attr_description(attr)
      method instance (line 818) | def self.instance
      type Mixin (line 836) | module Mixin
        function config (line 837) | def config

FILE: lib/jazzy/doc.rb
  type Jazzy (line 11) | module Jazzy
    class Doc (line 12) | class Doc < Mustache
      method copyright (line 17) | def copyright
      method jazzy_version (line 28) | def jazzy_version
      method objc_first? (line 33) | def objc_first?
      method language_stub (line 37) | def language_stub
      method module_version (line 41) | def module_version
      method docs_title (line 45) | def docs_title
      method enable_katex (line 57) | def enable_katex

FILE: lib/jazzy/doc_builder.rb
  type Jazzy (line 21) | module Jazzy
    type DocBuilder (line 24) | module DocBuilder
      function prepare_output_dir (line 26) | def self.prepare_output_dir(output_dir, clean)
      function doc_structure_for_docs (line 34) | def self.doc_structure_for_docs(docs)
      function children_for_doc (line 54) | def self.children_for_doc(doc)
      function build (line 70) | def self.build(options)
      function build_docs (line 94) | def self.build_docs(output_dir, source_module)
      function each_doc (line 105) | def self.each_doc(output_dir, docs, &block)
      function build_site (line 120) | def self.build_site(docs, coverage, options)
      function build_docs_for_sourcekitten_output (line 156) | def self.build_docs_for_sourcekitten_output(sourcekitten_output, opt...
      function relative_path_if_inside (line 174) | def self.relative_path_if_inside(path, base_path)
      function undocumented_warnings (line 183) | def self.undocumented_warnings(decls)
      function write_lint_report (line 195) | def self.write_lint_report(undocumented, options)
      function copy_theme_assets (line 212) | def self.copy_theme_assets(destination)
      function copy_extensions (line 223) | def self.copy_extensions(source_module, destination)
      function copy_extension (line 230) | def self.copy_extension(name, destination)
      function render (line 235) | def self.render(doc_model, markdown)
      function render_inline (line 240) | def self.render_inline(doc_model, markdown)
      function new_document (line 246) | def self.new_document(source_module, doc_model)
      function document_markdown (line 273) | def self.document_markdown(source_module, doc_model, path_to_root)
      function color_for_coverage (line 286) | def self.color_for_coverage(coverage)
      function generate_badge (line 308) | def self.generate_badge(coverage, options)
      function render_item (line 355) | def self.render_item(item, source_module)
      function make_task (line 387) | def self.make_task(mark, uid, items, doc_model)
      function render_tasks (line 401) | def self.render_tasks(source_module, children)
      function document (line 423) | def self.document(source_module, doc_model, path_to_root)
      function make_breadcrumbs (line 455) | def self.make_breadcrumbs(doc_model)

FILE: lib/jazzy/doc_index.rb
  type Jazzy (line 3) | module Jazzy
    class DocIndex (line 6) | class DocIndex
      class Scope (line 12) | class Scope
        method initialize (line 16) | def initialize(decl, children)
        method new_root (line 21) | def self.new_root(module_decls)
        method new_decl (line 33) | def self.new_decl(decl, child_decls)
        method merge (line 48) | def merge(new_scope)
        method lookup (line 61) | def lookup(parts)
        method lookup_regex (line 68) | def lookup_regex(regex)
        method lookup_path (line 74) | def lookup_path(parts)
      method initialize (line 82) | def initialize(all_decls)
      method lookup (line 90) | def lookup(name, context = nil)
      method lookup_regex (line 100) | def lookup_regex(regex)
      method lookup_fully_qualified (line 107) | def lookup_fully_qualified(lookup_name)
      method lookup_guess (line 113) | def lookup_guess(lookup_name)
      method lookup_context (line 132) | def lookup_context(lookup_name, context)
      class LookupName (line 149) | class LookupName
        method initialize (line 152) | def initialize(name)
        method fully_qualified? (line 156) | def fully_qualified?
        method objc? (line 160) | def objc?
        method parts (line 164) | def parts
        method find_parts (line 175) | def find_parts
    class SourceDeclaration (line 190) | class SourceDeclaration
      method index_names (line 192) | def index_names

FILE: lib/jazzy/docset_builder.rb
  type Jazzy (line 6) | module Jazzy
    type DocBuilder (line 7) | module DocBuilder
      class DocsetBuilder (line 9) | class DocsetBuilder
        method initialize (line 19) | def initialize(generated_docs_dir)
        method build! (line 29) | def build!(all_declarations)
        method safe_name (line 41) | def safe_name
        method write_plist (line 45) | def write_plist
        method create_archive (line 60) | def create_archive
        method copy_docs (line 70) | def copy_docs
        method copy_icon (line 78) | def copy_icon
        method create_index (line 82) | def create_index(all_declarations)
        method create_xml (line 96) | def create_xml
        method dash_url (line 105) | def dash_url
        method dash_feed_url (line 123) | def dash_feed_url

FILE: lib/jazzy/documentation_generator.rb
  type Jazzy (line 8) | module Jazzy
    type DocumentationGenerator (line 9) | module DocumentationGenerator
      function source_docs (line 12) | def self.source_docs
      function overview (line 22) | def self.overview(file_path)
      function documentation_entries (line 28) | def self.documentation_entries

FILE: lib/jazzy/executable.rb
  type Jazzy (line 3) | module Jazzy
    type Executable (line 4) | module Executable
      class IO (line 5) | class IO < Array
        method initialize (line 6) | def initialize(io = nil)
        method << (line 11) | def <<(value)
        method to_s (line 17) | def to_s
      function execute_command (line 23) | def execute_command(executable, args, raise_on_failure, env: {})

FILE: lib/jazzy/gem_version.rb
  type Jazzy (line 3) | module Jazzy

FILE: lib/jazzy/grouper.rb
  type Jazzy (line 3) | module Jazzy
    type Grouper (line 6) | module Grouper
      function group_docs (line 10) | def self.group_docs(docs, doc_index)
      function group_docs_by_type (line 25) | def self.group_docs_by_type(docs, type_category_prefix)
      function group_docs_by_module (line 34) | def self.group_docs_by_module(docs, type_category_prefix)
      function group_custom_categories (line 50) | def self.group_custom_categories(docs, doc_index)
      function select_docs (line 71) | def self.select_docs(doc_index, selector)
      function group_guides (line 85) | def self.group_guides(docs, prefix)
      function make_type_group (line 92) | def self.make_type_group(docs, type, type_category_prefix)
      function merge_categories (line 102) | def self.merge_categories(categories)
      function make_group (line 114) | def self.make_group(group, name, abstract, url_name = nil)
      function merge_consecutive_marks (line 129) | def self.merge_consecutive_marks(docs)

FILE: lib/jazzy/highlighter.rb
  type Jazzy (line 5) | module Jazzy
    type Highlighter (line 7) | module Highlighter
      class Formatter (line 11) | class Formatter < Rouge::Formatters::HTML
        method initialize (line 12) | def initialize(language)
        method stream (line 17) | def stream(tokens, &block)
      function highlight_swift (line 24) | def self.highlight_swift(source)
      function highlight_objc (line 28) | def self.highlight_objc(source)
      function highlight (line 32) | def self.highlight(source, language)

FILE: lib/jazzy/jazzy_markdown.rb
  type Jazzy (line 7) | module Jazzy
    type Markdown (line 8) | module Markdown
      type Footnotes (line 12) | module Footnotes
        function next_footnote (line 14) | def self.next_footnote
        function reset (line 22) | def reset
        function map_footnote (line 26) | def map_footnote(user_num)
        function footnote_ref (line 32) | def footnote_ref(num)
        function footnote_def (line 39) | def footnote_def(text, num)
      class JazzyHTML (line 49) | class JazzyHTML < Redcarpet::Render::HTML
        method header (line 56) | def header(text, header_level)
        method codespan (line 67) | def codespan(text)
        method list_item (line 130) | def list_item(text, _list_type)
        method render_list_aside (line 143) | def render_list_aside(type, text)
        method render_aside (line 147) | def render_aside(type, text)
        method list (line 156) | def list(text, list_type)
        method block_quote (line 181) | def block_quote(html)
        method block_code (line 190) | def block_code(code, language)
        method rouge_formatter (line 194) | def rouge_formatter(lexer)
      class JazzyDeclarationHTML (line 212) | class JazzyDeclarationHTML < JazzyHTML
        method reset (line 215) | def reset
        method list_item (line 238) | def list_item(text, _list_type)
        method render_param_returns (line 248) | def render_param_returns(matches)
      function renderer (line 256) | def self.renderer
      function markdown (line 260) | def self.markdown
      function render (line 265) | def self.render(markdown_text, default_language = nil)
      function render_inline (line 272) | def self.render_inline(markdown_text, default_language = nil)
      function rendered_returns (line 277) | def self.rendered_returns
      function rendered_parameters (line 281) | def self.rendered_parameters
      class JazzyCopyright (line 285) | class JazzyCopyright < Redcarpet::Render::HTML
        method link (line 286) | def link(link, _title, content)
      function copyright_markdown (line 292) | def self.copyright_markdown
      function render_copyright (line 299) | def self.render_copyright(markdown_text)

FILE: lib/jazzy/podspec_documenter.rb
  type Jazzy (line 6) | module Jazzy
    class PodspecDocumenter (line 8) | class PodspecDocumenter
      method initialize (line 11) | def initialize(podspec)
      method sourcekitten_output (line 17) | def sourcekitten_output(config)
      method create_podspec (line 39) | def self.create_podspec(podspec_path)
      method apply_config_defaults (line 48) | def self.apply_config_defaults(podspec, config)
      method author_name (line 83) | def self.author_name(podspec)
      method github_file_prefix (line 93) | def self.github_file_prefix(podspec)
      method compiler_swift_version (line 115) | def compiler_swift_version(user_version)
      method podspec_swift_version (line 125) | def podspec_swift_version
      method pod_path (line 136) | def pod_path
      method podfile (line 145) | def podfile(config)

FILE: lib/jazzy/search_builder.rb
  type Jazzy (line 3) | module Jazzy
    type SearchBuilder (line 4) | module SearchBuilder
      function build (line 5) | def self.build(source_module, output_dir)

FILE: lib/jazzy/source_declaration.rb
  type Jazzy (line 6) | module Jazzy
    class SourceDeclaration (line 8) | class SourceDeclaration
      method render_as_page? (line 15) | def render_as_page?
      method swift? (line 21) | def swift?
      method highlight_language (line 25) | def highlight_language
      method omit_content_from_parent? (line 31) | def omit_content_from_parent?
      method children= (line 46) | def children=(new_children)
      method namespace_path (line 53) | def namespace_path
      method namespace_ancestors (line 57) | def namespace_ancestors
      method fully_qualified_name (line 66) | def fully_qualified_name
      method fully_qualified_name_regexp (line 72) | def fully_qualified_name_regexp
      method fully_qualified_module_name_parts (line 78) | def fully_qualified_module_name_parts
      method fully_qualified_module_name (line 84) | def fully_qualified_module_name
      method docs_path (line 89) | def docs_path
      method objc_category_name (line 96) | def objc_category_name
      method swift_objc_extension? (line 100) | def swift_objc_extension?
      method swift_extension_objc_name (line 104) | def swift_extension_objc_name
      method display_language (line 111) | def display_language
      method display_declaration (line 117) | def display_declaration
      method display_other_language_declaration (line 123) | def display_other_language_declaration
      method usage_discouraged? (line 164) | def usage_discouraged?
      method filepath (line 168) | def filepath
      method docs_filename (line 173) | def docs_filename
      method constrained_extension? (line 182) | def constrained_extension?
      method mark_for_children (line 187) | def mark_for_children
      method inherited_types? (line 195) | def inherited_types?
      method other_inherited_types? (line 201) | def other_inherited_types?(unwanted)
      method type_from_doc_module? (line 209) | def type_from_doc_module?
      method mark_undocumented? (line 217) | def mark_undocumented?
      method extension_of_external_type? (line 221) | def extension_of_external_type?
      method ambiguous_module_name? (line 227) | def ambiguous_module_name?(group_name)
      method need_doc_module_note? (line 235) | def need_doc_module_note?
      method declaration_note (line 249) | def declaration_note
      method simplified_typename (line 261) | def simplified_typename
      method default_implementation? (line 267) | def default_implementation?(candidate)
      method readme? (line 274) | def readme?
      method alternative_abstract (line 278) | def alternative_abstract
      method alternative_abstract_file (line 284) | def alternative_abstract_file
      method abstract_glob (line 291) | def abstract_glob

FILE: lib/jazzy/source_declaration/access_control_level.rb
  type Jazzy (line 3) | module Jazzy
    class SourceDeclaration (line 4) | class SourceDeclaration
      class AccessControlLevel (line 5) | class AccessControlLevel
        method initialize (line 15) | def initialize(level)
        method from_accessibility (line 20) | def self.from_accessibility(accessibility)
        method from_doc (line 33) | def self.from_doc(doc)
        method implicit_deinit? (line 43) | def self.implicit_deinit?(doc)
        method from_doc_explicit_declaration (line 49) | def self.from_doc_explicit_declaration(doc)
        method from_human_string (line 60) | def self.from_human_string(string)
        method from_documentation_attribute (line 70) | def self.from_documentation_attribute(doc)
        method <=> (line 86) | def <=>(other)
        method included_levels (line 90) | def included_levels
        method excluded_levels (line 94) | def excluded_levels

FILE: lib/jazzy/source_declaration/type.rb
  type Jazzy (line 7) | module Jazzy
    class SourceDeclaration (line 8) | class SourceDeclaration
      class Type (line 10) | class Type
        method all (line 11) | def self.all
        method initialize (line 17) | def initialize(kind, declaration = nil)
        method fixup_kind (line 24) | def fixup_kind(kind, declaration)
        method dash_type (line 35) | def dash_type
        method name (line 39) | def name
        method global? (line 45) | def global?
        method url_name (line 50) | def url_name
        method name_controlled_manually? (line 54) | def name_controlled_manually?
        method plural_name (line 61) | def plural_name
        method plural_url_name (line 65) | def plural_url_name
        method objc_mark? (line 69) | def objc_mark?
        method swift_mark? (line 74) | def swift_mark?
        method mark? (line 78) | def mark?
        method task_mark? (line 83) | def task_mark?(name)
        method objc_enum? (line 87) | def objc_enum?
        method objc_typedef? (line 91) | def objc_typedef?
        method objc_category? (line 95) | def objc_category?
        method objc_class? (line 99) | def objc_class?
        method swift_type? (line 103) | def swift_type?
        method swift_enum_case? (line 107) | def swift_enum_case?
        method swift_enum_element? (line 111) | def swift_enum_element?
        method should_document? (line 115) | def should_document?
        method declaration? (line 119) | def declaration?
        method extension? (line 124) | def extension?
        method swift_extension? (line 128) | def swift_extension?
        method swift_extensible? (line 132) | def swift_extensible?
        method swift_protocol? (line 137) | def swift_protocol?
        method swift_typealias? (line 141) | def swift_typealias?
        method swift_global_function? (line 145) | def swift_global_function?
        method param? (line 149) | def param?
        method generic_type_param? (line 156) | def generic_type_param?
        method swift_variable? (line 160) | def swift_variable?
        method objc_unexposed? (line 164) | def objc_unexposed?
        method overview (line 170) | def self.overview
        method overview? (line 174) | def overview?
        method markdown (line 180) | def self.markdown
        method markdown? (line 184) | def markdown?
        method hash (line 188) | def hash
        method == (line 193) | def ==(other)

FILE: lib/jazzy/source_document.rb
  type Jazzy (line 7) | module Jazzy
    class SourceDocument (line 9) | class SourceDocument < SourceDeclaration
      method initialize (line 13) | def initialize
      method make_index (line 22) | def self.make_index(readme_path)
      method readme? (line 30) | def readme?
      method render_as_page? (line 34) | def render_as_page?
      method omit_content_from_parent? (line 38) | def omit_content_from_parent?
      method config (line 42) | def config
      method url_name (line 46) | def url_name
      method content (line 50) | def content(source_module)
      method readme_content (line 56) | def readme_content(source_module)
      method config_readme (line 60) | def config_readme
      method fallback_readme (line 64) | def fallback_readme
      method generated_readme (line 72) | def generated_readme(source_module)

FILE: lib/jazzy/source_host.rb
  type Jazzy (line 3) | module Jazzy
    type SourceHost (line 5) | module SourceHost
      function create (line 7) | def self.create(options)
      class GitHub (line 18) | class GitHub
        method name (line 22) | def name
        method extension (line 27) | def extension
        method image (line 32) | def image
        method url (line 37) | def url
        method item_url (line 44) | def item_url(item)
        method files_url (line 63) | def files_url
        method local_root_realpath (line 67) | def local_root_realpath
        method item_url_line_fragment (line 72) | def item_url_line_fragment(line)
        method item_url_multiline_fragment (line 76) | def item_url_multiline_fragment(start_line, end_line)
      class GitLab (line 82) | class GitLab < GitHub
        method name (line 83) | def name
        method image (line 87) | def image
      class BitBucket (line 93) | class BitBucket < GitHub
        method name (line 94) | def name
        method image (line 98) | def image
        method item_url_line_fragment (line 102) | def item_url_line_fragment(line)
        method item_url_multiline_fragment (line 106) | def item_url_multiline_fragment(start_line, end_line)

FILE: lib/jazzy/source_mark.rb
  type Jazzy (line 3) | module Jazzy
    class SourceMark (line 4) | class SourceMark
      method initialize (line 9) | def initialize(mark_string = nil)
      method new_generic_requirements (line 33) | def self.new_generic_requirements(requirements)
      method empty? (line 39) | def empty?
      method copy (line 43) | def copy(other)
      method can_merge? (line 50) | def can_merge?(other)

FILE: lib/jazzy/source_module.rb
  type Jazzy (line 9) | module Jazzy
    class SourceModule (line 12) | class SourceModule
      method initialize (line 24) | def initialize(docs, doc_structure, doc_coverage, docset_builder)
      method all_declarations (line 36) | def all_declarations

FILE: lib/jazzy/sourcekitten.rb
  function autolink_regex (line 21) | def autolink_regex(middle_regex, after_highlight)
  class String (line 31) | class String
    method autolink_block (line 32) | def autolink_block(doc_url, middle_regex, after_highlight)
    method unindent (line 51) | def unindent(count)
  type Jazzy (line 56) | module Jazzy
    type SourceKitten (line 58) | module SourceKitten
      function undocumented_abstract (line 59) | def self.undocumented_abstract
      function sanitize_filename (line 69) | def self.sanitize_filename(doc)
      function make_doc_urls (line 82) | def self.make_doc_urls(docs)
      function subdir_for_doc (line 119) | def self.subdir_for_doc(doc)
      function subdir_for_doc_single_module (line 130) | def self.subdir_for_doc_single_module(doc)
      function subdir_for_doc_multi_module (line 140) | def self.subdir_for_doc_multi_module(doc)
      function rec_path (line 165) | def self.rec_path(path)
      function use_spm? (line 173) | def self.use_spm?(module_config)
      function arguments_from_options (line 182) | def self.arguments_from_options(module_config)
      function objc_arguments_from_options (line 197) | def self.objc_arguments_from_options(module_config)
      function run_sourcekitten (line 218) | def self.run_sourcekitten(arguments)
      function make_default_doc_info (line 237) | def self.make_default_doc_info(declaration)
      function attribute? (line 244) | def self.attribute?(doc, attr_name)
      function availability_attribute? (line 250) | def self.availability_attribute?(doc)
      function spi_attribute? (line 254) | def self.spi_attribute?(doc)
      function should_document? (line 258) | def self.should_document?(doc)
      function should_document_spi? (line 287) | def self.should_document_spi?(doc)
      function should_document_acl? (line 297) | def self.should_document_acl?(type, doc)
      function should_document_swift_extension? (line 311) | def self.should_document_swift_extension?(doc)
      function process_undocumented_token (line 319) | def self.process_undocumented_token(doc, declaration)
      function parameters (line 335) | def self.parameters(doc, discovered)
      function make_doc_info (line 345) | def self.make_doc_info(doc, declaration)
      function highlight_declaration (line 364) | def self.highlight_declaration(doc, declaration)
      function make_deprecation_info (line 378) | def self.make_deprecation_info(doc, declaration)
      function xml_to_text (line 390) | def self.xml_to_text(xml)
      function attribute_regexp (line 398) | def self.attribute_regexp(name)
      function extract_attributes (line 411) | def self.extract_attributes(declaration, name = '\w+')
      function extract_documented_attributes (line 418) | def self.extract_documented_attributes(declaration)
      function extract_availability (line 424) | def self.extract_availability(declaration)
      function split_decl_attributes (line 429) | def self.split_decl_attributes(declaration)
      function prefer_parsed_decl? (line 434) | def self.prefer_parsed_decl?(parsed, annotated, type)
      function fix_up_compiler_decl (line 446) | def self.fix_up_compiler_decl(annotated_decl, declaration)
      function make_swift_declaration (line 458) | def self.make_swift_declaration(doc, declaration)
      function fabricate_spi_attributes (line 494) | def self.fabricate_spi_attributes(doc, attrs)
      function swift_async? (line 502) | def self.swift_async?(fully_annotated_decl)
      function make_objc_declaration (line 513) | def self.make_objc_declaration(declaration)
      function make_substructure (line 527) | def self.make_substructure(doc, declaration)
      function make_source_declarations (line 538) | def self.make_source_declarations(docs, parent = nil, mark = SourceM...
      function find_generic_requirements (line 634) | def self.find_generic_requirements(parsed_declaration)
      function expand_extensions (line 647) | def self.expand_extensions(decls)
      function expand_extension (line 661) | def self.expand_extension(extension, name_parts, decls)
      function deduplicate_declarations (line 688) | def self.deduplicate_declarations(declarations)
      function mergeable_objc? (line 700) | def self.mergeable_objc?(decl, root_decls)
      function mergeable_swift? (line 709) | def self.mergeable_swift?(decl)
      function module_deduplication_key (line 727) | def self.module_deduplication_key(decl)
      function deduplication_key (line 738) | def self.deduplication_key(decl, root_decls)
      function merge_declarations (line 761) | def self.merge_declarations(decls)
      function merge_type_and_extensions (line 795) | def self.merge_type_and_extensions(typedecls, extensions)
      function reject_inaccessible_extensions (line 817) | def self.reject_inaccessible_extensions(typedecl, extensions)
      function mark_and_merge_protocol_extensions (line 856) | def self.mark_and_merge_protocol_extensions(protocol, extensions)
      function merge_objc_declaration_marks (line 885) | def self.merge_objc_declaration_marks(typedecl, extensions)
      function move_merged_extension_marks (line 896) | def self.move_merged_extension_marks(decls)
      function merge_code_declaration (line 910) | def self.merge_code_declaration(decls)
      function next_doc_module_group (line 932) | def self.next_doc_module_group(decls)
      function need_doc_module_note? (line 941) | def self.need_doc_module_note?(decl, html_declaration)
      function autolink_text (line 960) | def self.autolink_text(text, doc, after_highlight: false)
      function autolink_text_fields (line 979) | def self.autolink_text_fields(doc)
      function autolink_highlight_fields (line 995) | def self.autolink_highlight_fields(doc)
      function autolink (line 1004) | def self.autolink(docs)
      function autolink_document (line 1013) | def self.autolink_document(html, doc)
      function filter_files (line 1022) | def self.filter_files(json)
      function filter_included_files (line 1032) | def self.filter_included_files(json)
      function filter_excluded_files (line 1043) | def self.filter_excluded_files(json)
      function reject_objc_types (line 1053) | def self.reject_objc_types(docs)
      function reject_swift_types (line 1070) | def self.reject_swift_types(docs)
      function mark_objc_external_categories (line 1075) | def self.mark_objc_external_categories(docs)
      function parse (line 1088) | def self.parse(sourcekitten_output, options, inject_docs)

FILE: lib/jazzy/stats.rb
  type Jazzy (line 3) | module Jazzy
    class Stats (line 5) | class Stats
      method add_documented (line 10) | def add_documented
      method add_acl_skipped (line 14) | def add_acl_skipped
      method add_spi_skipped (line 18) | def add_spi_skipped
      method add_undocumented (line 22) | def add_undocumented(decl)
      method remove_undocumented (line 26) | def remove_undocumented(decl)
      method acl_included (line 30) | def acl_included
      method undocumented (line 34) | def undocumented
      method initialize (line 38) | def initialize
      method report (line 43) | def report
      method doc_coverage (line 68) | def doc_coverage
      method comma_list (line 76) | def comma_list(items)
      method symbol_or_symbols (line 85) | def symbol_or_symbols(count)

FILE: lib/jazzy/symbol_graph.rb
  type Jazzy (line 16) | module Jazzy
    type SymbolGraph (line 17) | module SymbolGraph
      function build (line 23) | def self.build(module_config)
      function arguments (line 40) | def self.arguments(module_config, output_path)
      function parse_symbols (line 71) | def self.parse_symbols(directory)
      function sdk (line 87) | def self.sdk(module_config)
      function target (line 93) | def self.target
      function demangle (line 101) | def self.demangle(usr)

FILE: lib/jazzy/symbol_graph/constraint.rb
  type Jazzy (line 3) | module Jazzy
    type SymbolGraph (line 4) | module SymbolGraph
      class Constraint (line 7) | class Constraint
        method initialize (line 14) | def initialize(kind, lhs, rhs)
        method new_hash (line 30) | def self.new_hash(hash)
        method new_declaration (line 40) | def self.new_declaration(decl)
        method to_swift (line 47) | def to_swift
        method type_names (line 52) | def type_names
        method new_list (line 56) | def self.new_list(hash_list)
        method new_list_for_symbol (line 62) | def self.new_list_for_symbol(hash_list, path_components)
        method new_list_from_declaration (line 78) | def self.new_list_from_declaration(decl)
        method <=> (line 87) | def <=>(other)
        method hash (line 93) | def hash
  class Array (line 100) | class Array
    method to_where_clause (line 101) | def to_where_clause

FILE: lib/jazzy/symbol_graph/ext_key.rb
  type Jazzy (line 3) | module Jazzy
    type SymbolGraph (line 4) | module SymbolGraph
      class ExtKey (line 9) | class ExtKey
        method initialize (line 13) | def initialize(usr, constraints)
        method hash_key (line 18) | def hash_key
        method eql? (line 22) | def eql?(other)
        method hash (line 26) | def hash
      class ExtSymNode (line 31) | class ExtSymNode
        method ext_key (line 32) | def ext_key

FILE: lib/jazzy/symbol_graph/ext_node.rb
  type Jazzy (line 5) | module Jazzy
    type SymbolGraph (line 6) | module SymbolGraph
      class ExtConstraints (line 9) | class ExtConstraints
        method merged (line 14) | def merged
        method initialize (line 18) | def initialize(type_constraints, ext_constraints)
      class ExtNode (line 26) | class ExtNode < BaseNode
        method new_for_member (line 35) | def self.new_for_member(type_usr,
        method new_for_conformance (line 44) | def self.new_for_conformance(type_usr,
        method initialize (line 55) | def initialize(usr, name, constraints)
        method constraints (line 65) | def constraints
        method add_conformance (line 69) | def add_conformance(protocol)
        method full_declaration (line 73) | def full_declaration
        method to_sourcekit (line 81) | def to_sourcekit(module_name, ext_module_name)
        method sort_key (line 110) | def sort_key
        method <=> (line 114) | def <=>(other)
      class ExtSymNode (line 121) | class ExtSymNode < ExtNode
        method initialize (line 124) | def initialize(symbol)
        method to_sourcekit (line 131) | def to_sourcekit(module_name, ext_module_name)

FILE: lib/jazzy/symbol_graph/graph.rb
  type Jazzy (line 4) | module Jazzy
    type SymbolGraph (line 5) | module SymbolGraph
      class Graph (line 9) | class Graph
        method initialize (line 17) | def initialize(json, module_name, ext_module_name)
        method add_ext_member (line 42) | def add_ext_member(type_usr, member_node, constraints)
        method add_ext_conformance (line 52) | def add_ext_conformance(type_usr,
        method rel_target_name (line 70) | def rel_target_name(rel, target_node)
        method rel_source_name (line 77) | def rel_source_name(rel, source_node)
        method redundant_conformance? (line 86) | def redundant_conformance?(rel, type, protocol)
        method rebuild_member (line 94) | def rebuild_member(rel, source, target)
        method rebuild_conformance (line 109) | def rebuild_conformance(rel, source, target)
        method rebuild_default_implementation (line 127) | def rebuild_default_implementation(_rel, source, target)
        method rebuild_inherits (line 149) | def rebuild_inherits(_rel, source, target)
        method unalias_extensions (line 156) | def unalias_extensions(fake_usr, real_usr)
        method rebuild_rel (line 165) | def rebuild_rel(rel)
        method to_sourcekit (line 191) | def to_sourcekit

FILE: lib/jazzy/symbol_graph/relationship.rb
  type Jazzy (line 3) | module Jazzy
    type SymbolGraph (line 4) | module SymbolGraph
      class Relationship (line 6) | class Relationship
        method protocol_requirement? (line 22) | def protocol_requirement?
        method default_implementation? (line 26) | def default_implementation?
        method extension_to? (line 30) | def extension_to?
        method actor_protocol? (line 36) | def actor_protocol?
        method initialize (line 40) | def initialize(hash)
        method <=> (line 59) | def <=>(other)

FILE: lib/jazzy/symbol_graph/sym_node.rb
  type Jazzy (line 3) | module Jazzy
    type SymbolGraph (line 4) | module SymbolGraph
      class BaseNode (line 8) | class BaseNode
        method initialize (line 12) | def initialize
        method add_child (line 16) | def add_child(child)
        method add_children_to_sourcekit (line 21) | def add_children_to_sourcekit(hash, module_name)
      class SymNode (line 31) | class SymNode < BaseNode
        method override? (line 38) | def override?
        method protocol_requirement? (line 42) | def protocol_requirement?
        method top_level_decl? (line 46) | def top_level_decl?
        method initialize (line 50) | def initialize(symbol)
        method qualified_name (line 55) | def qualified_name
        method parent_qualified_name (line 59) | def parent_qualified_name
        method protocol? (line 63) | def protocol?
        method actor? (line 67) | def actor?
        method constraints (line 71) | def constraints
        method add_child? (line 79) | def add_child?(node, unique_context_constraints)
        method unique_context_constraints (line 92) | def unique_context_constraints(context)
        method conformance? (line 104) | def conformance?(protocol)
        method where_clause (line 111) | def where_clause
        method inherits_clause (line 116) | def inherits_clause
        method async? (line 123) | def async?
        method full_declaration (line 127) | def full_declaration
        method to_sourcekit (line 133) | def to_sourcekit(module_name)
        method <=> (line 159) | def <=>(other)

FILE: lib/jazzy/symbol_graph/symbol.rb
  type Jazzy (line 4) | module Jazzy
    type SymbolGraph (line 5) | module SymbolGraph
      class Symbol (line 7) | class Symbol
        method name (line 21) | def name
        method full_name (line 25) | def full_name
        method initialize (line 29) | def initialize(hash)
        method parse_decl_fragments (line 51) | def parse_decl_fragments(fragments)
        method init_declaration (line 63) | def init_declaration(raw_decl)
        method init_func_signature (line 77) | def init_func_signature(func_signature)
        method adjust_kind_for_declaration (line 113) | def adjust_kind_for_declaration(kind, keywords)
        method init_kind (line 122) | def init_kind(kind, keywords)
        method extension? (line 130) | def extension?
        method init_acl (line 136) | def init_acl(acl)
        method init_location (line 142) | def init_location(loc_hash)
        method init_constraints (line 151) | def init_constraints(hash, raw_decl)
        method init_generic_type_params (line 169) | def init_generic_type_params(hash)
        method init_doc_comments (line 180) | def init_doc_comments(comments_hash)
        method availability_attributes (line 189) | def availability_attributes(avail_hash_list)
        method decode_version (line 213) | def decode_version(hash)
        method spi_attributes (line 220) | def spi_attributes
        method init_attributes (line 224) | def init_attributes(avail_hash_list)
        method add_to_sourcekit (line 231) | def add_to_sourcekit(hash)
        method <=> (line 251) | def <=>(other)

FILE: lib/jazzy/themes/apple/assets/js/jazzy.js
  function toggleItem (line 15) | function toggleItem($link, $content) {
  function itemLinkToContent (line 21) | function itemLinkToContent($link) {
  function openCurrentItemIfClosed (line 26) | function openCurrentItemIfClosed() {

FILE: lib/jazzy/themes/apple/assets/js/jazzy.search.js
  function displayTemplate (line 10) | function displayTemplate(result) {
  function suggestionTemplate (line 14) | function suggestionTemplate(result) {

FILE: lib/jazzy/themes/apple/assets/js/typeahead.jquery.js
  function reverseArgs (line 55) | function reverseArgs(index, value) {
  function template (line 100) | function template() {
  function _p8 (line 153) | function _p8(s) {
  function build (line 178) | function build(o) {
  function buildHtml (line 197) | function buildHtml(c) {
  function buildSelectors (line 203) | function buildSelectors(classes) {
  function buildCss (line 210) | function buildCss() {
  function EventBus (line 267) | function EventBus(o) {
  function on (line 304) | function on(method, types, cb, context) {
  function onAsync (line 321) | function onAsync(types, cb, context) {
  function onSync (line 324) | function onSync(types, cb, context) {
  function off (line 327) | function off(types) {
  function trigger (line 338) | function trigger(types) {
  function getFlush (line 352) | function getFlush(callbacks, context, args) {
  function getNextTick (line 362) | function getNextTick() {
  function bindContext (line 379) | function bindContext(fn, context) {
  function hightlightTextNode (line 433) | function hightlightTextNode(textNode) {
  function traverse (line 445) | function traverse(el, hightlightTextNode) {
  function accent_replacer (line 457) | function accent_replacer(chr) {
  function getRegex (line 460) | function getRegex(patterns, caseSensitive, wordsOnly, diacriticInsensiti...
  function Input (line 485) | function Input(o, www) {
  function buildOverflowHelper (line 685) | function buildOverflowHelper($input) {
  function areQueriesEquivalent (line 702) | function areQueriesEquivalent(a, b) {
  function withModifier (line 705) | function withModifier($e) {
  function Dataset (line 718) | function Dataset(o, www) {
  function sync (line 859) | function sync(suggestions) {
  function async (line 871) | function async(suggestions) {
  function getDisplayFn (line 896) | function getDisplayFn(display) {
  function getTemplates (line 903) | function getTemplates(templates, displayFn) {
  function isValidName (line 919) | function isValidName(str) {
  function Menu (line 925) | function Menu(o, www) {
  function updateDataset (line 1047) | function updateDataset(dataset) {
  function clearDataset (line 1055) | function clearDataset(dataset) {
  function destroyDataset (line 1063) | function destroyDataset(dataset) {
  function Status (line 1072) | function Status(options) {
  function DefaultMenu (line 1122) | function DefaultMenu() {
  function Typeahead (line 1165) | function Typeahead(o, www) {
  function c (line 1448) | function c(ctx) {
  function attach (line 1474) | function attach() {
  function ttEach (line 1633) | function ttEach($els, fn) {
  function buildHintFromInput (line 1639) | function buildHintFromInput($input, www) {
  function prepInput (line 1648) | function prepInput($input, www) {
  function getBackgroundStyles (line 1663) | function getBackgroundStyles($el) {
  function revert (line 1675) | function revert($input) {
  function $elOrNull (line 1688) | function $elOrNull(obj) {

FILE: lib/jazzy/themes/fullwidth/assets/js/jazzy.js
  function toggleItem (line 15) | function toggleItem($link, $content) {
  function itemLinkToContent (line 21) | function itemLinkToContent($link) {
  function openCurrentItemIfClosed (line 26) | function openCurrentItemIfClosed() {

FILE: lib/jazzy/themes/fullwidth/assets/js/jazzy.search.js
  function displayTemplate (line 10) | function displayTemplate(result) {
  function suggestionTemplate (line 14) | function suggestionTemplate(result) {

FILE: lib/jazzy/themes/fullwidth/assets/js/typeahead.jquery.js
  function reverseArgs (line 55) | function reverseArgs(index, value) {
  function template (line 100) | function template() {
  function _p8 (line 153) | function _p8(s) {
  function build (line 178) | function build(o) {
  function buildHtml (line 197) | function buildHtml(c) {
  function buildSelectors (line 203) | function buildSelectors(classes) {
  function buildCss (line 210) | function buildCss() {
  function EventBus (line 267) | function EventBus(o) {
  function on (line 304) | function on(method, types, cb, context) {
  function onAsync (line 321) | function onAsync(types, cb, context) {
  function onSync (line 324) | function onSync(types, cb, context) {
  function off (line 327) | function off(types) {
  function trigger (line 338) | function trigger(types) {
  function getFlush (line 352) | function getFlush(callbacks, context, args) {
  function getNextTick (line 362) | function getNextTick() {
  function bindContext (line 379) | function bindContext(fn, context) {
  function hightlightTextNode (line 433) | function hightlightTextNode(textNode) {
  function traverse (line 445) | function traverse(el, hightlightTextNode) {
  function accent_replacer (line 457) | function accent_replacer(chr) {
  function getRegex (line 460) | function getRegex(patterns, caseSensitive, wordsOnly, diacriticInsensiti...
  function Input (line 485) | function Input(o, www) {
  function buildOverflowHelper (line 685) | function buildOverflowHelper($input) {
  function areQueriesEquivalent (line 702) | function areQueriesEquivalent(a, b) {
  function withModifier (line 705) | function withModifier($e) {
  function Dataset (line 718) | function Dataset(o, www) {
  function sync (line 859) | function sync(suggestions) {
  function async (line 871) | function async(suggestions) {
  function getDisplayFn (line 896) | function getDisplayFn(display) {
  function getTemplates (line 903) | function getTemplates(templates, displayFn) {
  function isValidName (line 919) | function isValidName(str) {
  function Menu (line 925) | function Menu(o, www) {
  function updateDataset (line 1047) | function updateDataset(dataset) {
  function clearDataset (line 1055) | function clearDataset(dataset) {
  function destroyDataset (line 1063) | function destroyDataset(dataset) {
  function Status (line 1072) | function Status(options) {
  function DefaultMenu (line 1122) | function DefaultMenu() {
  function Typeahead (line 1165) | function Typeahead(o, www) {
  function c (line 1448) | function c(ctx) {
  function attach (line 1474) | function attach() {
  function ttEach (line 1633) | function ttEach($els, fn) {
  function buildHintFromInput (line 1639) | function buildHintFromInput($input, www) {
  function prepInput (line 1648) | function prepInput($input, www) {
  function getBackgroundStyles (line 1663) | function getBackgroundStyles($el) {
  function revert (line 1675) | function revert($input) {
  function $elOrNull (line 1688) | function $elOrNull(obj) {

FILE: lib/jazzy/themes/jony/assets/js/jazzy.js
  function toggleItem (line 15) | function toggleItem($link, $content) {
  function itemLinkToContent (line 21) | function itemLinkToContent($link) {
  function openCurrentItemIfClosed (line 26) | function openCurrentItemIfClosed() {

FILE: spec/integration_spec.rb
  function configure_cocoapods (line 54) | def configure_cocoapods

FILE: spec/spec_helper.rb
  type Bacon (line 20) | module Bacon
    class Context (line 21) | class Context
      method temporary_directory (line 24) | def temporary_directory
  type SpecHelper (line 32) | module SpecHelper
    function temporary_directory (line 33) | def self.temporary_directory

FILE: spec/spec_helper/pre_flight.rb
  type Bacon (line 5) | module Bacon
    class Context (line 6) | class Context
Condensed preview — 90 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (566K chars).
[
  {
    "path": ".github/workflows/Tests.yml",
    "chars": 1269,
    "preview": "name: Tests\n  \non:\n  push:\n    branches: [master]\n  pull_request:\n    branches: ['*']\n\njobs:\n  danger_and_rubocop:\n    r"
  },
  {
    "path": ".gitignore",
    "chars": 894,
    "preview": "jazzy-docs/\n/docs/\nnode_modules\n\n*.gem\n*.rbc\n/.config\n/coverage/\n/InstalledFiles\n/pkg/\n/spec/reports/\n/test/tmp/\n/test/v"
  },
  {
    "path": ".gitmodules",
    "chars": 225,
    "preview": "[submodule \"SourceKitten\"]\n\tpath = SourceKitten\n\turl = https://github.com/jpsim/SourceKitten.git\n[submodule \"spec/integr"
  },
  {
    "path": ".rubocop.yml",
    "chars": 11459,
    "preview": "AllCops:\n  Exclude:\n    - ./spec/integration_specs/**/*\n    - ./spec/Moya.podspec\n    - ./vendor/**/*\n    - ./tmp/**/*\n "
  },
  {
    "path": "CHANGELOG.md",
    "chars": 55664,
    "preview": "## Master\n\n##### Breaking\n\n* None.\n\n##### Enhancements\n\n* None.\n\n##### Bug Fixes\n\n* None.\n\n## 0.15.4\n\n##### Breaking\n\n* "
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 2205,
    "preview": "## Code of Conduct\n\nThis project adheres to the [Contributor Covenant Code of Conduct](https://realm.io/conduct).\nBy par"
  },
  {
    "path": "Dangerfile",
    "chars": 1222,
    "preview": "# frozen_string_literal: true\n\n# Warn when there is a big PR\nwarn('Big PR') if git.lines_of_code > 500\n\n# Don't let test"
  },
  {
    "path": "Gemfile",
    "chars": 381,
    "preview": "# frozen_string_literal: true\n\nsource 'https://rubygems.org'\n\ngemspec\n\ngroup :development do\n  # Code style\n  gem 'ruboc"
  },
  {
    "path": "LICENSE",
    "chars": 1076,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 Realm Inc.\n\nPermission is hereby granted, free of charge, to any person obtain"
  },
  {
    "path": "ObjectiveC.md",
    "chars": 8824,
    "preview": "This document is about Jazzy's Objective-C documentation generation.\n\nIt's intended for users who are having problems af"
  },
  {
    "path": "README.md",
    "chars": 28966,
    "preview": "![jazzy](images/logo.jpg)\n\n[![Build Status](https://github.com/realm/jazzy/actions/workflows/Tests.yml/badge.svg)](https"
  },
  {
    "path": "Rakefile",
    "chars": 4676,
    "preview": "# frozen_string_literal: true\n\n#-- Bootstrap --------------------------------------------------------------#\n\ndesc 'Init"
  },
  {
    "path": "bin/jazzy",
    "chars": 436,
    "preview": "#!/usr/bin/env ruby\n# frozen_string_literal: true\n\nif $PROGRAM_NAME == __FILE__ && !ENV['JAZZY_NO_BUNDLER']\n  ENV['BUNDL"
  },
  {
    "path": "jazzy.gemspec",
    "chars": 1431,
    "preview": "# coding: utf-8\n# frozen_string_literal: true\n\nrequire File.expand_path('lib/jazzy/gem_version.rb', File.dirname(__FILE_"
  },
  {
    "path": "js/package.json",
    "chars": 356,
    "preview": "{\n  \"name\": \"jazzy-js\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Jazzy theme dependencies\",\n  \"main\": \"index.js\",\n  \"scri"
  },
  {
    "path": "lib/jazzy/config.rb",
    "chars": 28035,
    "preview": "# frozen_string_literal: true\n\nrequire 'optparse'\nrequire 'pathname'\nrequire 'uri'\n\nrequire 'jazzy/podspec_documenter'\nr"
  },
  {
    "path": "lib/jazzy/doc.rb",
    "chars": 1522,
    "preview": "# frozen_string_literal: true\n\nrequire 'date'\nrequire 'pathname'\nrequire 'mustache'\n\nrequire 'jazzy/config'\nrequire 'jaz"
  },
  {
    "path": "lib/jazzy/doc_builder.rb",
    "chars": 17084,
    "preview": "# frozen_string_literal: true\n\nrequire 'fileutils'\nrequire 'mustache'\nrequire 'pathname'\nrequire 'sassc'\n\nrequire 'jazzy"
  },
  {
    "path": "lib/jazzy/doc_index.rb",
    "chars": 6342,
    "preview": "# frozen_string_literal: true\n\nmodule Jazzy\n  # This class stores an index of symbol names for doing name lookup\n  # whe"
  },
  {
    "path": "lib/jazzy/docset_builder/info_plist.mustache",
    "chars": 858,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "lib/jazzy/docset_builder.rb",
    "chars": 4161,
    "preview": "# frozen_string_literal: true\n\nrequire 'mustache'\nrequire 'sqlite3'\n\nmodule Jazzy\n  module DocBuilder\n    # Follows the "
  },
  {
    "path": "lib/jazzy/documentation_generator.rb",
    "chars": 795,
    "preview": "# frozen_string_literal: true\n\nrequire 'pathname'\n\nrequire 'jazzy/jazzy_markdown'\nrequire 'jazzy/source_document'\n\nmodul"
  },
  {
    "path": "lib/jazzy/executable.rb",
    "chars": 1142,
    "preview": "# frozen_string_literal: true\n\nmodule Jazzy\n  module Executable\n    class IO < Array\n      def initialize(io = nil)\n    "
  },
  {
    "path": "lib/jazzy/gem_version.rb",
    "chars": 100,
    "preview": "# frozen_string_literal: true\n\nmodule Jazzy\n  VERSION = '0.15.4' unless defined? Jazzy::VERSION\nend\n"
  },
  {
    "path": "lib/jazzy/grouper.rb",
    "chars": 4682,
    "preview": "# frozen_string_literal: true\n\nmodule Jazzy\n  # This module deals with arranging top-level declarations and guides into\n"
  },
  {
    "path": "lib/jazzy/highlighter.rb",
    "chars": 743,
    "preview": "# frozen_string_literal: true\n\nrequire 'rouge'\n\nmodule Jazzy\n  # This module helps highlight code\n  module Highlighter\n "
  },
  {
    "path": "lib/jazzy/jazzy_markdown.rb",
    "chars": 8977,
    "preview": "# frozen_string_literal: true\n\nrequire 'redcarpet'\nrequire 'rouge'\nrequire 'rouge/plugins/redcarpet'\n\nmodule Jazzy\n  mod"
  },
  {
    "path": "lib/jazzy/podspec_documenter.rb",
    "chars": 5693,
    "preview": "# frozen_string_literal: true\n\nrequire 'tmpdir'\nrequire 'json'\n\nmodule Jazzy\n  # rubocop:disable Metrics/ClassLength\n  c"
  },
  {
    "path": "lib/jazzy/search_builder.rb",
    "chars": 582,
    "preview": "# frozen_string_literal: true\n\nmodule Jazzy\n  module SearchBuilder\n    def self.build(source_module, output_dir)\n      d"
  },
  {
    "path": "lib/jazzy/source_declaration/access_control_level.rb",
    "chars": 2733,
    "preview": "# frozen_string_literal: true\n\nmodule Jazzy\n  class SourceDeclaration\n    class AccessControlLevel\n      include Compara"
  },
  {
    "path": "lib/jazzy/source_declaration/type.rb",
    "chars": 13281,
    "preview": "# frozen_string_literal: true\n\nrequire 'logger'\nrequire 'active_support'\nrequire 'active_support/inflector'\n\nmodule Jazz"
  },
  {
    "path": "lib/jazzy/source_declaration.rb",
    "chars": 8615,
    "preview": "# frozen_string_literal: true\n\nrequire 'jazzy/source_declaration/access_control_level'\nrequire 'jazzy/source_declaration"
  },
  {
    "path": "lib/jazzy/source_document.rb",
    "chars": 1975,
    "preview": "# frozen_string_literal: true\n\nrequire 'pathname'\n\nrequire 'jazzy/jazzy_markdown'\n\nmodule Jazzy\n  # Standalone markdown "
  },
  {
    "path": "lib/jazzy/source_host.rb",
    "chars": 2510,
    "preview": "# frozen_string_literal: true\n\nmodule Jazzy\n  # Deal with different source code repositories\n  module SourceHost\n    # F"
  },
  {
    "path": "lib/jazzy/source_mark.rb",
    "chars": 1323,
    "preview": "# frozen_string_literal: true\n\nmodule Jazzy\n  class SourceMark\n    attr_accessor :name\n    attr_accessor :has_start_dash"
  },
  {
    "path": "lib/jazzy/source_module.rb",
    "chars": 1309,
    "preview": "# frozen_string_literal: true\n\nrequire 'uri'\n\nrequire 'jazzy/config'\nrequire 'jazzy/source_declaration'\nrequire 'jazzy/s"
  },
  {
    "path": "lib/jazzy/sourcekitten.rb",
    "chars": 39081,
    "preview": "# frozen_string_literal: true\n\nrequire 'json'\nrequire 'pathname'\nrequire 'shellwords'\nrequire 'xcinvoke'\nrequire 'cgi'\nr"
  },
  {
    "path": "lib/jazzy/stats.rb",
    "chars": 2079,
    "preview": "# frozen_string_literal: true\n\nmodule Jazzy\n  # Collect + report metadata about a processed module\n  class Stats\n    inc"
  },
  {
    "path": "lib/jazzy/symbol_graph/constraint.rb",
    "chars": 2576,
    "preview": "# frozen_string_literal: true\n\nmodule Jazzy\n  module SymbolGraph\n    # Constraint is a tidied-up JSON object, used by bo"
  },
  {
    "path": "lib/jazzy/symbol_graph/ext_key.rb",
    "chars": 882,
    "preview": "# frozen_string_literal: true\n\nmodule Jazzy\n  module SymbolGraph\n    # An ExtKey identifies an extension of a type, made"
  },
  {
    "path": "lib/jazzy/symbol_graph/ext_node.rb",
    "chars": 3994,
    "preview": "# frozen_string_literal: true\n\nrequire 'set'\n\nmodule Jazzy\n  module SymbolGraph\n    # For extensions we need to track co"
  },
  {
    "path": "lib/jazzy/symbol_graph/graph.rb",
    "chars": 7124,
    "preview": "# frozen_string_literal: true\n\n# rubocop:disable Metrics/ClassLength\nmodule Jazzy\n  module SymbolGraph\n    # A Graph is "
  },
  {
    "path": "lib/jazzy/symbol_graph/relationship.rb",
    "chars": 1916,
    "preview": "# frozen_string_literal: true\n\nmodule Jazzy\n  module SymbolGraph\n    # A Relationship is a tidied-up SymbolGraph JSON ob"
  },
  {
    "path": "lib/jazzy/symbol_graph/sym_node.rb",
    "chars": 4516,
    "preview": "# frozen_string_literal: true\n\nmodule Jazzy\n  module SymbolGraph\n    # The rebuilt syntax tree is made of nodes that eit"
  },
  {
    "path": "lib/jazzy/symbol_graph/symbol.rb",
    "chars": 8818,
    "preview": "# frozen_string_literal: true\n\n# rubocop:disable Metrics/ClassLength\nmodule Jazzy\n  module SymbolGraph\n    # A Symbol is"
  },
  {
    "path": "lib/jazzy/symbol_graph.rb",
    "chars": 3788,
    "preview": "# frozen_string_literal: true\n\nrequire 'set'\nrequire 'jazzy/symbol_graph/graph'\nrequire 'jazzy/symbol_graph/constraint'\n"
  },
  {
    "path": "lib/jazzy/themes/apple/assets/css/highlight.css.scss",
    "chars": 3264,
    "preview": "/*! Jazzy - https://github.com/realm/jazzy\n *  Copyright Realm Inc.\n *  SPDX-License-Identifier: MIT\n */\n/* Credit to ht"
  },
  {
    "path": "lib/jazzy/themes/apple/assets/css/jazzy.css.scss",
    "chars": 10953,
    "preview": "/*! Jazzy - https://github.com/realm/jazzy\n *  Copyright Realm Inc.\n *  SPDX-License-Identifier: MIT\n */\n///////////////"
  },
  {
    "path": "lib/jazzy/themes/apple/assets/js/jazzy.js",
    "chars": 1876,
    "preview": "// Jazzy - https://github.com/realm/jazzy\n// Copyright Realm Inc.\n// SPDX-License-Identifier: MIT\n\nwindow.jazzy = {'docs"
  },
  {
    "path": "lib/jazzy/themes/apple/assets/js/jazzy.search.js",
    "chars": 2100,
    "preview": "// Jazzy - https://github.com/realm/jazzy\n// Copyright Realm Inc.\n// SPDX-License-Identifier: MIT\n\n$(function(){\n  var $"
  },
  {
    "path": "lib/jazzy/themes/apple/assets/js/typeahead.jquery.js",
    "chars": 70178,
    "preview": "/*!\n * typeahead.js 1.3.3\n * https://github.com/corejavascript/typeahead.js\n * Copyright 2013-2024 Twitter, Inc. and oth"
  },
  {
    "path": "lib/jazzy/themes/apple/templates/deprecation.mustache",
    "chars": 326,
    "preview": "{{#deprecation_message}}\n<div class=\"aside aside-deprecated\">\n  <p class=\"aside-title\">Deprecated</p>\n  {{{deprecation_m"
  },
  {
    "path": "lib/jazzy/themes/apple/templates/doc.mustache",
    "chars": 3295,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <title>{{name}} {{kind}} Reference</title>\n    <link rel=\"stylesheet\" type"
  },
  {
    "path": "lib/jazzy/themes/apple/templates/footer.mustache",
    "chars": 301,
    "preview": "<section id=\"footer\">\n  {{{copyright}}}\n  <p>Generated by <a class=\"link\" href=\"https://github.com/realm/jazzy\" target=\""
  },
  {
    "path": "lib/jazzy/themes/apple/templates/header.mustache",
    "chars": 813,
    "preview": "<header>\n  <div class=\"content-wrapper\">\n    <p><a href=\"{{path_to_root}}index.html\">{{docs_title}}</a>{{#doc_coverage}}"
  },
  {
    "path": "lib/jazzy/themes/apple/templates/nav.mustache",
    "chars": 397,
    "preview": "<nav class=\"sidebar\">\n  <ul class=\"nav-groups\">\n    {{#structure}}\n    <li class=\"nav-group-name\">\n      <a href=\"{{path"
  },
  {
    "path": "lib/jazzy/themes/apple/templates/parameter.mustache",
    "chars": 130,
    "preview": "<tr>\n  <td>\n    <code>\n    <em>{{name}}</em>\n    </code>\n  </td>\n  <td>\n    <div>\n      {{{discussion}}}\n    </div>\n  </"
  },
  {
    "path": "lib/jazzy/themes/apple/templates/task.mustache",
    "chars": 3145,
    "preview": "<div class=\"task-group\">\n  {{#name}}\n  <div class=\"task-name-container\">\n    <a name=\"/{{uid}}\"></a>\n    <a name=\"//appl"
  },
  {
    "path": "lib/jazzy/themes/apple/templates/tasks.mustache",
    "chars": 129,
    "preview": "{{#tasks.count}}\n<section class=\"section task-group-section\">\n  {{#tasks}}\n  {{> task}}\n  {{/tasks}}\n</section>\n{{/tasks"
  },
  {
    "path": "lib/jazzy/themes/fullwidth/assets/css/highlight.css.scss",
    "chars": 3264,
    "preview": "/*! Jazzy - https://github.com/realm/jazzy\n *  Copyright Realm Inc.\n *  SPDX-License-Identifier: MIT\n */\n/* Credit to ht"
  },
  {
    "path": "lib/jazzy/themes/fullwidth/assets/css/jazzy.css.scss",
    "chars": 11288,
    "preview": "/*! Jazzy - https://github.com/realm/jazzy\n *  Copyright Realm Inc.\n *  SPDX-License-Identifier: MIT\n */\n// ============"
  },
  {
    "path": "lib/jazzy/themes/fullwidth/assets/js/jazzy.js",
    "chars": 1876,
    "preview": "// Jazzy - https://github.com/realm/jazzy\n// Copyright Realm Inc.\n// SPDX-License-Identifier: MIT\n\nwindow.jazzy = {'docs"
  },
  {
    "path": "lib/jazzy/themes/fullwidth/assets/js/jazzy.search.js",
    "chars": 2100,
    "preview": "// Jazzy - https://github.com/realm/jazzy\n// Copyright Realm Inc.\n// SPDX-License-Identifier: MIT\n\n$(function(){\n  var $"
  },
  {
    "path": "lib/jazzy/themes/fullwidth/assets/js/typeahead.jquery.js",
    "chars": 70178,
    "preview": "/*!\n * typeahead.js 1.3.3\n * https://github.com/corejavascript/typeahead.js\n * Copyright 2013-2024 Twitter, Inc. and oth"
  },
  {
    "path": "lib/jazzy/themes/fullwidth/templates/deprecation.mustache",
    "chars": 326,
    "preview": "{{#deprecation_message}}\n<div class=\"aside aside-deprecated\">\n  <p class=\"aside-title\">Deprecated</p>\n  {{{deprecation_m"
  },
  {
    "path": "lib/jazzy/themes/fullwidth/templates/doc.mustache",
    "chars": 3299,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <title>{{name}} {{kind}} Reference</title>\n    <link rel=\"stylesheet\" type"
  },
  {
    "path": "lib/jazzy/themes/fullwidth/templates/footer.mustache",
    "chars": 304,
    "preview": "<section class=\"footer\">\n  {{{copyright}}}\n  <p>Generated by <a class=\"link\" href=\"https://github.com/realm/jazzy\" targe"
  },
  {
    "path": "lib/jazzy/themes/fullwidth/templates/header.mustache",
    "chars": 1053,
    "preview": "<header class=\"header\">\n  <p class=\"header-col header-col--primary\">\n    <a class=\"header-link\" href=\"{{path_to_root}}in"
  },
  {
    "path": "lib/jazzy/themes/fullwidth/templates/nav.mustache",
    "chars": 456,
    "preview": "<nav class=\"navigation\">\n  <ul class=\"nav-groups\">\n    {{#structure}}\n    <li class=\"nav-group-name\">\n      <a class=\"na"
  },
  {
    "path": "lib/jazzy/themes/fullwidth/templates/parameter.mustache",
    "chars": 130,
    "preview": "<tr>\n  <td>\n    <code>\n    <em>{{name}}</em>\n    </code>\n  </td>\n  <td>\n    <div>\n      {{{discussion}}}\n    </div>\n  </"
  },
  {
    "path": "lib/jazzy/themes/fullwidth/templates/task.mustache",
    "chars": 3168,
    "preview": "<div class=\"task-group\">\n  {{#name}}\n  <div class=\"task-name-container\">\n    <a name=\"/{{uid}}\"></a>\n    <a name=\"//appl"
  },
  {
    "path": "lib/jazzy/themes/fullwidth/templates/tasks.mustache",
    "chars": 157,
    "preview": "{{#tasks.count}}\n<section class=\"section\">\n  <div class=\"section-content\">\n    {{#tasks}}\n    {{> task}}\n    {{/tasks}}\n"
  },
  {
    "path": "lib/jazzy/themes/jony/assets/css/highlight.css.scss",
    "chars": 3264,
    "preview": "/*! Jazzy - https://github.com/realm/jazzy\n *  Copyright Realm Inc.\n *  SPDX-License-Identifier: MIT\n */\n/* Credit to ht"
  },
  {
    "path": "lib/jazzy/themes/jony/assets/css/jazzy.css.scss",
    "chars": 10161,
    "preview": "/*! Jazzy - https://github.com/realm/jazzy\n *  Copyright Realm Inc.\n *  SPDX-License-Identifier: MIT\n */\n///////////////"
  },
  {
    "path": "lib/jazzy/themes/jony/assets/js/jazzy.js",
    "chars": 1876,
    "preview": "// Jazzy - https://github.com/realm/jazzy\n// Copyright Realm Inc.\n// SPDX-License-Identifier: MIT\n\nwindow.jazzy = {'docs"
  },
  {
    "path": "lib/jazzy/themes/jony/templates/deprecation.mustache",
    "chars": 326,
    "preview": "{{#deprecation_message}}\n<div class=\"aside aside-deprecated\">\n  <p class=\"aside-title\">Deprecated</p>\n  {{{deprecation_m"
  },
  {
    "path": "lib/jazzy/themes/jony/templates/doc.mustache",
    "chars": 3513,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <title>{{name}} {{kind}} Reference</title>\n    <link rel=\"stylesheet\" type"
  },
  {
    "path": "lib/jazzy/themes/jony/templates/footer.mustache",
    "chars": 301,
    "preview": "<section id=\"footer\">\n  {{{copyright}}}\n  <p>Generated by <a class=\"link\" href=\"https://github.com/realm/jazzy\" target=\""
  },
  {
    "path": "lib/jazzy/themes/jony/templates/header.mustache",
    "chars": 755,
    "preview": "<header>\n  <div class=\"content-wrapper\">\n    <p>\n      <a href=\"{{path_to_root}}index.html\">{{docs_title}}</a>\n      <sp"
  },
  {
    "path": "lib/jazzy/themes/jony/templates/nav.mustache",
    "chars": 400,
    "preview": "<nav class=\"nav-bottom\">\n  <ul class=\"nav-groups\">\n    {{#structure}}\n    <li class=\"nav-group-name\">\n      <a href=\"{{p"
  },
  {
    "path": "lib/jazzy/themes/jony/templates/parameter.mustache",
    "chars": 130,
    "preview": "<tr>\n  <td>\n    <code>\n    <em>{{name}}</em>\n    </code>\n  </td>\n  <td>\n    <div>\n      {{{discussion}}}\n    </div>\n  </"
  },
  {
    "path": "lib/jazzy/themes/jony/templates/task.mustache",
    "chars": 3145,
    "preview": "<div class=\"task-group\">\n  {{#name}}\n  <div class=\"task-name-container\">\n    <a name=\"/{{uid}}\"></a>\n    <a name=\"//appl"
  },
  {
    "path": "lib/jazzy/themes/jony/templates/tasks.mustache",
    "chars": 129,
    "preview": "{{#tasks.count}}\n<section class=\"section task-group-section\">\n  {{#tasks}}\n  {{> task}}\n  {{/tasks}}\n</section>\n{{/tasks"
  },
  {
    "path": "lib/jazzy.rb",
    "chars": 127,
    "preview": "# frozen_string_literal: true\n\nrequire 'jazzy/config'\nrequire 'jazzy/doc_builder'\n\nEncoding.default_external = Encoding:"
  },
  {
    "path": "spec/Moya.podspec",
    "chars": 1924,
    "preview": "Pod::Spec.new do |s|\n  s.name         = \"Moya\"\n  s.version      = \"15.0.0\"\n  s.summary      = \"Network abstraction layer"
  },
  {
    "path": "spec/integration_spec.rb",
    "chars": 11866,
    "preview": "# frozen_string_literal: true\n\n# ------------------------------------ #\n#  Jazzy Integration tests             #\n# -----"
  },
  {
    "path": "spec/spec_helper/pre_flight.rb",
    "chars": 623,
    "preview": "# frozen_string_literal: true\n\n# Restores the config to the default state before each requirement\n\nmodule Bacon\n  class "
  },
  {
    "path": "spec/spec_helper.rb",
    "chars": 651,
    "preview": "# frozen_string_literal: true\n\nrequire 'rubygems'\nrequire 'bundler/setup'\nrequire 'bacon'\nrequire 'mocha-on-bacon'\nrequi"
  }
]

// ... and 2 more files (download for full content)

About this extraction

This page contains the full source code of the realm/jazzy GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 90 files (527.4 KB), approximately 133.8k tokens, and a symbol index with 656 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!