diff --git a/.autotest b/.autotest deleted file mode 100644 index 916207ee6e..0000000000 --- a/.autotest +++ /dev/null @@ -1,24 +0,0 @@ -require 'autotest/restart' - -Autotest.add_hook :run_command do |_, cmd| - system "#{Gem.ruby} -rubygems #{Gem.bin_path 'rake', 'rake'} generate" - cmd.sub! ' -e ', ' -we ' - cmd.sub! "'minitest'", "'minitest', '~> 4.7'" -end - -Autotest.add_hook :initialize do |at| - at.testlib = '' - at.add_exception '.git' - - def at.path_to_classname s - sep = File::SEPARATOR - f = s.sub(/^test#{sep}/, '').sub(/\.rb$/, '').split(sep) - f = f.map { |path| path.split(/_|(\d+)/).map { |seg| seg.capitalize }.join } - f = f.map { |path| path =~ /^Test/ ? path : "Test#{path}" } - f.join('::'). - gsub('Rdoc', 'RDoc'). - gsub('Ri', 'RI'). - gsub('Changelog', 'ChangeLog') - end -end - diff --git a/.document b/.document index ad81ce07da..fe7bc0def1 100644 --- a/.document +++ b/.document @@ -1,5 +1,4 @@ -History.txt -LICENSE.txt -README.txt -RI.txt +*.md +*.rdoc lib +doc diff --git a/.generated_files_rubocop.yml b/.generated_files_rubocop.yml new file mode 100644 index 0000000000..cabd0719fa --- /dev/null +++ b/.generated_files_rubocop.yml @@ -0,0 +1,12 @@ +# This rubocop configuration is ONLY for the generated files (listed in Rakefile). It is not meant to be used for RDoc's +# source code. +# The purpose of this file is to ensure the generated files don't have trailing whitespace or empty lines, which could +# be a problem for ruby/ruby's CI +AllCops: + TargetRubyVersion: 3.3 + DisabledByDefault: true + +Layout/TrailingWhitespace: + Enabled: true +Layout/TrailingEmptyLines: + Enabled: true diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..b18fd29357 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'weekly' diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000000..c13e7050c0 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,16 @@ +# release.yml + +changelog: + categories: + - title: ✨ Enhancements + labels: + - enhancement + - title: 🐛 Bug Fixes + labels: + - bug + - title: 📚 Documentation + labels: + - documentation + - title: 🛠 Other Changes + labels: + - "*" diff --git a/.github/workflows/cloudflare-preview.yml b/.github/workflows/cloudflare-preview.yml new file mode 100644 index 0000000000..bccc125764 --- /dev/null +++ b/.github/workflows/cloudflare-preview.yml @@ -0,0 +1,142 @@ +name: Cloudflare Pages Preview Deployment + +on: + # Runs automatically for PRs from ruby/rdoc + # Fork PRs will be filtered out by the if condition + pull_request: + + # Allows manual triggering for fork PRs + workflow_dispatch: + inputs: + pull_request_number: + description: 'Pull Request Number (for fork PRs)' + required: true + type: string + +jobs: + deploy-preview: + runs-on: ubuntu-latest + # Skip if PR from fork and NOT manually triggered + if: ${{ github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == 'ruby/rdoc' }} + + steps: + - name: Checkout for PR from main repo + if: ${{ github.event_name == 'pull_request' }} + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.ref }} + + # For fork PRs that are manually triggered, we need to get the PR details first + - name: Get PR details for fork + if: ${{ github.event_name == 'workflow_dispatch' }} + id: pr_details + uses: actions/github-script@v7 + with: + script: | + const prNumber = ${{ inputs.pull_request_number }}; + + // Get PR details to find the head SHA + const { data: pr } = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: prNumber + }); + + console.log(`Fork PR head SHA: ${pr.head.sha}`); + console.log(`Fork PR head ref: ${pr.head.ref}`); + console.log(`Fork PR repo: ${pr.head.repo.full_name}`); + + // Set outputs for checkout step + core.setOutput('head_sha', pr.head.sha); + core.setOutput('head_ref', pr.head.ref); + core.setOutput('repo_full_name', pr.head.repo.full_name); + + - name: Checkout for manually triggered fork PR + if: ${{ github.event_name == 'workflow_dispatch' }} + uses: actions/checkout@v4 + with: + ref: ${{ steps.pr_details.outputs.head_sha }} + repository: ${{ steps.pr_details.outputs.repo_full_name }} + + - name: Setup Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.4' + bundler-cache: true + + - name: Install dependencies + run: bundle install + + - name: Build site + run: bundle exec rake rdoc + + - name: Set PR Number + id: pr_number + run: | + if [ "${{ github.event_name }}" == "pull_request" ]; then + echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV + else + echo "PR_NUMBER=${{ inputs.pull_request_number }}" >> $GITHUB_ENV + fi + + # Deploy to Cloudflare Pages using wrangler-action + - name: Deploy to Cloudflare Pages + id: deploy + uses: cloudflare/wrangler-action@v3 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + command: pages deploy ./_site --project-name=rdoc --branch="${{ env.PR_NUMBER }}-preview" + + # Comment on PR with preview URL - works for both regular PRs and fork PRs + - name: Comment on PR with preview URL + uses: actions/github-script@v7 + with: + script: | + const prNumber = ${{ env.PR_NUMBER }}; + const url = "${{ steps.deploy.outputs.deployment-url }}"; + const commentMarker = "🚀 Preview deployment available at:"; + + // Get commit SHA based on event type + let commitSha; + if ('${{ github.event_name }}' === 'pull_request') { + commitSha = '${{ github.event.pull_request.head.sha }}'; + } else { + // For workflow_dispatch, get the SHA from the PR details + commitSha = '${{ steps.pr_details.outputs.head_sha }}'; + } + + // Get all comments on the PR + const comments = await github.rest.issues.listComments({ + issue_number: prNumber, + owner: context.repo.owner, + repo: context.repo.repo, + per_page: 100 + }); + + // Look for our previous bot comment + const existingComment = comments.data.find(comment => + comment.body.includes(commentMarker) + ); + + const commentBody = `${commentMarker} [${url}](${url}) (commit: ${commitSha})`; + + if (existingComment) { + // Update existing comment + await github.rest.issues.updateComment({ + comment_id: existingComment.id, + owner: context.repo.owner, + repo: context.repo.repo, + body: commentBody + }); + console.log("Updated existing preview comment"); + } else { + // Create new comment + await github.rest.issues.createComment({ + issue_number: prNumber, + owner: context.repo.owner, + repo: context.repo.repo, + body: commentBody + }); + console.log("Created new preview comment"); + } diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml new file mode 100644 index 0000000000..d5d467cd46 --- /dev/null +++ b/.github/workflows/gh-pages.yml @@ -0,0 +1,47 @@ +name: Deploy RDoc site to Pages + +on: + push: + branches: [ 'master' ] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + if: ${{ github.repository == 'ruby/rdoc' && !startsWith(github.event_name, 'pull') }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Ruby + uses: ruby/setup-ruby@eaecf785f6a34567a6d97f686bbb7bccc1ac1e5c # v1.237.0 + with: + ruby-version: '3.2' + bundler-cache: true + - name: Setup Pages + id: pages + uses: actions/configure-pages@v5 + - name: Build with RDoc + # Outputs to the './_site' directory by default + run: bundle exec rake rdoc + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000000..27ea686ca1 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,32 @@ +name: Lint + +on: + push: + branches: + - '**' + - '!dependabot/**' + pull_request: + +permissions: # added using https://github.com/step-security/secure-workflows + contents: read + +jobs: + lint: + strategy: + fail-fast: false + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 # v3.3.0 + # libyaml-dev is needed for psych, see https://github.com/ruby/setup-ruby/issues/409 + - if: ${{ matrix.os == 'ubuntu-latest' }} + run: sudo apt install libyaml-dev + - name: Set up Ruby + uses: ruby/setup-ruby@master + with: + ruby-version: 3.3 + bundler-cache: true + - name: Run rubocop + run: bundle exec rubocop + - name: Sanity check for the format_generated_files task + run: bundle exec rake generate format_generated_files + diff --git a/.github/workflows/pr-preview-comment.yml b/.github/workflows/pr-preview-comment.yml new file mode 100644 index 0000000000..018b57596f --- /dev/null +++ b/.github/workflows/pr-preview-comment.yml @@ -0,0 +1,72 @@ +name: Comment on Fork PRs + +on: + pull_request_target: + types: [opened, reopened, synchronize] + +# Required permissions for commenting on PRs +permissions: + contents: read + pull-requests: write + +jobs: + comment-on-fork-pr: + runs-on: ubuntu-latest + # Only run for fork PRs + if: github.event.pull_request.head.repo.fork == true + steps: + - name: Comment on PR with manual deployment instructions + uses: actions/github-script@v7 + with: + script: |- + const prNumber = context.payload.pull_request.number; + const workflowUrl = `https://github.com/ruby/rdoc/actions/workflows/cloudflare-preview.yml`; + const commentMarker = "## Cloudflare Preview Deployment"; + + // Create a direct link that pre-fills the PR number input + const dispatchUrl = `${workflowUrl}/dispatch?ref=main&inputs%5Bpull_request_number%5D=${prNumber}`; + + // Get all comments on the PR + const comments = await github.rest.issues.listComments({ + issue_number: prNumber, + owner: context.repo.owner, + repo: context.repo.repo, + per_page: 100 + }); + + // Look for our previous bot comment + const existingComment = comments.data.find(comment => + comment.body.includes(commentMarker) + ); + + const messageLines = [ + `${commentMarker}`, + `⚠️ This PR is from a fork, so the preview deployment workflow doesn't run automatically for security reasons.`, + ``, + `### For Maintainers:`, + `[🚀 Click here to run the preview deployment workflow](${dispatchUrl})`, + ``, + `This will trigger a Cloudflare Pages preview deployment for this PR.` + ]; + + const commentBody = messageLines.join('\n'); + + if (existingComment) { + // Update existing comment + await github.rest.issues.updateComment({ + comment_id: existingComment.id, + owner: context.repo.owner, + repo: context.repo.repo, + body: commentBody + }); + console.log("Updated existing fork PR comment"); + } else { + // Create new comment + await github.rest.issues.createComment({ + issue_number: prNumber, + owner: context.repo.owner, + repo: context.repo.repo, + body: commentBody + }); + console.log("Created new fork PR comment"); + } diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml new file mode 100644 index 0000000000..355589ba45 --- /dev/null +++ b/.github/workflows/push_gem.yml @@ -0,0 +1,46 @@ +name: Publish gem to rubygems.org + +on: + push: + tags: + - 'v*' + +permissions: + contents: read + +jobs: + push: + if: github.repository == 'ruby/rdoc' + runs-on: ubuntu-latest + + environment: + name: rubygems.org + url: https://rubygems.org/gems/rdoc + + permissions: + contents: write + id-token: write + + steps: + - name: Harden Runner + uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 + with: + egress-policy: audit + + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + + - name: Set up Ruby + uses: ruby/setup-ruby@eaecf785f6a34567a6d97f686bbb7bccc1ac1e5c # v1.237.0 + with: + bundler-cache: true + ruby-version: ruby + + - name: Publish to RubyGems + uses: rubygems/release-gem@a25424ba2ba8b387abc8ef40807c2c85b96cbe32 # v1.1.1 + + - name: Create GitHub release + run: | + tag_name="$(git describe --tags --abbrev=0)" + gh release create "${tag_name}" --verify-tag --generate-notes + env: + GITHUB_TOKEN: ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }} diff --git a/.github/workflows/ruby-core.yml b/.github/workflows/ruby-core.yml new file mode 100644 index 0000000000..f243aa14ca --- /dev/null +++ b/.github/workflows/ruby-core.yml @@ -0,0 +1,82 @@ +name: Document generation test with ruby/ruby + +on: + pull_request: + + push: + branches: + - master + +concurrency: + group: ci-${{ github.ref }}-${{ github.workflow }} + +permissions: # added using https://github.com/step-security/secure-workflows + contents: read + +jobs: + ruby_core: + name: Generate ruby/ruby documentation with the current RDoc commit + runs-on: ubuntu-latest + strategy: + fail-fast: false + timeout-minutes: 30 + steps: + - name: Set up latest ruby head + uses: ruby/setup-ruby@eaecf785f6a34567a6d97f686bbb7bccc1ac1e5c # v1.237.0 + with: + ruby-version: head + bundler: none + - name: Save latest buildable revision to environment + run: echo "REF=$(ruby -v | cut -d')' -f1 | cut -d' ' -f5)" >> $GITHUB_ENV + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v3.1.0 + with: + repository: ruby/ruby + path: ruby/ruby + fetch-depth: 10 + - name: Checkout the latest buildable revision + run: git switch -c ${{ env.REF }} + working-directory: ruby/ruby + - name: Install libraries + run: | + set -x + sudo apt-get update -q || : + sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev bison autoconf ruby + - name: Build Ruby + run: | + # Download the required auxiliary files for autoconf + # This is necessary because autoconf 2.71+ (included in Ubuntu latest) + # fails with "cannot find required auxiliary files" error + # These files (config.guess and config.sub) are needed for system detection + ruby tool/downloader.rb -d tool -e gnu config.guess config.sub + autoconf + ./configure -C --disable-install-doc + working-directory: ruby/ruby + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v3.1.0 + with: + path: ruby/rdoc + - name: Build RDoc locally + # The `build` task provided by `require 'bundler/gem_tasks'` seems to have a bug + # as described in https://github.com/rubygems/rubygems/issues/8477 + # The manual `gem build` and `gem install` are used to work around this issue. + run: | + bundle install + gem build rdoc.gemspec + # This gem isn't used for generating Ruby documentation. + # This is just for fixing `pkg/rdoc-X.Y.Z.gem` path. + gem install rdoc-*.gem + bundle exec rake build:local_ruby + working-directory: ruby/rdoc + - name: Generate Documentation with RDoc + run: make html + working-directory: ruby/ruby + # We need to clear the generated documentation to generate them again + # with the Prism parser. + - name: Clear Generated Documentation + run: rm -r .ext/html + working-directory: ruby/ruby + - name: Generate Documentation with RDoc (Prism parser) + run: make html + working-directory: ruby/ruby + env: + RDOC_USE_PRISM_PARSER: true + diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000000..ce0b9aedef --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,65 @@ +name: Test + +on: + push: + branches: + - '**' + - '!dependabot/**' + pull_request: + +permissions: # added using https://github.com/step-security/secure-workflows + contents: read + +jobs: + ruby-versions: + uses: ruby/actions/.github/workflows/ruby_versions.yml@master + with: + # 2.7 breaks `test_parse_statements_nodoc_identifier_alias_method` + min_version: 3.0 + versions: '["mswin"]' + + test: + needs: ruby-versions + strategy: + fail-fast: false + matrix: + ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }} + os: [ubuntu-latest, macos-latest, windows-latest] + exclude: + - os: windows-latest + ruby: truffleruby + - os: windows-latest + ruby: truffleruby-head + - os: windows-latest + ruby: jruby + - os: windows-latest + ruby: jruby-head + - os: macos-latest + ruby: mswin + - os: ubuntu-latest + ruby: mswin + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 # v3.3.0 + # libyaml-dev is needed for psych, see https://github.com/ruby/setup-ruby/issues/409 + - if: ${{ matrix.os == 'ubuntu-latest' }} + run: sudo apt install libyaml-dev + - name: Set up Ruby + uses: ruby/setup-ruby@master + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true # 'bundle install' and cache + - name: Run test + run: bundle exec rake + env: + RUBYOPT: --enable-frozen_string_literal + - name: Run test with Prism parser + run: bundle exec rake + env: + RUBYOPT: --enable-frozen_string_literal + RDOC_USE_PRISM_PARSER: true + - if: ${{ matrix.ruby == 'head' && startsWith(matrix.os, 'ubuntu') }} + run: bundle exec rake rdoc + - if: ${{ matrix.ruby == 'head' && startsWith(matrix.os, 'ubuntu') }} + run: bundle exec rake install diff --git a/.gitignore b/.gitignore index fa0558cb49..149ac7f66f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,17 @@ *.rbc *.swp +/coverage .DS_Store /.rdoc /.rvmrc +/.ruby-version /TAGS -/doc +/html +/_site /lib/rdoc/rd/block_parser.rb /lib/rdoc/rd/inline_parser.rb /lib/rdoc/markdown.rb +/lib/rdoc/markdown/literals.rb /pkg /tmp +Gemfile.lock diff --git a/.rdoc_options b/.rdoc_options new file mode 100644 index 0000000000..a0ef82abd3 --- /dev/null +++ b/.rdoc_options @@ -0,0 +1,6 @@ +op_dir: _site # for GitHub Pages and should match the config of RDoc task in Rakefile +title: rdoc Documentation +main_page: README.rdoc +warn_missing_rdoc_ref: true +autolink_excluded_words: +- RDoc diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000000..a5634a0b4b --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,33 @@ +AllCops: + TargetRubyVersion: 3.0 + DisabledByDefault: true + SuggestExtensions: false + Exclude: + # Exclude files that are auto generated + - "lib/rdoc/rd/block_parser.rb" + - "lib/rdoc/rd/inline_parser.rb" + - "lib/rdoc/markdown.rb" + - "lib/rdoc/markdown/literals.rb" + # Exclude dependency files when installing them under vendor + - "vendor/**/*" + +Layout/TrailingWhitespace: + Enabled: true + +Layout/TrailingEmptyLines: + Enabled: true + +Layout/SpaceAroundKeyword: + Enabled: true + +Layout/SpaceBeforeComma: + Enabled: true + +Layout/SpaceAfterComma: + Enabled: true + +Lint/UnreachableCode: + Enabled: true + +Style/MethodDefParentheses: + Enabled: true diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 45d7a48afc..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,24 +0,0 @@ ---- -after_script: -- rake travis:after -t -before_script: -- gem install hoe-travis --no-rdoc --no-ri -- rake travis:before -t -language: ruby -notifications: - email: - - mail@zzak.io -rvm: -- 1.8.7 -- 1.9.3 -- 2.0.0 -- 2.1.0 -- 2.2.0 -- ruby-head -- rbx-2 -script: rake travis -matrix: - allow_failures: - - rvm: 1.8.7 - - rvm: rbx-2 - - rvm: ruby-head diff --git a/CONTRIBUTING.rdoc b/CONTRIBUTING.rdoc index 0aaff642b2..d76eb6b0ad 100644 --- a/CONTRIBUTING.rdoc +++ b/CONTRIBUTING.rdoc @@ -8,7 +8,7 @@ classes for each feature. == Bugs If you think you found a bug, file a ticket on the {issues -tracker}[https://github.com/rdoc/rdoc/issues] on github. +tracker}[https://github.com/ruby/rdoc/issues] on github. If your bug involves an error RDoc produced please include a sample file that illustrates the problem or link to the repository or gem that is associated @@ -17,14 +17,16 @@ with the bug. Please include steps to reproduce the issue. Here are some examples of good issues: -* https://github.com/rdoc/rdoc/issues/55 -* https://github.com/rdoc/rdoc/issues/61 +* https://github.com/ruby/rdoc/issues/55 +* https://github.com/ruby/rdoc/issues/61 == Developer Quick Start -RDoc uses hoe for development. To get ready to work on RDoc run: +RDoc uses bundler for development. To get ready to work on RDoc run: - $ gem install hoe + $ gem install bundler + [...] + $ bundle install [...] $ rake [...] @@ -32,14 +34,13 @@ RDoc uses hoe for development. To get ready to work on RDoc run: This will install all the necessary dependencies for development with rake, generate documentation and run the tests for the first time. -If the tests don't pass on the first run check the {Travis CI page for -RDoc}[https://travis-ci.org/rdoc/rdoc] to see if there are any known failures +If the tests don't pass on the first run check the {GitHub Actions page}[https://github.com/ruby/rdoc/actions] to see if there are any known failures (there shouldn't be). You can now use `rake` and `autotest` to run the tests. Note: the `rake` command must be used first before running any tests, because -its used to generate various parsers implemented in RDoc. Also `rake clean` is +it's used to generate various parsers implemented in RDoc. Also `rake clean` is helpful to delete these generated files. == Glossary @@ -216,4 +217,3 @@ To register the parser with rdoc, add the markup type's name and class to the RDoc::Text::MARKUP_FORMAT hash like: RDoc::Text::MARKUP_FORMAT['rdoc'] = RDoc::Markup - diff --git a/ExampleMarkdown.md b/ExampleMarkdown.md index 2a883c5c84..fd4359f355 100644 --- a/ExampleMarkdown.md +++ b/ExampleMarkdown.md @@ -1,3 +1,5 @@ +# Example Markdown + This document contains example output to show RDoc styling. This file was created from a Markdown file. diff --git a/ExampleRDoc.rdoc b/ExampleRDoc.rdoc index 79c2432ae2..b5dd68c19c 100644 --- a/ExampleRDoc.rdoc +++ b/ExampleRDoc.rdoc @@ -1,3 +1,5 @@ += Example \RDoc + This document contains example output to show RDoc styling. This file was created from a RDoc Markup file. diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000000..0cfa9f88c0 --- /dev/null +++ b/Gemfile @@ -0,0 +1,13 @@ +source 'https://rubygems.org' + +gemspec + +gem 'rake' +gem 'racc', '> 1.4.10' +gem 'kpeg', '>= 1.3.3' +gem 'test-unit' +gem 'test-unit-ruby-core' +gem 'rubocop', '>= 1.31.0' +gem 'gettext' +gem 'prism', '>= 0.30.0' +gem 'webrick' diff --git a/History.rdoc b/History.rdoc index cb5104ef33..deb8c77787 100644 --- a/History.rdoc +++ b/History.rdoc @@ -1,16 +1,45 @@ -=== 4.3.0 / 2016-11-04 += History + +== 5.1.0 / 2017-02-24 + +* Bug fixes + * Fix an issue that rdoc fails when running on Windows with RUBYOPT=-U. + PR #430 by Toshihiko Ichida + +* Minor enhancements + * Parse ruby 2.1 def. PR #436 by Akira Matsuda. + * Suppress warnings in eval. PR #440 by Nobuyoshi Nakada. + +== 5.0.0 / 2016-11-05 + +* Major enhancements + * Cleanup deprecated code targeted Ruby 1.8 + +* Bug fixes + * Ensure badge data is included in result of JsonIndex template. + * Ensure items in the nil section are displayed in HTML output. Issue #399 + by Daniel Svensson. + * Parse rb_intern_const correctly in C. PR #381 by Sho Hashimoto. + * Fix broken assets caused by #335 when serving ri. PR #360 by Alex Wood. + * Don't try to parse svg files. Issue #350 by Sigurd Svela. + +* Minor enhancements + * Improve class name expansion/resolution in ri. PR #400 by NARUSE, Yui + * Improve performance of document generation. PR #397 by Yusuke Endoh. + +== 4.3.0 / 2016-11-04 * Minor enhancements * Removed json dependency for Ruby 2.4.0 * End to support Ruby 1.8.x -=== 4.2.2 / 2016-02-09 +== 4.2.2 / 2016-02-09 * Bug fixes * Include lib/rdoc/generator/pot/* in built gem -=== 4.2.1 / 2015-12-22 +== 4.2.1 / 2015-12-22 * Bug fixes * Fixed infinite loop with CR #339 by @nobu @@ -20,7 +49,7 @@ * Fix for valid syntax `class C end` parsing #368 by @nobu -=== 4.2.0 / 2014-12-06 +== 4.2.0 / 2014-12-06 * Major enhancements * RDoc can now produce translation files for use with gettext. See @@ -50,7 +79,7 @@ * Bug fixes * Fixed HTML labels for cross-browser compatibility. This breaks existing links but enables cross-browser compatibility. Pull request #330 by Jens - Wille. + Will. * RDoc handles ASCII-incompatible encodings now. An encoding hint may need to be added to the file for RDoc to produce correct output, though. Issue #288 by Manuel Meurer. @@ -89,12 +118,12 @@ #312 by Scott Thompson. * Fixed RegExp matching stack overflow on Ruby 1.8.7. Issue #327 by sshao. -=== 4.1.2 / 2014-09-05 +== 4.1.2 / 2014-09-05 * Bug fixes * Updated vendored jQuery to 1.6.4. Bug ruby/ruby#711 by @neuralme -=== 4.1.1 / 2014-01-09 +== 4.1.1 / 2014-01-09 * Bug fixes * Fixed reporting of undocumented method parameters when including when @@ -105,7 +134,7 @@ * Removed duplicated condition in superclass fixup. Pull request #282 by Benoit Daloze. -=== 4.1.0 / 2013-12-26 +== 4.1.0 / 2013-12-26 * Notable changes * Improved accessibility of HTML output. Accessibility review was provided @@ -195,7 +224,7 @@ * Regexp options are no longer stripped in HTML output. Bug #259 by Zachary Scott, Pull request #265 by Rein Henrichs -=== 4.0.1 / 2013-03-27 +== 4.0.1 / 2013-03-27 * Bug fixes * RDoc::Options parser should rescue from OptionParser::ParseError. @@ -225,7 +254,7 @@ * The C parser now de-duplicates call-seq if the same C function is used for multiple method names. Bug #203 by Pete Higgins -=== 4.0.0 / 2013-02-24 +== 4.0.0 / 2013-02-24 RDoc 4.0 includes several new features and several breaking changes. The changes should not affect users of `rdoc` or `ri`. @@ -353,7 +382,7 @@ Changes since RDoc 3.12.1: * RDoc now ignores methods defined on constants instead of creating a fake module. Bug #163 by Zachary Scott. * Fixed ChangeLog parsing for FFI gem. Bug #165 by Zachary Scott. - * RDoc now links \#=== methods. Bug #164 by Zachary Scott. + * RDoc now links \#== methods. Bug #164 by Zachary Scott. * Allow [] following argument names for TomDoc. Bug #167 by Ellis Berner. * Fixed the RDoc servlet for home and site directories. Bug #170 by Thomas Leitner. @@ -428,7 +457,7 @@ Changes since RDoc 4.0.0.rc.2: * Templates now use the correct encoding when generating pages. Issue #183 by Vít Ondruch -=== 4.0.0.rc.2 / 2013-02-05 +== 4.0.0.rc.2 / 2013-02-05 * Minor enhancements * Added current heading and page-top links to HTML headings. @@ -449,7 +478,7 @@ Changes since RDoc 4.0.0.rc.2: * RDoc now ignores methods defined on constants instead of creating a fake module. Bug #163 by Zachary Scott. * Fixed ChangeLog parsing for FFI gem. Bug #165 by Zachary Scott. - * RDoc now links \#=== methods. Bug #164 by Zachary Scott. + * RDoc now links \#== methods. Bug #164 by Zachary Scott. * Allow [] following argument names for TomDoc. Bug #167 by Ellis Berner. * Fixed the RDoc servlet for home and site directories. Bug #170 by Thomas Leitner. @@ -460,7 +489,7 @@ Changes since RDoc 4.0.0.rc.2: * Fixed deletion of attribute ri data when a class was loaded then saved. Issue #171 by Thomas Leitner. -=== 4.0.0.preview2.1 / 2012-12-14 +== 4.0.0.preview2.1 / 2012-12-14 * Minor enhancements * Added --page-dir option to give pretty names for a FAQ, guides, or other @@ -483,7 +512,7 @@ Changes since RDoc 4.0.0.rc.2: * Incremental ri builds of C files now work. C variable names from previous runs are now saved between runs. -=== 4.0.0.preview2 / 2012-12-01 +== 4.0.0.preview2 / 2012-12-01 * Breaking changes * The default output encoding for RDoc is now UTF-8. Previously RDoc used @@ -631,7 +660,7 @@ Changes since RDoc 4.0.0.rc.2: * Fixed class << ::Foo writing documentation to /Foo.html * Fixed class ::A referencing itself from inside its own namespace. -=== 3.12.2 / 2013-02-24 +== 3.12.2 / 2013-02-24 * Bug fixes * Fixed bug in syntax-highlighting that would corrupt regular expressions. @@ -645,7 +674,7 @@ Changes since RDoc 4.0.0.rc.2: end. When a HEREDOC is not followed by a line end RDoc is not currently smart enough to restore the source correctly. Bug #162 by Zachary Scott. -=== 3.12.1 / 2013-02-05 +== 3.12.1 / 2013-02-05 * Bug fixes * Fixed an XSS exploit in darkfish.js. This could lead to cookie disclosure @@ -653,7 +682,7 @@ Changes since RDoc 4.0.0.rc.2: details including a patch you can apply to generated RDoc documentation. * Ensured that rd parser files are generated before checking the manifest. -=== 3.12 / 2011-12-15 +== 3.12 / 2011-12-15 * Minor enhancements * Added DEVELOPERS document which contains an overview of how RDoc works and @@ -684,17 +713,17 @@ Changes since RDoc 4.0.0.rc.2: * In rdoc, backspace and ansi formatters, whitespace between label or note and the colon is now stripped. -=== 3.11 / 2011-10-17 +== 3.11 / 2011-10-17 * Bug fixes * Avoid parsing TAGS files included in gems. Issue #81 by Santiago Pastorino. -=== 3.10 / 2011-10-08 +== 3.10 / 2011-10-08 * Major enhancements * RDoc HTML output has been improved: - * The search from Володя Колесников's (Vladimir Kolesnikov) Sdoc has been + * The search from Володя Колесников's (Vladimir Kolesnikov) SDoc has been integrated. The search index generation is a reusable component through @@ -795,19 +824,19 @@ Changes since RDoc 4.0.0.rc.2: parsed. Unless your project includes nonexistent modules this avoids worst-case behavior (O(n!)) of RDoc::Include#module. -=== 3.9.5 / 2013-02-05 +== 3.9.5 / 2013-02-05 * Bug fixes * Fixed an XSS exploit in darkfish.js. This could lead to cookie disclosure to third parties. See CVE-2013-0256.rdoc for full details including a patch you can apply to generated RDoc documentation. -=== 3.9.4 / 2011-08-26 +== 3.9.4 / 2011-08-26 * Bug fixes * Applied typo and grammar fixes from Luke Gruber. Ruby bug #5203 -=== 3.9.3 / 2011-08-23 +== 3.9.3 / 2011-08-23 * Bug fixes * Add US-ASCII magic comments to work with ruby -Ku. Issue #63 by @@ -817,14 +846,14 @@ Changes since RDoc 4.0.0.rc.2: * Markup defined by RDoc::Markup#add_special inside a is no longer converted. -=== 3.9.2 / 2011-08-11 +== 3.9.2 / 2011-08-11 * Bug fix * Loosened TIDYLINK regexp to allow any content in the link section like: {foo}[rdoc-ref:SomeClass] * In HTML output headings are capped at
again -=== 3.9.1 / 2011-07-31 +== 3.9.1 / 2011-07-31 * Bug fixes * Fix RDoc::Markup parser for a header followed by a non-text token. Issue @@ -832,7 +861,7 @@ Changes since RDoc 4.0.0.rc.2: * Fix RDoc::Markup::ToHtmlCrossref#gen_url for non-rdoc-ref links. * Fix bug report URL when rdoc crashes. -=== 3.9 / 2011-07-30 +== 3.9 / 2011-07-30 * Minor enhancements * RDoc::Parser::C now supports :doc: and :nodoc: for class comments @@ -852,7 +881,7 @@ Changes since RDoc 4.0.0.rc.2: * Remove tokenizer restriction on header lengths for verbatim sections. Issue #49 by trans -=== 3.8 / 2011-06-29 +== 3.8 / 2011-06-29 * Minor enhancements * RDoc::Parser::C can now discover methods on ENV and ARGF. @@ -861,7 +890,7 @@ Changes since RDoc 4.0.0.rc.2: * Updating Object in an ri data store with new data now removes methods, includes, constants and aliases. -=== 3.7 / 2011-06-27 +== 3.7 / 2011-06-27 * Minor enhancements * New directive :category: which allows methods to be grouped into sections @@ -906,7 +935,7 @@ Changes since RDoc 4.0.0.rc.2: * ri data generation for method aliases no longer duplicates the class in #full_name -=== 3.6.1 / 2011-05-15 +== 3.6.1 / 2011-05-15 * Bug fixes * Fix infinite loop created when re-encountering BasicObject. @@ -914,7 +943,7 @@ Changes since RDoc 4.0.0.rc.2: * rb_path2class() can now be used to discover the parent class in rb_define_class_under. -=== 3.6 / 2011-05-13 +== 3.6 / 2011-05-13 * Major Enhancements * Interactive ri is now the default when no names are given. @@ -939,7 +968,7 @@ Changes since RDoc 4.0.0.rc.2: * The doc directive now forces documentation even when the method is marked private or protected. -=== 3.5.3 / 2010-02-06 +== 3.5.3 / 2010-02-06 * Bug fixes * When including a file perform a lossy force-transcoding to the output @@ -951,7 +980,7 @@ Changes since RDoc 4.0.0.rc.2: Bug #4376. * When Darkfish fails the file being generated is now reported. -=== 3.5.2 / 2010-02-04 +== 3.5.2 / 2010-02-04 * Deprecations * RDoc::Context::Section#sequence is now deprecated. Use @@ -968,14 +997,14 @@ Changes since RDoc 4.0.0.rc.2: * Fixed post-install message for Ruby 1.9.2 users. * Set required ruby version to >= 1.8.7. -=== 3.5.1 / 2010-01-30 +== 3.5.1 / 2010-01-30 * Bug fixes * Fixed some typos. Pull request #13 by R.T. Lechow. * Ensure an RDoc::Stats is created in #parse_files. Fixes documentation for railties which has no files. Reported by Aaron Patterson -=== 3.5 / 2010-01-29 +== 3.5 / 2010-01-29 * Minor enhancements * RDoc::Parser::C looks for rb_scan_args and fills in RDoc::AnyMethod#params @@ -998,7 +1027,7 @@ Changes since RDoc 4.0.0.rc.2: * Relaxed RDoc::Parser::Ruby#remove_private_comments to consume more dashes as older versions once did. Bug #7 by Claus Folke Brobak. -=== 3.4 / 2010-01-06 +== 3.4 / 2010-01-06 * Minor enhancements * RDoc::RDoc#document may now be called with an RDoc::Options instance. @@ -1006,7 +1035,7 @@ Changes since RDoc 4.0.0.rc.2: * Added skips to Encoding tests running on 1.8. * Fixed warnings -=== 3.3 / 2010-01-03 +== 3.3 / 2010-01-03 * Minor enhancements * The coverage report can now report undocumented method parameters @@ -1033,7 +1062,7 @@ Changes since RDoc 4.0.0.rc.2: parser. RubyForge bug #28370 by Erik Hollensbe. * ri no longer displays all methods in the inheritance chain. -=== 3.2 / 2010-12-29 +== 3.2 / 2010-12-29 * Minor enhancements * RDoc generator authors may now suppress updating the output dir (creating @@ -1043,7 +1072,7 @@ Changes since RDoc 4.0.0.rc.2: * RDoc's gitignore now ignores .DS_Store files. Pull Request #3 by Shane Becker. -=== 3.1 / 2010-12-28 +== 3.1 / 2010-12-28 RDoc has moved to github. Releases after 3.1 reference github unless otherwise noted. @@ -1081,12 +1110,12 @@ otherwise noted. * RDoc::Parser::Ruby now parses negative numbers correctly. RubyForge patch #28544 by Eito Katagiri. -=== 3.0.1 / 2010-12-19 +== 3.0.1 / 2010-12-19 * Bug fix * RDoc no longer has a Perl parser. -=== 3.0 / 2010-12-19 +== 3.0 / 2010-12-19 Special thanks to Thierry Lambert for massive improvements to RDoc. @@ -1181,7 +1210,7 @@ Special thanks to Thierry Lambert for massive improvements to RDoc. * Methods added to true, false and nil are now documented. * Remove warning for methods defined on globals. -=== 2.5.11 / 2010-08-20 +== 2.5.11 / 2010-08-20 * Minor Enhancements * Alias comments are now discovered by the C parser. Reported by Jeremy @@ -1189,7 +1218,7 @@ Special thanks to Thierry Lambert for massive improvements to RDoc. * Removed --all option which is unused in RDoc. Use the nodoc or stopdoc/startdoc directives to suppress documentation instead. -=== 2.5.10 / 2010-08-17 +== 2.5.10 / 2010-08-17 * Minor Enhancements * Support rb_singleton_class(). Reported by Jeremy Evans. @@ -1207,14 +1236,14 @@ Special thanks to Thierry Lambert for massive improvements to RDoc. Evans. * RDoc now understands singleton aliases. Reported by Jeremy Evans. -=== 2.5.9 / 2010-07-06 +== 2.5.9 / 2010-07-06 * Bug Fixes * Look up pager correctly. * Fixed handling of bullets in verbatim sections. Partial patch by Juha-Jarmo Heinonen. -=== 2.5.8 / 2010-04-27 +== 2.5.8 / 2010-04-27 *NOTE*: @@ -1239,7 +1268,7 @@ If you don't want to rebuild the rdoc for `gem server`, add --no-rdoc. * ri no longer complains about nonexistent pagers. * Fixed failing test -=== 2.5.7 / 2010-04-22 +== 2.5.7 / 2010-04-22 * Minor Enhancements * Unrecognized RDoc directives can now be registered by a plugin for @@ -1250,7 +1279,7 @@ If you don't want to rebuild the rdoc for `gem server`, add --no-rdoc. * rdoc -p no longer means --pipe if files are also given. * RDoc now knows about BasicObject by default. Ruby Bug #1318 by Ambrus Zsbán -=== 2.5.6 / 2010-04-22 +== 2.5.6 / 2010-04-22 * Minor Enhancements * Unrecognized RDoc directives are added as metadata to the object they get @@ -1266,7 +1295,7 @@ If you don't want to rebuild the rdoc for `gem server`, add --no-rdoc. options. * Fixed link size on Darkfish file pages -=== 2.5.5 / 2010-04-19 +== 2.5.5 / 2010-04-19 * 1 Minor Enhancement * Use #binread in RDoc::Markup::PreProcess. Patch from ruby trunk. @@ -1278,7 +1307,7 @@ If you don't want to rebuild the rdoc for `gem server`, add --no-rdoc. * Fixed handling of ignored invalid options to continue after the invalid option. -=== 2.5.4 / 2010-04-18 +== 2.5.4 / 2010-04-18 * 2 Minor Enhancements * Methods will now be cross-referenced when preceded with ::. Ruby Bug @@ -1289,7 +1318,7 @@ If you don't want to rebuild the rdoc for `gem server`, add --no-rdoc. * RDoc::Parser::Ruby now handles while begin a; b end # .... Ruby Bug #3160 by Yusuke Endoh. -=== 2.5.3 / 2010-04-10 +== 2.5.3 / 2010-04-10 * 1 Minor Enhancement * RDoc::Parser::Simple and the include directive remove coding: comment from @@ -1299,7 +1328,7 @@ If you don't want to rebuild the rdoc for `gem server`, add --no-rdoc. #3121 by Yusuke Endoh. * Compare times as Integers as created.rid doesn't store fractional times. -=== 2.5.2 / 2010-04-09 +== 2.5.2 / 2010-04-09 * 1 Minor Enhancement * Imported various changes by Nobu from ruby trunk. @@ -1307,7 +1336,7 @@ If you don't want to rebuild the rdoc for `gem server`, add --no-rdoc. * RDoc parses files without extensions as text files again. * RDoc::Parser::Ruby parses %{ strings correctly again. -=== 2.5.1 / 2010-04-06 +== 2.5.1 / 2010-04-06 * 1 Minor Enhancement * RDoc::Parser::C now supports the include directive for classes and @@ -1321,7 +1350,7 @@ If you don't want to rebuild the rdoc for `gem server`, add --no-rdoc. * RDoc::Task's rerdoc task no longer deletes the doc directory twice. * rdoc --force-update now works correctly. Patch by Nobu Nokada -=== 2.5 / 2010-03-31 +== 2.5 / 2010-03-31 * 9 Major Enhancements * Darkfish now has a "Home" button @@ -1377,13 +1406,13 @@ If you don't want to rebuild the rdoc for `gem server`, add --no-rdoc. Filed Selenium bug #27789. * Alias comments are no longer hidden. Reported by Adam Avilla. -=== 2.4.3 / 2009-04-01 +== 2.4.3 / 2009-04-01 * 2 Bug Fixes * Corrected patch for file links * Corrected display of file popup -=== 2.4.2 / 2009-03-25 +== 2.4.2 / 2009-03-25 * 2 Minor Enhancements * Added --pipe for turning RDoc on stdin into HTML @@ -1408,7 +1437,7 @@ If you don't want to rebuild the rdoc for `gem server`, add --no-rdoc. * Added back --promiscuous which didn't do anything you cared about. Why did you enable it? Nobody looked at that page! Oh, it warns, too. -=== 2.4.1 / 2009-02-26 +== 2.4.1 / 2009-02-26 * 1 Minor Enhancements * Added :attr:, :attr_reader:, :attr_writer:, :attr_accessor: directives. @@ -1419,7 +1448,7 @@ If you don't want to rebuild the rdoc for `gem server`, add --no-rdoc. * Restore --inline-source that warns * Fixed links to files in Darkfish output -=== 2.4.0 / 2009-02-24 +== 2.4.0 / 2009-02-24 * 9 Minor Enhancements * `ri -f html` is now XHTML-happy @@ -1446,7 +1475,7 @@ If you don't want to rebuild the rdoc for `gem server`, add --no-rdoc. * RDoc doesn't crash with def (blah).foo() end * RDoc doesn't crash with #define functions -=== 2.3.0 / 2009-01-28 +== 2.3.0 / 2009-01-28 * 3 Major Enhancements * Michael Granger's Darkfish generator is now the default for HTML output @@ -1481,7 +1510,7 @@ If you don't want to rebuild the rdoc for `gem server`, add --no-rdoc. * C file RDoc is no longer included in token stream * Scan all gem paths to match gem name for ri output -=== 2.2.1 / 2008-09-24 +== 2.2.1 / 2008-09-24 This version provides some minor fixes and enhancements to 2.2.0 intended to polish RDoc for Ruby 1.9.1. @@ -1513,7 +1542,7 @@ to polish RDoc for Ruby 1.9.1. * Fixed missing display of constant values in ri. * Fixed display of constants in ri's html output. -=== 2.2.0 / 2008-09-19 +== 2.2.0 / 2008-09-19 This version includes some significant enhancements to ri. See RI.txt for documentation about ri. @@ -1594,7 +1623,7 @@ documentation about ri. * Fixed the horizontal rule markup (---) so that it correctly adds a horizontal rule rather than suppressing all text that follows. -=== 2.1.0 / 2008-07-20 +== 2.1.0 / 2008-07-20 * 3 Major Enhancements: * RDoc now knows about meta-programmed methods, see RDoc::Parser::Ruby @@ -1624,7 +1653,7 @@ documentation about ri. described in the documentation * RDoc now correctly sets superclasses if they were originally unknown -=== 2.0.0 / 2008-04-10 +== 2.0.0 / 2008-04-10 * 3 Major Enhancements: * Renamespaced everything RDoc under the RDoc module. diff --git a/LEGAL.rdoc b/LEGAL.rdoc index 2ad8f4412c..dae1059161 100644 --- a/LEGAL.rdoc +++ b/LEGAL.rdoc @@ -5,7 +5,7 @@ The files in this distribution are covered by the Ruby license (see LICENSE) except the features mentioned below: Darkfish:: - Darkfish was written by Michael Granger and is included under the MIT + Darkfish was written by Michael Granger and is included under the BSD 3-Clause license. Darkfish contains images from the Silk Icons set by Mark James. See lib/rdoc/generator/darkfish.rb for license information. @@ -14,7 +14,7 @@ Darkfish:: * lib/rdoc/generator/template/darkfish/* * lib/rdoc/generator/template/darkfish/images -Sdoc:: +SDoc:: Portions of SDoc by (Володя Колесников) Vladimir Kolesnikov are included under the MIT license as RDoc::Generator::JsonIndex. See lib/rdoc/generator/json_index.rb for license information. @@ -23,7 +23,7 @@ Sdoc:: * lib/rdoc/generator/template/json_index/* * The +#search_index+ methods on RDoc::CodeObject subclasses were derived from sdoc. - * RDoc::ClassModule#document_self_or_methods comes from Sdoc. + * RDoc::ClassModule#document_self_or_methods comes from SDoc. peg-markdown:: RDoc's Markdown support is derived from peg-markdown by John MacFarlane. It diff --git a/LICENSE.rdoc b/LICENSE.rdoc index 683585ac8b..c61bb93398 100644 --- a/LICENSE.rdoc +++ b/LICENSE.rdoc @@ -1,3 +1,5 @@ += License + RDoc is copyrighted free software. You can redistribute it and/or modify it under either the terms of the GPL diff --git a/Manifest.txt b/Manifest.txt deleted file mode 100644 index 9dcceea56b..0000000000 --- a/Manifest.txt +++ /dev/null @@ -1,309 +0,0 @@ -.autotest -.document -CONTRIBUTING.rdoc -CVE-2013-0256.rdoc -ExampleMarkdown.md -ExampleRDoc.rdoc -History.rdoc -LEGAL.rdoc -LICENSE.rdoc -Manifest.txt -README.rdoc -RI.rdoc -Rakefile -TODO.rdoc -bin/rdoc -bin/ri -lib/gauntlet_rdoc.rb -lib/rdoc.rb -lib/rdoc/alias.rb -lib/rdoc/anon_class.rb -lib/rdoc/any_method.rb -lib/rdoc/attr.rb -lib/rdoc/class_module.rb -lib/rdoc/code_object.rb -lib/rdoc/code_objects.rb -lib/rdoc/comment.rb -lib/rdoc/constant.rb -lib/rdoc/context.rb -lib/rdoc/context/section.rb -lib/rdoc/cross_reference.rb -lib/rdoc/encoding.rb -lib/rdoc/erb_partial.rb -lib/rdoc/erbio.rb -lib/rdoc/extend.rb -lib/rdoc/generator.rb -lib/rdoc/generator/darkfish.rb -lib/rdoc/generator/json_index.rb -lib/rdoc/generator/markup.rb -lib/rdoc/generator/ri.rb -lib/rdoc/generator/pot.rb -lib/rdoc/generator/pot/message_extractor.rb -lib/rdoc/generator/pot/po.rb -lib/rdoc/generator/pot/po_entry.rb -lib/rdoc/generator/template/darkfish/.document -lib/rdoc/generator/template/darkfish/_footer.rhtml -lib/rdoc/generator/template/darkfish/_head.rhtml -lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml -lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml -lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml -lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml -lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml -lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml -lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml -lib/rdoc/generator/template/darkfish/_sidebar_navigation.rhtml -lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml -lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml -lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml -lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml -lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml -lib/rdoc/generator/template/darkfish/class.rhtml -lib/rdoc/generator/template/darkfish/css/fonts.css -lib/rdoc/generator/template/darkfish/fonts/Lato-Light.ttf -lib/rdoc/generator/template/darkfish/fonts/Lato-LightItalic.ttf -lib/rdoc/generator/template/darkfish/fonts/Lato-Regular.ttf -lib/rdoc/generator/template/darkfish/fonts/Lato-RegularItalic.ttf -lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttf -lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttf -lib/rdoc/generator/template/darkfish/images/add.png -lib/rdoc/generator/template/darkfish/images/arrow_up.png -lib/rdoc/generator/template/darkfish/images/brick.png -lib/rdoc/generator/template/darkfish/images/brick_link.png -lib/rdoc/generator/template/darkfish/images/bug.png -lib/rdoc/generator/template/darkfish/images/bullet_black.png -lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.png -lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.png -lib/rdoc/generator/template/darkfish/images/date.png -lib/rdoc/generator/template/darkfish/images/delete.png -lib/rdoc/generator/template/darkfish/images/find.png -lib/rdoc/generator/template/darkfish/images/loadingAnimation.gif -lib/rdoc/generator/template/darkfish/images/macFFBgHack.png -lib/rdoc/generator/template/darkfish/images/package.png -lib/rdoc/generator/template/darkfish/images/page_green.png -lib/rdoc/generator/template/darkfish/images/page_white_text.png -lib/rdoc/generator/template/darkfish/images/page_white_width.png -lib/rdoc/generator/template/darkfish/images/plugin.png -lib/rdoc/generator/template/darkfish/images/ruby.png -lib/rdoc/generator/template/darkfish/images/tag_blue.png -lib/rdoc/generator/template/darkfish/images/tag_green.png -lib/rdoc/generator/template/darkfish/images/transparent.png -lib/rdoc/generator/template/darkfish/images/wrench.png -lib/rdoc/generator/template/darkfish/images/wrench_orange.png -lib/rdoc/generator/template/darkfish/images/zoom.png -lib/rdoc/generator/template/darkfish/index.rhtml -lib/rdoc/generator/template/darkfish/js/darkfish.js -lib/rdoc/generator/template/darkfish/js/jquery.js -lib/rdoc/generator/template/darkfish/js/search.js -lib/rdoc/generator/template/darkfish/page.rhtml -lib/rdoc/generator/template/darkfish/css/rdoc.css -lib/rdoc/generator/template/darkfish/servlet_not_found.rhtml -lib/rdoc/generator/template/darkfish/servlet_root.rhtml -lib/rdoc/generator/template/darkfish/table_of_contents.rhtml -lib/rdoc/generator/template/json_index/.document -lib/rdoc/generator/template/json_index/js/navigation.js -lib/rdoc/generator/template/json_index/js/searcher.js -lib/rdoc/ghost_method.rb -lib/rdoc/i18n.rb -lib/rdoc/i18n/locale.rb -lib/rdoc/i18n/text.rb -lib/rdoc/include.rb -lib/rdoc/known_classes.rb -lib/rdoc/markdown.kpeg -lib/rdoc/markdown.rb -lib/rdoc/markdown/entities.rb -lib/rdoc/markdown/literals_1_8.kpeg -lib/rdoc/markdown/literals_1_8.rb -lib/rdoc/markdown/literals_1_9.kpeg -lib/rdoc/markdown/literals_1_9.rb -lib/rdoc/markup.rb -lib/rdoc/markup/attr_changer.rb -lib/rdoc/markup/attr_span.rb -lib/rdoc/markup/attribute_manager.rb -lib/rdoc/markup/attributes.rb -lib/rdoc/markup/blank_line.rb -lib/rdoc/markup/block_quote.rb -lib/rdoc/markup/document.rb -lib/rdoc/markup/formatter.rb -lib/rdoc/markup/formatter_test_case.rb -lib/rdoc/markup/hard_break.rb -lib/rdoc/markup/heading.rb -lib/rdoc/markup/include.rb -lib/rdoc/markup/indented_paragraph.rb -lib/rdoc/markup/inline.rb -lib/rdoc/markup/list.rb -lib/rdoc/markup/list_item.rb -lib/rdoc/markup/paragraph.rb -lib/rdoc/markup/parser.rb -lib/rdoc/markup/pre_process.rb -lib/rdoc/markup/raw.rb -lib/rdoc/markup/rule.rb -lib/rdoc/markup/special.rb -lib/rdoc/markup/text_formatter_test_case.rb -lib/rdoc/markup/to_ansi.rb -lib/rdoc/markup/to_bs.rb -lib/rdoc/markup/to_html.rb -lib/rdoc/markup/to_html_crossref.rb -lib/rdoc/markup/to_html_snippet.rb -lib/rdoc/markup/to_joined_paragraph.rb -lib/rdoc/markup/to_label.rb -lib/rdoc/markup/to_markdown.rb -lib/rdoc/markup/to_rdoc.rb -lib/rdoc/markup/to_table_of_contents.rb -lib/rdoc/markup/to_test.rb -lib/rdoc/markup/to_tt_only.rb -lib/rdoc/markup/verbatim.rb -lib/rdoc/meta_method.rb -lib/rdoc/method_attr.rb -lib/rdoc/mixin.rb -lib/rdoc/normal_class.rb -lib/rdoc/normal_module.rb -lib/rdoc/options.rb -lib/rdoc/parser.rb -lib/rdoc/parser/c.rb -lib/rdoc/parser/changelog.rb -lib/rdoc/parser/markdown.rb -lib/rdoc/parser/rd.rb -lib/rdoc/parser/ruby.rb -lib/rdoc/parser/ruby_tools.rb -lib/rdoc/parser/simple.rb -lib/rdoc/parser/text.rb -lib/rdoc/rd.rb -lib/rdoc/rd/block_parser.rb -lib/rdoc/rd/block_parser.ry -lib/rdoc/rd/inline.rb -lib/rdoc/rd/inline_parser.rb -lib/rdoc/rd/inline_parser.ry -lib/rdoc/rdoc.rb -lib/rdoc/require.rb -lib/rdoc/ri.rb -lib/rdoc/ri/driver.rb -lib/rdoc/ri/formatter.rb -lib/rdoc/ri/paths.rb -lib/rdoc/ri/store.rb -lib/rdoc/ruby_lex.rb -lib/rdoc/ruby_token.rb -lib/rdoc/rubygems_hook.rb -lib/rdoc/servlet.rb -lib/rdoc/single_class.rb -lib/rdoc/stats.rb -lib/rdoc/stats/normal.rb -lib/rdoc/stats/quiet.rb -lib/rdoc/stats/verbose.rb -lib/rdoc/store.rb -lib/rdoc/task.rb -lib/rdoc/test_case.rb -lib/rdoc/text.rb -lib/rdoc/token_stream.rb -lib/rdoc/tom_doc.rb -lib/rdoc/top_level.rb -test/MarkdownTest_1.0.3/Amps and angle encoding.text -test/MarkdownTest_1.0.3/Auto links.text -test/MarkdownTest_1.0.3/Backslash escapes.text -test/MarkdownTest_1.0.3/Blockquotes with code blocks.text -test/MarkdownTest_1.0.3/Code Blocks.text -test/MarkdownTest_1.0.3/Code Spans.text -test/MarkdownTest_1.0.3/Hard-wrapped paragraphs with list-like lines.text -test/MarkdownTest_1.0.3/Horizontal rules.text -test/MarkdownTest_1.0.3/Inline HTML (Advanced).text -test/MarkdownTest_1.0.3/Inline HTML (Simple).text -test/MarkdownTest_1.0.3/Inline HTML comments.text -test/MarkdownTest_1.0.3/Links, inline style.text -test/MarkdownTest_1.0.3/Links, reference style.text -test/MarkdownTest_1.0.3/Links, shortcut references.text -test/MarkdownTest_1.0.3/Literal quotes in titles.text -test/MarkdownTest_1.0.3/Markdown Documentation - Basics.text -test/MarkdownTest_1.0.3/Markdown Documentation - Syntax.text -test/MarkdownTest_1.0.3/Nested blockquotes.text -test/MarkdownTest_1.0.3/Ordered and unordered lists.text -test/MarkdownTest_1.0.3/Strong and em together.text -test/MarkdownTest_1.0.3/Tabs.text -test/MarkdownTest_1.0.3/Tidyness.text -test/README -test/binary.dat -test/hidden.zip.txt -test/test.ja.largedoc -test/test.ja.rdoc -test/test.ja.txt -test/test.txt -test/test_rdoc_alias.rb -test/test_rdoc_any_method.rb -test/test_rdoc_attr.rb -test/test_rdoc_class_module.rb -test/test_rdoc_code_object.rb -test/test_rdoc_comment.rb -test/test_rdoc_constant.rb -test/test_rdoc_context.rb -test/test_rdoc_context_section.rb -test/test_rdoc_cross_reference.rb -test/test_rdoc_encoding.rb -test/test_rdoc_extend.rb -test/test_rdoc_generator_darkfish.rb -test/test_rdoc_generator_json_index.rb -test/test_rdoc_generator_markup.rb -test/test_rdoc_generator_ri.rb -test/test_rdoc_generator_pot.rb -test/test_rdoc_generator_pot_po.rb -test/test_rdoc_generator_pot_po_entry.rb -test/test_rdoc_i18n_locale.rb -test/test_rdoc_i18n_text.rb -test/test_rdoc_include.rb -test/test_rdoc_markdown.rb -test/test_rdoc_markdown_test.rb -test/test_rdoc_markup.rb -test/test_rdoc_markup_attribute_manager.rb -test/test_rdoc_markup_attributes.rb -test/test_rdoc_markup_document.rb -test/test_rdoc_markup_formatter.rb -test/test_rdoc_markup_hard_break.rb -test/test_rdoc_markup_heading.rb -test/test_rdoc_markup_include.rb -test/test_rdoc_markup_indented_paragraph.rb -test/test_rdoc_markup_paragraph.rb -test/test_rdoc_markup_parser.rb -test/test_rdoc_markup_pre_process.rb -test/test_rdoc_markup_raw.rb -test/test_rdoc_markup_to_ansi.rb -test/test_rdoc_markup_to_bs.rb -test/test_rdoc_markup_to_html.rb -test/test_rdoc_markup_to_html_crossref.rb -test/test_rdoc_markup_to_html_snippet.rb -test/test_rdoc_markup_to_joined_paragraph.rb -test/test_rdoc_markup_to_label.rb -test/test_rdoc_markup_to_markdown.rb -test/test_rdoc_markup_to_rdoc.rb -test/test_rdoc_markup_to_table_of_contents.rb -test/test_rdoc_markup_to_tt_only.rb -test/test_rdoc_markup_verbatim.rb -test/test_rdoc_method_attr.rb -test/test_rdoc_normal_class.rb -test/test_rdoc_normal_module.rb -test/test_rdoc_options.rb -test/test_rdoc_parser.rb -test/test_rdoc_parser_c.rb -test/test_rdoc_parser_changelog.rb -test/test_rdoc_parser_markdown.rb -test/test_rdoc_parser_rd.rb -test/test_rdoc_parser_ruby.rb -test/test_rdoc_parser_simple.rb -test/test_rdoc_rd.rb -test/test_rdoc_rd_block_parser.rb -test/test_rdoc_rd_inline.rb -test/test_rdoc_rd_inline_parser.rb -test/test_rdoc_rdoc.rb -test/test_rdoc_require.rb -test/test_rdoc_ri_driver.rb -test/test_rdoc_ri_paths.rb -test/test_rdoc_ruby_lex.rb -test/test_rdoc_ruby_token.rb -test/test_rdoc_rubygems_hook.rb -test/test_rdoc_servlet.rb -test/test_rdoc_single_class.rb -test/test_rdoc_stats.rb -test/test_rdoc_store.rb -test/test_rdoc_task.rb -test/test_rdoc_text.rb -test/test_rdoc_token_stream.rb -test/test_rdoc_tom_doc.rb -test/test_rdoc_top_level.rb -test/xref_data.rb -test/xref_test_case.rb diff --git a/README.rdoc b/README.rdoc index a0f0c70fc0..c4b60b29c0 100644 --- a/README.rdoc +++ b/README.rdoc @@ -1,9 +1,9 @@ = \RDoc - Ruby Documentation System -home :: https://github.com/rdoc/rdoc -rdoc :: http://docs.seattlerb.org/rdoc -bugs :: https://github.com/rdoc/rdoc/issues -code quality :: {code climate}[https://codeclimate.com/github/rdoc/rdoc] +home :: https://github.com/ruby/rdoc +rdoc :: https://ruby.github.io/rdoc +bugs :: https://github.com/ruby/rdoc/issues +code quality :: https://codeclimate.com/github/ruby/rdoc == Description @@ -46,7 +46,7 @@ contain just Markup-style markup (with or without leading '#' comment markers). If directory names are passed to RDoc, they are scanned recursively for C and Ruby source files only. -To generate documentation using +rake+ see RDoc::Task[http://docs.seattlerb.org/rdoc/RDocTask.html]. +To generate documentation using +rake+ see RDoc::Task[https://ruby.github.io/rdoc/RDoc/Task.html]. To generate documentation programmatically: @@ -54,12 +54,18 @@ To generate documentation programmatically: require 'rdoc/rdoc' options = RDoc::Options.new + options.files = ['a.rb', 'b.rb'] + options.setup_generator 'darkfish' # see RDoc::Options rdoc = RDoc::RDoc.new rdoc.document options # see RDoc::RDoc +You can specify the target files for document generation with +.document+ file in the project root directory. ++.document+ file contains a list of file and directory names including comment lines starting with '#'. +See https://github.com/ruby/rdoc/blob/master/.document as an example. + == Writing Documentation To write documentation for RDoc place a comment above the class, module, @@ -106,9 +112,18 @@ To determine how well your project is documented run rdoc -C lib to get a documentation coverage report. rdoc -C1 lib includes parameter names in the documentation coverage report. +== Theme Options + +There are a few community-maintained themes for \RDoc: + +- rorvswild-theme-rdoc[https://github.com/BaseSecrete/rorvswild-theme-rdoc] +- hanna[https://github.com/jeremyevans/hanna] (a fork maintained by {Jeremy Evans}[https://github.com/jeremyevans]) + +Please follow the theme's README for usage instructions. + == Bugs -See CONTRIBUTING@Bugs for information on filing a bug report. It's OK to file +See CONTRIBUTING.rdoc for information on filing a bug report. It's OK to file a bug report for anything you're having a problem with. If you can't figure out how to make RDoc produce the output you like that is probably a documentation bug. diff --git a/RI.md b/RI.md new file mode 100644 index 0000000000..45addacdbc --- /dev/null +++ b/RI.md @@ -0,0 +1,842 @@ +# `ri`: Ruby Information + +`ri` (ruby information) is the Ruby command-line utility +that gives fast and easy on-line access to Ruby documentation. + +`ri` can show documentation for Ruby itself and for its installed gems: + +- A **class** or **module**: + text associated with the class or module definition + in a source file (`.rb` or `.c`). +- One or more **methods**: + text associated with method definitions + in source files (`.rb` and `.c`). +- A **page**: + text from a stand-alone documentation file + (`.rdoc` or `.md`, or sometimes other). + +Examples (output omitted): + +```sh +$ ri Hash # Document for class Hash. +$ ri Array#sort # Document for instance method sort in class Array. +$ ri read # Documents for methods ::read and #read in all classes and modules. +$ ri ruby:dig_methods # Document for page dig_methods. +``` + +`ri` can also show lists of: + +- **classes** and **modules**: + full or partial list. +- **pages**: + for Ruby or for an installed gem. + +Examples (output omitted): + +```sh +$ ri --list # List of classes and modules. +$ ri ruby: # List of Ruby pages. +``` + +## Why `ri`? + +Using `ri` may have advantages over using +the [Ruby online documentation](https://docs.ruby-lang.org/en/master): + +- The `ri` documentation is always available, even when you do not have internet access + (think: airplane mode). +- If you are working in a terminal window, typing `ri _whatever_` (or just `ri`) + may be faster than navigating to a browser window and searching for documentation. +- If you are working in an + [irb \(interactive Ruby\)](https://docs.ruby-lang.org/en/master/IRB.html) + session, you _already_ have immediate access to `ri`: + just type `'show_doc'`. + +## Modes + +There are two `ri` modes: + +- Static mode: + In general, `ri` responds in its static mode + if a _name_ is given; + it shows results and exits (as in the examples above). + See [Static Mode][1]. +- Interactive mode: + In general, `ri` enters its interactive mode + if no _name_ is given; + in interactive mode, `ri` shows results and waits for another command: + + ```sh + $ ri + Enter the method name you want to look up. + You can use tab to autocomplete. + Enter a blank line to exit. + >> + ``` + + See [Interactive Mode][2]. + +## Names + +In both modes, static and interactive, +`ri` responds to an input _name_ that specifies what is to be displayed: +a document, multiple documents, or other information: + +- Static mode (in the shell): type `'ri _name_'`; + examples (output omitted): + + ```sh + $ ri File + $ ri IO#readlines + $ ri ruby: + ``` + +- Interactive mode (already in `ri`): just type the _name_; + examples (output omitted): + + ```sh + $ ri + Enter the method name you want to look up. + You can use tab to autocomplete. + Enter a blank line to exit. + >> File + >> IO#readlines + >> ruby: + ``` + +### Names for Class and Module Documents + +These example `ri` commands cite names for class and module documents +(see [details and examples][3]): + +| Command | Shows | +|------------------------------|------------------------------------------------------------| +| ri File | Document for Ruby class File. | +| ri File::Stat | Document for Ruby nested class File::Stat. | +| ri Enumerable | Document for Ruby module Enumerable. | +| ri Arr | Document for Ruby class Array (unique initial characters). | +| ri Nokogiri::HTML4::Document | Document for gem class Nokogiri::HTML4::Document. | +| ri Nokogiri | Document for gem module Nokogiri. | +
+ +If [option \\--all][4] +is in effect, documents for the methods in the named class or module +are included in the display. + +### Names for Method Documents + +These example `ri` commands cite names for method documents +(see [details and examples][5]): + +| Command | Shows | +|--------------------------------------|----------------------------------------------------------------------------------| +| ri IO::readlines | Document for Ruby class method IO::readlines. | +| ri IO#readlines | Document for Ruby instance method IO::readlines. | +| ri IO.readlines | Documents for Ruby instance method IO::readlines and class method IO::readlines. | +| ri ::readlines | Documents for all class methods ::readlines. | +| ri #readlines | Documents for all instance methods #readlines. | +| ri .readlines, ri readlines | Documents for class methods ::readlines and instance methods #readlines. | +| ri Nokogiri::HTML4::Document::parse | Document for gem class method Nokogiri::HTML4::Document::parse. | +| ri Nokogiri::HTML4::Document#fragment | Document for gem instance method Nokogiri::HTML4::Document#fragment. | +
+ +### Names for Page Documents + +These example `ri` commands cite names for page documents +(see [details and examples][6]): + +| Command | Shows | +|--------------------------------|--------------------------------------------------| +| ri ruby:syntax/assignment.rdoc | Document for Ruby page assignment. | +| ri ruby:syntax/assignment | Same document, if no other syntax/assignment.*. | +| ri ruby:assignment | Same document, if no other */assignment.*. | +| ri nokogiri:README.md | Document for page README.md. | +
+ +### Names for Lists + +These example `ri` commands cite names for lists +(see [details and examples][7]): + +| Command | Shows | +|---------------|-------------------------| +| ri ruby: | List of Ruby pages. | +| ri nokogiri: | List of Nokogiri pages. | +
+ +There are more lists available; +see [option \\--list][8]. + +## Pro Tips + +### `ri` at the Ready + +If you are a frequent `ri` user, +you can save time by keeping open a dedicated command window +with either of: + +- A running [interactive ri][2] session. +- A running [irb session][9]; + type `'show_doc'` to enter `ri`, newline to exit. + +When you switch to that window, `ri` is ready to respond quickly, +without the performance overhead of re-reading `ri` sources. + +### Output Filters + +The `pager` value actually need not be simply the path to an executable; +it's actually a full-fledged command line, +and so may include not only the executable path, +but also whatever options and arguments that executable accepts. + +You can, for example, set the pager value to `'grep . | less'`, +which will exclude blank lines (thus saving screen space) +before piping the result to `less`; +example (output omitted): + +```sh +$ RI_PAGER="grep . | less" ri Array +``` + +See the documentation for your chosen pager programs +(e.g, type `'grep --help'`, `'less --help'`). + +### Links in `ri` Output + +#### Implicit Link + +When you see: + +- `'IO::readlines'`, `'IO#readlines'`, `'IO.readlines'`: + use that same text as the _name_ in an `ri` command. + + Examples (output omitted): + + ```sh + $ ri IO::readlines + $ ri IO#readlines + $ ri IO.readlines + ``` + +- `'#read'`, `'::read'`, `'.read'`: + you're likely already in the `ri` document for a class or module, + or for a method in a class or module; + use that same text with the name of the class or module (such as `'File'`) + as the _name_ in an `ri` command. + + Examples (output omitted): + + ```sh + $ ri File::read + $ ri File#read + $ ri File.read + ``` + +#### Explicit Link + +When you see: + +- `'{Dig Methods}[rdoc-ref:doc/dig_methods.rdoc]'`: + use the trailing part of the `'[rdoc-ref:doc/'` in an `ri` command + for a Ruby document. + + Example (output omitted): + + ```sh + $ ri ruby:dig_methods.rdoc + ``` + +- `'{Table (information)}[https://en.wikipedia.org/wiki/Table_(information)]'`: + go to the given URL in your browser. + +## About the Examples + +- `ri` output can be large; + to save space, an example may pipe it to one of these: + + - [head](https://www.man7.org/linux/man-pages/man1/head.1.html): leading lines only. + - [tail](https://www.man7.org/linux/man-pages/man1/tail.1.html): trailing lines only. + - [wc -l](https://www.man7.org/linux/man-pages/man1/wc.1.html): line count only. + - [grep](https://www.man7.org/linux/man-pages/man1/grep.1.html): selected lines only. + +- An example that involves a gem assumes that gems `nokogiri` and `minitest` are installed. + +## `ri` Documents + +This section outlines what you can expect to find +in the `ri` document for a class, module, method, or page. + +See also: + +- [Pager][10]. +- [Links in ri Output][11]. + +### Class and Module Documents + +The document for a class or module shows: + +- The class or module name, along with its parent class if any. +- Where it's defined (Ruby core or gem). +- When each exists: + + - The names of its included modules. + - The text of its embedded documentation. + - Its constants. + - Its class methods. + - Its instance methods. + +Examples: + +- Ruby class `Array`: + + ```sh + $ ri Array | head + = Array < Object + + ------------------------------------------------------------------------ + = Includes: + Enumerable (from ruby core) + + (from ruby core) + ------------------------------------------------------------------------ + An Array is an ordered, integer-indexed collection of objects, called + elements. Any object may be an Array element. + ``` + +- Gem module `Nokogiri`: + + ```sh + $ ri Nokogiri | head + = Nokogiri + + (from gem nokogiri-1.16.2-x86_64-linux) + ------------------------------------------------------------------------ + + Nokogiri parses and searches XML/HTML very quickly, and also has + correctly implemented CSS3 selector support as well as XPath 1.0 + support. + + Parsing a document returns either a Nokogiri::XML::Document, or a + ``` + +The document typically includes certain headings, +which may be useful for searching: + +```sh +$ ri IO | grep "^= " += IO < Object += Includes: += Constants: += Class methods: += Instance methods: +``` + +### Method Documents + +The document for a method includes: + +- The source of the method: `'(from ruby core)'` or `'(from gem _gem_)'`. +- The calling sequence(s) for the method. +- The text of its embedded documentation (if it exists). + +Examples: + +```sh +$ ri IO#read | head += IO#read + +(from ruby core) +------------------------------------------------------------------------ +ios.read([length [, outbuf]]) -> string, outbuf, or nil + +------------------------------------------------------------------------ + +Reads length bytes from the I/O stream. +``` + +```sh +$ ri Nokogiri::parse | head += Nokogiri::parse + +(from gem nokogiri-1.16.2-x86_64-linux) +------------------------------------------------------------------------ + parse(string, url = nil, encoding = nil, options = nil) { |doc| ... } + +------------------------------------------------------------------------ + +Parse an HTML or XML document. string contains the document. +``` + +The output for a _name_ that cites methods includes the document +for each found implementation; +the number of such implementations depends on the _name_: + +- Within a class: + + Each of these commands shows documents + for methods in Ruby class `IO` (output omitted): + + ```sh + $ ri IO::readlines # Class method ::readlines. + $ ri IO#readlines # Instance method #readlines. + $ ri IO.readlines # Both of above. + ``` + +- In all classes: + + Each of these commands shows documents + for methods in all classes (output omitted): + + ```sh + $ ri ::readlines # Class method ::readlines. + $ ri \#readlines # Instance method #readlines. + $ ri .readlines # Both of above. + ``` + + For these all-classes commands, + the output is organized into sections, + one for each found method (output filtered to show sections): + + ```sh + $ ri ::readlines | grep "= Implementation" + === Implementation from CSV + === Implementation from IO + ``` + + ```sh + $ ri \#readlines | grep "= Implementation" + === Implementation from ARGF + === Implementation from CSV + === Implementation from IO + === Implementation from Kernel + === Implementation from Buffering + === Implementation from Pathname + === Implementation from StringIO + === Implementation from GzipReader + ``` + + ```sh + $ ri .readlines | grep "= Implementation" + === Implementation from ARGF + === Implementation from CSV + === Implementation from CSV + === Implementation from IO + === Implementation from IO + === Implementation from Kernel + === Implementation from Buffering + === Implementation from Pathname + === Implementation from StringIO + === Implementation from GzipReader + ``` + +### Page Documents + +The document for a Ruby page is the text from the `.rdoc` or `.md` source +for that page: + +```sh +$ ri ruby:dig_methods | head += Dig Methods + +Ruby's dig methods are useful for accessing nested data structures. + +Consider this data: + item = { + id: "0001", + type: "donut", + name: "Cake", + ppu: 0.55, +``` + +The document for a gem page is whatever the gem has generated +for the page: + +```sh +$ ri minitest:README | head += minitest/{test,spec,mock,benchmark} + +home: + https://github.com/minitest/minitest + +bugs: + https://github.com/minitest/minitest/issues + +rdoc: + https://docs.seattlerb.org/minitest +``` + +## `ri` Lists + +The list of Ruby pages is available via _name_ `'ruby:'`: + +```sh +$ ri ruby: | head += Pages in ruby core + +CONTRIBUTING.md +COPYING +COPYING.ja +LEGAL +NEWS-1.8.7 +NEWS-1.9.1 +NEWS-1.9.2 +NEWS-1.9.3 +``` + +```sh +$ ri ruby: | tail +syntax/control_expressions.rdoc +syntax/exceptions.rdoc +syntax/literals.rdoc +syntax/methods.rdoc +syntax/miscellaneous.rdoc +syntax/modules_and_classes.rdoc +syntax/pattern_matching.rdoc +syntax/precedence.rdoc +syntax/refinements.rdoc +win32/README.win32 +``` + +The list of gem pages is available via _name_ `'_gem_name_'`: + +```sh +$ ri nokogiri: | head += Pages in gem nokogiri-1.16.2-x86_64-linux + +README.md +lib/nokogiri/css/tokenizer.rex +``` + +See also: + +- [Option \\--list][8]: + lists classes and modules. +- [Option \\--list-doc-dirs][12]: + lists `ri` source directories. + +## `ri` Information + +With certain options, +an `ri` command may display information other than documents or lists: + +- [Option \\--help or -h][13]: + Shows `ri` help text. +- [option \\--version or -v][14]: + Shows `ri` version. +- [Option \\--dump=FILEPATH][15]: + Shows dump of `ri` cache file at the given filepath. + +## Static Mode + +In static mode, `ri` shows a response and exits. + +In general, `ri` responds in static mode +if the command gives a _name_: + +```sh +$ ri Array | head += Array < Object + +------------------------------------------------------------------------ += Includes: +Enumerable (from ruby core) + +(from ruby core) +------------------------------------------------------------------------ +An Array is an ordered, integer-indexed collection of objects, called +elements. Any object may be an Array element. +``` + +`ri` also responds in static mode when certain options are given, +even when no _name_ is given; +see [ri Information][16]. + +## Interactive Mode + +In general, `ri` responds to a command in interactive mode +if the command has no arguments: + +```sh +$ ri +Enter the method name you want to look up. +You can use tab to autocomplete. +Enter a blank line to exit. +>> + +``` + +A command in interactive mode are similar to one in static mode, +except that it: + +- Omits command word `ri`; you just type the _name_. +- Omits options; in interactive mode the only options in effect + are those taken from environment variable `RI`. + See [Options][17]. +- Supports tab auto-completion for the name of a class, module, or method; + when, for example, you type `"Arr\t"` (here `"\t` represents the tab character), + `ri` "completes" the text as `'Array '`. + +See also [ri at the Ready][18]. + +## Pager + +Because `ri` output is often large, +`ri` by default pipes it to a _pager_, +which is the program whose name is the first-found among: + +- The value of `ENV['RI_PAGER']`. +- The value of `ENV['PAGER']`. +- `'pager'`. +- `'less'`. +- `'more'`. + +If none is found, the output goes directly to `$stdout`, with no pager. + +If you set environment variable `RI_PAGER` or `PAGER`, +its value should be the name of an executable program +that will accept the `ri` output (such as `'pager'`, `'less'`, or `'more'`). + +See also [Output Filters][19]. + +## Options + +Options may be given on the `ri` command line; +those should be whitespace-separated, and must precede the given _name_, if any. + +Options may also be specified in environment variable `RI`; +those should also be whitespace-separated. + +An option specified in environment variable `RI` +may be overridden by an option on the `ri` command line: + +```sh +$ RI="--all" ri Array | wc -l +4224 +$ RI="--all" ri --no-all Array | wc -l +390 +``` + +### Source Directories Options + +#### Options `--doc-dir=DIRPATH`, `-d DIRPATH` + +Option `--doc-dir=DIRPATH` (aliased as `-d`) adds the given directory path +to the beginning of the array of `ri` source directory paths: + +```sh +$ ri --doc-dir=/tmp --list-doc-dirs | head -1 +/tmp +``` + +#### Options `--gems`, `--no-gems` + +Option `--gems` (the default) specifies that documents from installed gems +may be included; +option `--no-gems` may be used to exclude them: + +```sh +$ ri --list | wc -l +1417 +$ ri --list --no-gems| wc -l +1262 +``` + +#### Options `--home`, `--no-home` + +Option `--home` (the default) specifies that `ri` is to include source directory +in `~/.rdoc` if it exists; +option `--no-home` may be used to exclude them. + +#### Options `--list-doc-dirs`, `--no-list-doc-dirs` + +Option `--list-doc-dirs` specifies that a list of the `ri` source directories +is to be displayed; +default is `--no-list-doc-dirs`. + +#### Option `--no-standard` + +Option `--no-standard` specifies that documents from the standard libraries +are not to be included; +default is to include documents from the standard libraries. + +#### Options `--site`, `--no-site` + +Option `--site` (the default) specifies that documents from the site libraries +may be included; +option `--no-site` may be used to exclude them. + +#### Options `--system`, `--no-system` + +Option `--system` (the default) specifies that documents from the system libraries +may be included; +option `--no-system` may be used to exclude them. + +### Mode Options + +#### Options `--interactive`, `-i`, `--no-interactive` + +Option `--interactive` (aliased as `-i`) +specifies that `ri` is to enter interactive mode (ignoring the _name_ if given); +the option is the default when no _name_ is given; +option `--no-interactive` (the default) +specifies that `ri` is not to enter interactive mode, +regardless of whether _name_ is given. + +### Information Options + +#### Options `--help`, `-h` + +Option `--help` (aliased as `-h`) specifies that `ri` is to show +its help text and exit. + +#### Options `--version`, `-v` + +Option `--version` (aliased as `-v`) specifies that `ri` is to show its version and exit. + +### Debugging Options + +#### Options `--dump=FILEPATH`, `--no-dump` + +Option `--dump=FILEPATH` specifies that `ri` is to dump the content +of the `.ri` file at the given file path; +option`--no-dump` (the default) specifies that `ri` is not to dump content. + +The file path may point to any `.ri` file, +but typically would point to one named `cache.ri`: + +```sh +$ ri --dump=/usr/share/ri/3.0.0/system/cache.ri | wc -l +14487 +$ ri --dump=/usr/share/ri/3.0.0/system/cache.ri | head +{:ancestors=> + {"Array"=>["Enumerable", "Object"], + "RubyVM"=>["Object"], + "RubyVM::AbstractSyntaxTree::Node"=>["Object"], + "Object"=>["BasicObject", "Kernel"], + "Integer"=>["Numeric"], + "Module"=>["Object"], + "Class"=>["Module"], + "Complex"=>["Numeric"], + "NilClass"=>["Object"], +``` + +#### Options `--profile`, `--no-profile` + +Option `--profile` specifies that the program is to be run with the Ruby profiler; +option `no-profile` (the default) specifies that the program is not to be run +with the Ruby profiler. + +### Output Options + +#### Options `--format=FORMAT`, `-f FORMAT` + +Option `--format=FORMAT` (aliased as `-f`) specifies the formatter for the output, +which must be `ansi`, `bs`, `markdown`, or `rdoc`; +the default is `bs` for paged output, `ansi` otherwise. + +#### Options `--pager`, `--no-pager` + +Option `--pager` (the default) specifies that the output is to be piped +to a pager; +option `--no-pager` specifies that the output is not to be piped. + +#### Options `--width=NUMBER`, `-w NUMBER` + +Option `--width` (aliased as `-w`) specifies that the lengths of the displayed lines +should be restricted to the given _NUMBER_ of characters; +this is to be accomplished by line-wrapping, not truncation. +The default width is `80`: + +```sh +$ ri --width=40 Array | head += Array < Object + +---------------------------------------- += Includes: +Enumerable (from ruby core) + +(from ruby core) +---------------------------------------- +An Array is an ordered, integer-indexed +collection of objects, called +``` + + +### List Options + +#### Options `--list`, `-l`, `--no-list` + +Option `--list` (aliased as `-l`) specifies that all class and module names +whose initial characters match the given _name_ are to be displayed: +whose initial characters match the given _name_ are to be displayed: + +```sh +$ ri --list Ar | head +ArgumentError +Array +``` + +If no _name_ is given, all class and module names are displayed. + +Option `--no-list` (the default) specifies that a list of class and module names +is not to be displayed. + +### Methods Options (for Class or Module) + +#### Options `--all`, `-a`, `--no-all` + +Option `--all` (aliased as `-a`) specifies that when _name_ identifies a class or module, +the documents for all its methods are included; +option `--no-all` (the default) specifies that the method documents are not to be included: + +```shell +$ ri Array | wc -l +390 +$ ri --all Array | wc -l +4224 +``` + +### Server Option + +#### Option `--server=NUMBER` + +Option `--server` specifies that the \RDoc server is to be run on the port +given as _NUMBER_; +the default port is `8214`. + +## Generating `ri` Source Files + +`ri` by default reads data from directories installed by Ruby and gems. + +You can create your own `ri` source files. +This command creates `ri` source files in local directory `my_ri`, +from Ruby source files in local directory `my_sources`: + +```sh +$ rdoc --op my_ri --format=ri my_sources +``` + +Those files may then be considered for any `ri` command +by specifying option `--doc-dir=my_ri`; +see [option \\--doc-dir][20]. + +[1]: rdoc-ref:RI.md@Static+Mode +[2]: rdoc-ref:RI.md@Interactive+Mode +[3]: rdoc-ref:RI.md@Class+and+Module+Documents +[4]: rdoc-ref:RI.md@Options+--all-2C+-a-2C+--no-all +[5]: rdoc-ref:RI.md@Method+Documents +[6]: rdoc-ref:RI.md@Page+Documents +[7]: rdoc-ref:RI.md@ri+Lists +[8]: rdoc-ref:RI.md@Options+--list-2C+-l-2C+--no-list +[9]: https://docs.ruby-lang.org/en/master/IRB.html +[10]: rdoc-ref:RI.md@Pager +[11]: rdoc-ref:RI.md@Links+in+ri+Output +[12]: rdoc-ref:RI.md@Options+--list-doc-dirs-2C+--no-list-doc-dirs +[13]: rdoc-ref:RI.md@Options+--help-2C+-h +[14]: rdoc-ref:RI.md@Options+--version-2C+-v +[15]: rdoc-ref:RI.md@Options+--dump-3DFILEPATH-2C+--no-dump +[16]: rdoc-ref:RI.md@ri+Information +[17]: rdoc-ref:RI.md@Options +[18]: rdoc-ref:RI.md@ri+at+the+Ready +[19]: rdoc-ref:RI.md@Output+Filters +[20]: rdoc-ref:RI.md@Options+--doc-dir-3DDIRPATH-2C+-d+DIRPATH diff --git a/RI.rdoc b/RI.rdoc deleted file mode 100644 index f007b512e2..0000000000 --- a/RI.rdoc +++ /dev/null @@ -1,57 +0,0 @@ -= RI - -+ri+ is a tool that allows Ruby documentation to be viewed on the command-line. - -You can use +ri+ to look up information from either the command line or -interactively. When you run +ri+ without any arguments it will launch in -interactive mode. In interactive mode you can tab-complete class and method -names. - -== Usage - -To see information for a class, do: - ri ClassName - -For example, for the Array class, do: - ri Array - -To see information on a method on a class, do: - ri ClassName.method - -This will show both instance and class methods. For example, the IO -class defines both IO::read and IO#read: - ri IO.read - -To see information for an instance method, do: - ri ClassName#method_name - -For example, for Array's +join+ method, do: - ri Array#join - -To see information for a class method, do: - ri ClassName::method_name - -For example, for Module's +private+ method, do: - ri Module::private - -To read documentation for all +read+ methods, do: - ri read - -== Options - -+ri+ supports a variety of options, all of which can be viewed via +--help+. -Of particular interest, are: - -[-f] - Outputs ri data using the selected formatter. You can see the available - formatters in ri --help -[-T] - Send output to stdout, rather than to a pager. - -All options also can be specified through the +RI+ environment variable. -Command-line options always override those specified in the +RI+ environment -variable. - -The +RI_PAGER+ environment variable allows you to choose a particular pager or -particular options for your pager. - diff --git a/Rakefile b/Rakefile index aec3ded2a1..17f5b9061b 100644 --- a/Rakefile +++ b/Rakefile @@ -1,172 +1,121 @@ -$:.unshift File.expand_path 'lib' -require 'rdoc' -require 'hoe' +# frozen_string_literal: true -ENV['BENCHMARK'] = 'yes' +$:.unshift File.expand_path('lib', __dir__) # default template dir -task :docs => :generate -task :test => :generate +require_relative 'lib/rdoc/task' +require 'bundler/gem_tasks' +require 'rake/testtask' + +task :test => [:normal_test, :rubygems_test] PARSER_FILES = %w[ - lib/rdoc/rd/block_parser.rb - lib/rdoc/rd/inline_parser.rb - lib/rdoc/markdown.rb - lib/rdoc/markdown/literals_1_8.rb - lib/rdoc/markdown/literals_1_9.rb + lib/rdoc/rd/block_parser.ry + lib/rdoc/rd/inline_parser.ry + lib/rdoc/markdown.kpeg + lib/rdoc/markdown/literals.kpeg ] -Hoe.plugin :git -Hoe.plugin :kpeg -Hoe.plugin :minitest -Hoe.plugin :travis - $rdoc_rakefile = true -hoe = Hoe.spec 'rdoc' do - developer 'Eric Hodel', 'drbrain@segment7.net' - developer 'Dave Thomas', '' - developer 'Phil Hagelberg', 'technomancy@gmail.com' - developer 'Tony Strauss', 'tony.strauss@designingpatterns.com' - - self.rsync_args = '-avz' - rdoc_locations << 'docs.seattlerb.org:/data/www/docs.seattlerb.org/rdoc/' - rdoc_locations << 'drbrain@rubyforge.org:/var/www/gforge-projects/rdoc/' - - self.licenses << 'Ruby' - self.readme_file = 'README.rdoc' - self.history_file = 'History.rdoc' - self.testlib = :minitest - self.extra_rdoc_files += %w[ - CVE-2013-0256.rdoc - CONTRIBUTING.rdoc - ExampleMarkdown.md - ExampleRDoc.rdoc - History.rdoc - LEGAL.rdoc - LICENSE.rdoc - README.rdoc - RI.rdoc - TODO.rdoc - ] - - self.clean_globs += PARSER_FILES - self.kpeg_flags = '-fsv' if self.respond_to? :kpeg_flags= # no plugin - - require_ruby_version '>= 1.9.3' - extra_dev_deps << ['racc', '~> 1.4', '> 1.4.10'] - extra_dev_deps << ['minitest', '~> 4'] - - extra_rdoc_files << 'Rakefile' - spec_extras['required_rubygems_version'] = '>= 1.3' - spec_extras['homepage'] = 'http://docs.seattlerb.org/rdoc' -end +task :default => :test -hoe.test_prelude = 'gem "minitest", "~> 4.0"' - -def rake(*args) - sh $0, *args +task rdoc: :generate +RDoc::Task.new do |doc| + # RDoc task defaults to /html and overrides the op_dir option in .rdoc_options + doc.rdoc_dir = "_site" # for GitHub Pages end -need_racc = PARSER_FILES.any? do |rb_file| - ry_file = rb_file.gsub(/\.rb\z/, ".ry") - not File.exist?(rb_file) or - (File.exist?(ry_file) and File.mtime(rb_file) < File.mtime(ry_file)) -end - -if need_racc - Rake::Task["default"].prerequisites.clear - task :default do - rake "check_extra_deps" - rake "install_plugins" - rake "newb" +task "coverage" do + cov = [] + e = IO.popen([FileUtils::RUBY, "-I./lib", "exe/rdoc", "-C"], &:read) + e.scan(/^ *# in file (?.*)\n *(?.*)|^ *(?.*\S) *# in file (?.*)/) do + cov << "%s: %s\n" % $~.values_at(:loc, :code) end + cov.sort! + puts cov end -Rake::Task['docs'].actions.clear -task :docs do - $LOAD_PATH.unshift 'lib' - require 'rdoc' - - options = RDoc::Options.new - options.title = "rdoc #{RDoc::VERSION} Documentation" - options.op_dir = 'doc' - options.main_page = 'README.rdoc' - options.files = hoe.spec.extra_rdoc_files + %w[lib] - options.setup_generator 'darkfish' +Rake::TestTask.new(:normal_test) do |t| + t.verbose = true + t.deps = :generate + t.test_files = FileList["test/**/*_test.rb"].exclude("test/rdoc/rdoc_rubygems_hook_test.rb") +end - RDoc::RDoc.new.document options +Rake::TestTask.new(:rubygems_test) do |t| + t.verbose = true + t.deps = :generate + t.pattern = "test/rdoc/rdoc_rubygems_hook_test.rb" end -# requires ruby 1.8 and ruby 1.8 to build -hoe.clean_globs -= PARSER_FILES.grep(/literals_/) +path = "pkg/#{Bundler::GemHelper.gemspec.full_name}" -task :generate => :isolate -task :generate => PARSER_FILES -task :check_manifest => :generate +package_parser_files = PARSER_FILES.map do |parser_file| + name = File.basename(parser_file, File.extname(parser_file)) + _path = File.dirname(parser_file) + package_parser_file = "#{path}/#{name}.rb" + parsed_file = "#{_path}/#{name}.rb" -rule '.rb' => '.ry' do |t| - racc = Gem.bin_path 'racc', 'racc' + file package_parser_file => parsed_file # ensure copy runs before racc - ruby "-rubygems #{racc} -l -o #{t.name} #{t.source}" + package_parser_file end -path = "pkg/#{hoe.spec.full_name}" +parsed_files = PARSER_FILES.map do |parser_file| + ext = File.extname(parser_file) + parsed_file = "#{parser_file.chomp(ext)}.rb" + + file parsed_file => parser_file do |t| + puts "Generating #{parsed_file}..." + case ext + when '.ry' # need racc + racc = Gem.bin_path 'racc', 'racc' + rb_file = parser_file.gsub(/\.ry\z/, ".rb") + ruby "#{racc} -l -E -o #{rb_file} #{parser_file}" + File.open(rb_file, 'r+') do |f| + newtext = "# frozen_string_literal: true\n#{f.read}" + f.rewind + f.write newtext + end + when '.kpeg' # need kpeg + kpeg = Gem.bin_path 'kpeg', 'kpeg' + rb_file = parser_file.gsub(/\.kpeg\z/, ".rb") + ruby "#{kpeg} -fsv -o #{rb_file} #{parser_file}" + File.write(rb_file, File.read(rb_file).gsub(/ +$/, '')) # remove trailing spaces + end + end -package_parser_files = PARSER_FILES.map do |parser_file| - package_parser_file = "#{path}/#{parser_file}" - file package_parser_file => parser_file # ensure copy runs before racc - package_parser_file + parsed_file end task "#{path}.gem" => package_parser_files +desc "Generate all files used racc and kpeg" +task :generate => parsed_files -# These tasks expect to have the following directory structure: -# -# git/git.rubini.us/code # Rubinius git HEAD checkout -# svn/ruby/trunk # ruby subversion HEAD checkout -# svn/rdoc/trunk # RDoc subversion HEAD checkout -# -# If you don't have this directory structure, set RUBY_PATH and/or -# RUBINIUS_PATH. - -diff_options = "-urpN --exclude '*svn*' --exclude '*swp' --exclude '*rbc'" -rsync_options = "-avP --exclude '*svn*' --exclude '*swp' --exclude '*rbc' --exclude '*.rej' --exclude '*.orig' --exclude '*.kpeg' --exclude '*.ry' --exclude 'literals_1_8.rb' --exclude 'gauntlet_rdoc.rb'" - -rubinius_dir = ENV['RUBINIUS_PATH'] || '../../../git/git.rubini.us/code' -ruby_dir = ENV['RUBY_PATH'] || '../../svn/ruby/trunk' - -desc "Updates Ruby HEAD with the currently checked-out copy of RDoc." -task :update_ruby do - sh "rsync #{rsync_options} bin/rdoc #{ruby_dir}/bin/rdoc" - sh "rsync #{rsync_options} bin/ri #{ruby_dir}/bin/ri" - sh "rsync #{rsync_options} lib/ #{ruby_dir}/lib" - sh "rsync #{rsync_options} test/ #{ruby_dir}/test/rdoc" +task :clean do + parsed_files.each do |path| + File.delete(path) if File.exist?(path) + end end -desc "Diffs Ruby HEAD with the currently checked-out copy of RDoc." -task :diff_ruby do - options = "-urpN --exclude '*svn*' --exclude '*swp' --exclude '*rbc'" +desc "Build #{Bundler::GemHelper.gemspec.full_name} and move it to local ruby/ruby project's bundled gems folder" +namespace :build do + task local_ruby: :build do + target = File.join("..", "ruby", "gems") - sh "diff #{diff_options} bin/rdoc #{ruby_dir}/bin/rdoc; true" - sh "diff #{diff_options} bin/ri #{ruby_dir}/bin/ri; true" - sh "diff #{diff_options} lib/rdoc.rb #{ruby_dir}/lib/rdoc.rb; true" - sh "diff #{diff_options} lib/rdoc #{ruby_dir}/lib/rdoc; true" - sh "diff #{diff_options} test #{ruby_dir}/test/rdoc; true" -end + unless File.directory?(target) + abort("Expected Ruby to be cloned under the same parent directory as RDoc to use this task") + end -desc "Updates Rubinius HEAD with the currently checked-out copy of RDoc." -task :update_rubinius do - sh "rsync #{rsync_options} bin/rdoc #{rubinius_dir}/lib/bin/rdoc.rb" - sh "rsync #{rsync_options} bin/ri #{rubinius_dir}/lib/bin/ri.rb" - sh "rsync #{rsync_options} lib/ #{rubinius_dir}/lib" - sh "rsync #{rsync_options} test/ #{rubinius_dir}/test/rdoc" + mv("#{path}.gem", target) + end end -desc "Diffs Rubinius HEAD with the currently checked-out copy of RDoc." -task :diff_rubinius do - sh "diff #{diff_options} bin/rdoc #{rubinius_dir}/lib/bin/rdoc.rb; true" - sh "diff #{diff_options} bin/ri #{rubinius_dir}/lib/bin/ri.rb; true" - sh "diff #{diff_options} lib/rdoc.rb #{rubinius_dir}/lib/rdoc.rb; true" - sh "diff #{diff_options} lib/rdoc #{rubinius_dir}/lib/rdoc; true" - sh "diff #{diff_options} test #{rubinius_dir}/test/rdoc; true" +begin + require 'rubocop/rake_task' +rescue LoadError +else + RuboCop::RakeTask.new(:format_generated_files) do |t| + t.options = parsed_files + ["--config=.generated_files_rubocop.yml"] + end + task :build => [:generate, "format_generated_files:autocorrect"] end diff --git a/TODO.rdoc b/TODO.rdoc index 431f6f640e..da919118d9 100644 --- a/TODO.rdoc +++ b/TODO.rdoc @@ -1,9 +1,10 @@ += TODO This file contains some things that might happen in RDoc, or might not. Forward Looking Statements applies. -=== RDoc::VERSION.succ +== RDoc::VERSION.succ -Blockers: +=== Blockers: * Update LICENSE to match ruby's switch * The alias keyword should not be bidirectional @@ -13,7 +14,7 @@ Blockers: * Fix consumption of , after link like: RDoc[rdoc-ref:RDoc], <- comma here * Remove support for links like Matrix[*rows] -Nice to have: +=== Nice to have: * Parse only changed files (like in ruby) * Page of Glory (or Shame) in HTML output showing documentation coverage @@ -26,9 +27,9 @@ Nice to have: * Global variable support * Provide the code_object to directive handlers -=== 4 +== More Future -API changes to RDoc +=== API changes to RDoc * RDoc::TopLevel#add_method should automatically create the appropriate method class rather than requiring one be passed in. @@ -36,7 +37,7 @@ API changes to RDoc * Add versions to RDoc::Markup syntax tree marshal format * Comments can no longer be Strings -=== Crazy Ideas +== Crazy Ideas * Auto-normalize heading levels to look OK. It's weird to see an

in the middle of a method section. @@ -46,7 +47,7 @@ API changes to RDoc * Rename Context to Container * Rename NormalClass to Class -=== Accessibility +== Accessibility Page title in right hand side diff --git a/bin/console b/bin/console new file mode 100755 index 0000000000..2090c32bd8 --- /dev/null +++ b/bin/console @@ -0,0 +1,10 @@ +#!/usr/bin/env ruby + +require 'bundler/setup' +require 'rdoc' + +# This is the easy way to prepare various kinds of RDoc objects. +require_relative '../doc/rdoc/markup_reference' + +require 'irb' +IRB.start(__FILE__) diff --git a/doc/rdoc/markup_reference.rb b/doc/rdoc/markup_reference.rb new file mode 100644 index 0000000000..ee585b2497 --- /dev/null +++ b/doc/rdoc/markup_reference.rb @@ -0,0 +1,1281 @@ +require 'rdoc' + +# \Class \RDoc::MarkupReference exists only to provide a suitable home +# for a reference document for \RDoc markup. +# +# All objects defined in this class -- classes, modules, methods, aliases, +# attributes, and constants -- are solely for illustrating \RDoc markup, +# and have no other legitimate use. +# +# == About the Examples +# +# - Examples in this reference are Ruby code and comments; +# certain differences from other sources +# (such as C code and comments) are noted. +# - Almost all examples on this page are all RDoc-like; +# that is, they have no explicit comment markers like Ruby # +# or C /* ... */. +# - An example that shows rendered HTML output +# displays that output in a blockquote: +# +# >>> +# Some stuff +# +# == \RDoc Sources +# +# The sources of \RDoc documentation vary according to the type of file: +# +# - .rb (Ruby code file): +# +# - Markup may be found in Ruby comments: +# A comment that immediately precedes the definition +# of a Ruby class, module, method, alias, constant, or attribute +# becomes the documentation for that defined object. +# - An \RDoc directive may be found in: +# +# - A trailing comment (on the same line as code); +# see :nodoc:, :doc:, and :notnew:. +# - A single-line comment; +# see other {Directives}[rdoc-ref:RDoc::MarkupReference@Directives]. +# +# - Documentation may be derived from the Ruby code itself; +# see {Documentation Derived from Ruby Code}[rdoc-ref:RDoc::MarkupReference@Documentation+Derived+from+Ruby+Code]. +# +# - .c (C code file): markup is parsed from C comments. +# A comment that immediately precedes +# a function that implements a Ruby method, +# or otherwise immediately precedes the definition of a Ruby object, +# becomes the documentation for that object. +# - .rdoc (\RDoc markup text file) or .md (\RDoc markdown text file): +# markup is parsed from the entire file. +# The text is not associated with any code object, +# but may (depending on how the documentation is built) +# become a separate page. +# +# An RDoc document: +# +# - A (possibly multi-line) comment in a Ruby or C file +# that generates \RDoc documentation (as above). +# - The entire markup (.rdoc) file or markdown (.md) file +# (which is usually multi-line). +# +# === Blocks +# +# It's convenient to think of an \RDoc document as a sequence of _blocks_ +# of various types (details at the links): +# +# - {Paragraph}[rdoc-ref:RDoc::MarkupReference@Paragraphs]: +# an ordinary paragraph. +# - {Verbatim text block}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks]: +# a block of text to be rendered literally. +# - {Code block}[rdoc-ref:RDoc::MarkupReference@Code+Blocks]: +# a verbatim text block containing Ruby code, +# to be rendered with code highlighting. +# - {Block quote}[rdoc-ref:RDoc::MarkupReference@Block+Quotes]: +# a longish quoted passage, to be rendered with indentation +# instead of quote marks. +# - {List}[rdoc-ref:RDoc::MarkupReference@Lists]: items for +# a bullet list, numbered list, lettered list, or labeled list. +# - {Heading}[rdoc-ref:RDoc::MarkupReference@Headings]: +# a heading. +# - {Horizontal rule}[rdoc-ref:RDoc::MarkupReference@Horizontal+Rules]: +# a line across the rendered page. +# - {Directive}[rdoc-ref:RDoc::MarkupReference@Directives]: +# various special directions for the rendering. +# - {Text Markup}[rdoc-ref:RDoc:MarkupReference@Text+Markup]: +# text to be rendered in a special way. +# +# About the blocks: +# +# - Except for a paragraph, a block is distinguished by its indentation, +# or by unusual initial or embedded characters. +# - Any block may appear independently +# (that is, not nested in another block); +# some blocks may be nested, as detailed below. +# - In a multi-line block, +# \RDoc looks for the block's natural left margin, +# which becomes the base margin for the block +# and is the initial current margin for the block. +# +# ==== Paragraphs +# +# A paragraph consists of one or more non-empty lines of ordinary text, +# each beginning at the current margin. +# +# Note: Here, ordinary text means text that is not identified +# by indentation, or by unusual initial or embedded characters. +# See below. +# +# Paragraphs are separated by one or more empty lines. +# +# Example input: +# +# \RDoc produces HTML and command-line documentation for Ruby projects. +# \RDoc includes the rdoc and ri tools for generating and displaying +# documentation from the command-line. +# +# You'll love it. +# +# Rendered HTML: +# >>> +# \RDoc produces HTML and command-line documentation for Ruby projects. +# \RDoc includes the rdoc and ri tools for generating and displaying +# documentation from the command-line. +# +# You'll love it. +# +# A paragraph may contain nested blocks, including: +# +# - {Verbatim text blocks}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks]. +# - {Code blocks}[rdoc-ref:RDoc::MarkupReference@Code+Blocks]. +# - {Block quotes}[rdoc-ref:RDoc::MarkupReference@Block+Quotes]. +# - {Lists}[rdoc-ref:RDoc::MarkupReference@Lists]. +# - {Headings}[rdoc-ref:RDoc::MarkupReference@Headings]. +# - {Horizontal rules}[rdoc-ref:RDoc::MarkupReference@Horizontal+Rules]. +# - {Text Markup}[rdoc-ref:RDoc:MarkupReference@Text+Markup]. +# +# ==== Verbatim Text Blocks +# +# Text indented farther than the current margin becomes a verbatim text block +# (or a code block, described next). +# In the rendered HTML, such text: +# +# - Is indented. +# - Has a contrasting background color. +# +# The verbatim text block ends at the first line beginning at the current margin. +# +# Example input: +# +# This is not verbatim text. +# +# This is verbatim text. +# Whitespace is honored. # See? +# Whitespace is honored. # See? +# +# This is still the same verbatim text block. +# +# This is not verbatim text. +# +# Rendered HTML: +# >>> +# This is not verbatim text. +# +# This is verbatim text. +# Whitespace is honored. # See? +# Whitespace is honored. # See? +# +# This is still the same verbatim text block. +# +# This is not verbatim text. +# +# A verbatim text block may not contain nested blocks of any kind +# -- it's verbatim. +# +# ==== Code Blocks +# +# A special case of verbatim text is the code block, +# which is merely verbatim text that \RDoc recognizes as Ruby code: +# +# In the rendered HTML, the code block: +# +# - Is indented. +# - Has a contrasting background color. +# - Has syntax highlighting. +# +# Example input: +# +# Consider this method: +# +# def foo(name = '', value = 0) +# @name = name # Whitespace is still honored. +# @value = value +# end +# +# +# Rendered HTML: +# >>> +# Consider this method: +# +# def foo(name = '', value = 0) +# @name = name # Whitespace is still honored. +# @value = value +# end +# +# Pro tip: If your indented Ruby code does not get highlighted, +# it may contain a syntax error. +# +# A code block may not contain nested blocks of any kind +# -- it's verbatim. +# +# ==== Block Quotes +# +# You can use the characters >>> (unindented), +# followed by indented text, to treat the text +# as a {block quote}[https://en.wikipedia.org/wiki/Block_quotation]: +# +# Example input: +# +# Here's a block quote: +# >>> +# Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer +# commodo quam iaculis massa posuere, dictum fringilla justo pulvinar. +# Quisque turpis erat, pharetra eu dui at, sollicitudin accumsan nulla. +# +# Aenean congue ligula eu ligula molestie, eu pellentesque purus +# faucibus. In id leo non ligula condimentum lobortis. Duis vestibulum, +# diam in pellentesque aliquet, mi tellus placerat sapien, id euismod +# purus magna ut tortor. +# +# Rendered HTML: +# +# >>> +# Here's a block quote: +# >>> +# Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer +# commodo quam iaculis massa posuere, dictum fringilla justo pulvinar. +# Quisque turpis erat, pharetra eu dui at, sollicitudin accumsan nulla. +# +# Aenean congue ligula eu ligula molestie, eu pellentesque purus +# faucibus. In id leo non ligula condimentum lobortis. Duis vestibulum, +# diam in pellentesque aliquet, mi tellus placerat sapien, id euismod +# purus magna ut tortor. +# +# Note that, unlike verbatim text, single newlines are not honored, +# but that a double newline begins a new paragraph in the block quote. +# +# A block quote may contain nested blocks, including: +# +# - Other block quotes. +# - {Paragraphs}[rdoc-ref:RDoc::MarkupReference@Paragraphs]. +# - {Verbatim text blocks}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks]. +# - {Code blocks}[rdoc-ref:RDoc::MarkupReference@Code+Blocks]. +# - {Lists}[rdoc-ref:RDoc::MarkupReference@Lists]. +# - {Headings}[rdoc-ref:RDoc::MarkupReference@Headings]. +# - {Horizontal rules}[rdoc-ref:RDoc::MarkupReference@Horizontal+Rules]. +# - {Text Markup}[rdoc-ref:RDoc:MarkupReference@Text+Markup]. +# +# ==== Lists +# +# Each type of list item is marked by a special beginning: +# +# - Bullet list item: Begins with a hyphen or asterisk. +# - Numbered list item: Begins with digits and a period. +# - Lettered list item: Begins with an alphabetic character and a period. +# - Labeled list item: Begins with one of: +# - Square-bracketed text. +# - A word followed by two colons. +# +# A list begins with a list item and continues, even across blank lines, +# as long as list items of the same type are found at the same indentation level. +# +# A new list resets the current margin inward. +# Additional lines of text aligned at that margin +# are part of the continuing list item. +# +# A list item may be continued on additional lines that are aligned +# with the first line. See examples below. +# +# A list item may contain nested blocks, including: +# +# - Other lists of any type. +# - {Paragraphs}[rdoc-ref:RDoc::MarkupReference@Paragraphs]. +# - {Verbatim text blocks}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks]. +# - {Code blocks}[rdoc-ref:RDoc::MarkupReference@Code+Blocks]. +# - {Block quotes}[rdoc-ref:RDoc::MarkupReference@Block+Quotes]. +# - {Headings}[rdoc-ref:RDoc::MarkupReference@Headings]. +# - {Horizontal rules}[rdoc-ref:RDoc::MarkupReference@Horizontal+Rules]. +# - {Text Markup}[rdoc-ref:RDoc:MarkupReference@Text+Markup]. +# +# ===== Bullet Lists +# +# A bullet list item begins with a hyphen or asterisk. +# +# Example input: +# +# - An item. +# - Another. +# - An item spanning +# multiple lines. +# +# * Yet another. +# - Last one. +# +# Rendered HTML: +# >>> +# - An item. +# - Another. +# - An item spanning +# multiple lines. +# +# * Yet another. +# - Last one. +# +# ===== Numbered Lists +# +# A numbered list item begins with digits and a period. +# +# The items are automatically re-numbered. +# +# Example input: +# +# 100. An item. +# 10. Another. +# 1. An item spanning +# multiple lines. +# +# 1. Yet another. +# 1000. Last one. +# +# Rendered HTML: +# >>> +# 100. An item. +# 10. Another. +# 1. An item spanning +# multiple lines. +# +# 1. Yet another. +# 1000. Last one. +# +# ===== Lettered Lists +# +# A lettered list item begins with letters and a period. +# +# The items are automatically "re-lettered." +# +# Example input: +# +# z. An item. +# y. Another. +# x. An item spanning +# multiple lines. +# +# x. Yet another. +# a. Last one. +# +# Rendered HTML: +# >>> +# z. An item. +# y. Another. +# +# x. Yet another. +# a. Last one. +# +# ===== Labeled Lists +# +# A labeled list item begins with one of: +# +# - Square-bracketed text: the label and text are on two lines. +# - A word followed by two colons: the label and text are on the same line. +# +# Example input: +# +# [foo] An item. +# bat:: Another. +# [bag] An item spanning +# multiple lines. +# +# [bar baz] Yet another. +# bam:: Last one. +# +# Rendered HTML: +# >>> +# [foo] An item. +# bat:: Another. +# [bag] An item spanning +# multiple lines. +# +# [bar baz] Yet another. +# bam:: Last one. +# +# ==== Headings +# +# A heading begins with up to six equal-signs, followed by heading text. +# Whitespace between those and the heading text is optional. +# +# Examples: +# +# = Section 1 +# == Section 1.1 +# === Section 1.1.1 +# === Section 1.1.2 +# == Section 1.2 +# = Section 2 +# = Foo +# == Bar +# === Baz +# ==== Bam +# ===== Bat +# ====== Bad +# ============Still a Heading (Level 6) +# \== Not a Heading +# +# A heading may contain only one type of nested block: +# +# - {Text Markup}[rdoc-ref:RDoc:MarkupReference@Text+Markup]. +# +# ==== Horizontal Rules +# +# A horizontal rule consists of a line with three or more hyphens +# and nothing more. +# +# Example input: +# +# --- +# --- Not a horizontal rule. +# +# -- Also not a horizontal rule. +# --- +# +# Rendered HTML: +# >>> +# --- +# --- Not a horizontal rule. +# +# -- Also not a horizontal rule. +# --- +# +# ==== Directives +# +# ===== Directives for Allowing or Suppressing Documentation +# +# - # :stopdoc:: +# +# - Appears on a line by itself. +# - Specifies that \RDoc should ignore markup +# until next :startdoc: directive or end-of-file. +# +# - # :startdoc:: +# +# - Appears on a line by itself. +# - Specifies that \RDoc should resume parsing markup. +# +# - # :enddoc:: +# +# - Appears on a line by itself. +# - Specifies that \RDoc should ignore markup to end-of-file +# regardless of other directives. +# +# - # :nodoc:: +# +# - Appended to a line of code +# that defines a class, module, method, alias, constant, or attribute. +# +# - Specifies that the defined object should not be documented. +# +# - For a method definition in C code, it the directive must be in the comment line +# immediately preceding the definition: +# +# /* :nodoc: */ +# static VALUE +# some_method(VALUE self) +# { +# return self; +# } +# +# Note that this directive has no effect at all +# when placed at the method declaration: +# +# /* :nodoc: */ +# rb_define_method(cMyClass, "do_something", something_func, 0); +# +# The above comment is just a comment and has nothing to do with \RDoc. +# Therefore, +do_something+ method will be reported as "undocumented" +# unless that method or function is documented elsewhere. +# +# - For a constant definition in C code, this directive can not work +# because there is no "implementation" place for a constant. +# +# - # :nodoc: all: +# +# - Appended to a line of code +# that defines a class or module. +# - Specifies that the class or module should not be documented. +# By default, however, a nested class or module _will_ be documented. +# +# - # :doc:: +# +# - Appended to a line of code +# that defines a class, module, method, alias, constant, or attribute. +# - Specifies the defined object should be documented, even if it otherwise +# would not be documented. +# +# - # :notnew: (aliased as :not_new: and :not-new:): +# +# - Appended to a line of code +# that defines instance method +initialize+. +# - Specifies that singleton method +new+ should not be documented. +# By default, Ruby fakes a corresponding singleton method +new+, +# which \RDoc includes in the documentation. +# Note that instance method +initialize+ is private, and so by default +# is not documented. +# +# For Ruby code, but not for other \RDoc sources, +# there is a shorthand for :stopdoc: and :startdoc:: +# +# # Documented. +# #-- +# # Not documented. +# #++ +# # Documented. +# +# For C code, any of directives :startdoc:, :stopdoc:, +# and :enddoc: may appear in a stand-alone comment: +# +# /* :startdoc: */ +# /* :stopdoc: */ +# /* :enddoc: */ +# +# ===== Directive for Specifying \RDoc Source Format +# +# - # :markup: _type_: +# +# - Appears on a line by itself. +# - Specifies the format for the \RDoc input; +# parameter +type+ is one of: +rdoc+ (the default), +markdown+, +rd+, +tomdoc+. +# See {Markup Formats}[rdoc-ref:RDoc::Markup@Markup+Formats]. +# +# ===== Directives for Method Documentation +# +# - # :call-seq:: +# +# - Appears on a line by itself. +# - Specifies the calling sequence to be reported in the HTML, +# overriding the actual calling sequence in the code. +# See method #call_seq_directive. +# +# Note that \RDoc can build the calling sequence for a Ruby-coded method, +# but not for other languages. +# You may want to override that by explicitly giving a :call-seq: +# directive if you want to include: +# +# - A return type, which is not automatically inferred. +# - Multiple calling sequences. +# +# For C code, the directive may appear in a stand-alone comment. +# +# - # :args: _arg_names_ (aliased as :arg:): +# +# - Appears on a line by itself. +# - Specifies the arguments to be reported in the HTML, +# overriding the actual arguments in the code. +# See method #args_directive. +# +# - # :yields: _arg_names_ (aliased as :yield:): +# +# - Appears on a line by itself. +# - Specifies the yield arguments to be reported in the HTML, +# overriding the actual yield in the code. +# See method #yields_directive. +# +# ===== Directives for Organizing Documentation +# +# By default, \RDoc groups: +# +# - Singleton methods together in alphabetical order. +# - Instance methods and their aliases together in alphabetical order. +# - Attributes and their aliases together in alphabetical order. +# +# You can use directives to modify those behaviors. +# +# - # :section: _section_title_: +# +# - Appears on a line by itself. +# - Specifies that following methods are to be grouped into the section +# with the given section_title, +# or into the default section if no title is given. +# The directive remains in effect until another such directive is given, +# but may be temporarily overridden by directive :category:. +# See below. +# +# The comment block containing this directive: +# +# - Must be separated by a blank line from the documentation for the next item. +# - May have one or more lines preceding the directive. +# These will be removed, along with any trailing lines that match them. +# Such lines may be visually helpful. +# - Lines of text that are not so removed become the descriptive text +# for the section. +# +# Example: +# +# # ---------------------------------------- +# # :section: My Section +# # This is the section that I wrote. +# # See it glisten in the noon-day sun. +# # ---------------------------------------- +# +# ## +# # Comment for some_method +# def some_method +# # ... +# end +# +# You can use directive :category: to temporarily +# override the current section. +# +# - # :category: _section_title_: +# +# - Appears on a line by itself. +# - Specifies that just one following method is to be included +# in the given section, or in the default section if no title is given. +# Subsequent methods are to be grouped into the current section. +# +# ===== Directive for Including a File +# +# - # :include: _filepath_: +# +# - Appears on a line by itself. +# - Specifies that the contents of the given file +# are to be included at this point. +# The file content is shifted to have the same indentation as the colon +# at the start of the directive. +# +# The file is searched for in the directory containing the current file, +# and then in each of the directories given with the --include +# command-line option. +# +# For C code, the directive may appear in a stand-alone comment +# +# ==== Text Markup +# +# Text markup is metatext that affects HTML rendering: +# +# - Typeface: italic, bold, monofont. +# - Character conversions: copyright, trademark, certain punctuation. +# - Links. +# - Escapes: marking text as "not markup." +# +# ===== Typeface Markup +# +# Typeface markup can specify that text is to be rendered +# as italic, bold, or monofont. +# +# Typeface markup may contain only one type of nested block: +# +# - More typeface markup: +# italic, bold, monofont. +# +# ====== Italic +# +# Text may be marked as italic via HTML tag or . +# +# Example input: +# +# Italicized words in a paragraph. +# +# >>> +# Italicized words in a block quote. +# +# - Italicized words in a list item. +# +# ====== Italicized words in a Heading +# +# Italicized passage containing *bold* and +monofont+. +# +# Rendered HTML: +# >>> +# Italicized words in a paragraph. +# +# >>> +# Italicized words in a block quote. +# +# - Italicized words in a list item. +# +# ====== Italicized words in a Heading +# +# Italicized passage containing *bold* and +monofont+. +# +# A single word may be italicized via a shorthand: +# prefixed and suffixed underscores. +# +# Example input: +# +# _Italic_ in a paragraph. +# +# >>> +# _Italic_ in a block quote. +# +# - _Italic_ in a list item. +# +# ====== _Italic_ in a Heading +# +# Rendered HTML: +# >>> +# _Italic_ in a paragraph. +# +# >>> +# _Italic_ in a block quote. +# +# - _Italic_ in a list item. +# +# ====== _Italic_ in a Heading +# +# ====== Bold +# +# Text may be marked as bold via HTML tag . +# +# Example input: +# +# Bold words in a paragraph. +# +# >>> +# Bold words in a block quote. +# +# - Bold words in a list item. +# +# ====== Bold words in a Heading +# +# Bold passage containing _italics_ and +monofont+. +# +# Rendered HTML: +# +# >>> +# Bold words in a paragraph. +# +# >>> +# Bold words in a block quote. +# +# - Bold words in a list item. +# +# ====== Bold words in a Heading +# +# Bold passage containing _italics_ and +monofont+. +# +# A single word may be made bold via a shorthand: +# prefixed and suffixed asterisks. +# +# Example input: +# +# *Bold* in a paragraph. +# +# >>> +# *Bold* in a block quote. +# +# - *Bold* in a list item. +# +# ===== *Bold* in a Heading +# +# Rendered HTML: +# +# >>> +# *Bold* in a paragraph. +# +# >>> +# *Bold* in a block quote. +# +# - *Bold* in a list item. +# +# ===== *Bold* in a Heading +# +# ====== Monofont +# +# Text may be marked as monofont +# -- sometimes called 'typewriter font' -- +# via HTML tag or . +# +# Example input: +# +# Monofont words in a paragraph. +# +# >>> +# Monofont words in a block quote. +# +# - Monofont words in a list item. +# +# ====== Monofont words in heading +# +# Monofont passage containing _italics_ and *bold*. +# +# Rendered HTML: +# +# >>> +# Monofont words in a paragraph. +# +# >>> +# Monofont words in a block quote. +# +# - Monofont words in a list item. +# +# ====== Monofont words in heading +# +# Monofont passage containing _italics_ and *bold*. +# +# A single word may be made monofont by a shorthand: +# prefixed and suffixed plus-signs. +# +# Example input: +# +# +Monofont+ in a paragraph. +# +# >>> +# +Monofont+ in a block quote. +# +# - +Monofont+ in a list item. +# +# ====== +Monofont+ in a Heading +# +# Rendered HTML: +# +# >>> +# +Monofont+ in a paragraph. +# +# >>> +# +Monofont+ in a block quote. +# +# - +Monofont+ in a list item. +# +# ====== +Monofont+ in a Heading +# +# ==== Character Conversions +# +# Certain combinations of characters may be converted to special characters; +# whether the conversion occurs depends on whether the special character +# is available in the current encoding. +# +# - (c) converts to (c) (copyright character); must be lowercase. +# +# - (r) converts to (r) (registered trademark character); must be lowercase. +# +# - 'foo' converts to 'foo' (smart single-quotes). +# +# - "foo" converts to "foo" (smart double-quotes). +# +# - foo ... bar converts to foo ... bar (1-character ellipsis). +# +# - foo -- bar converts to foo -- bar (1-character en-dash). +# +# - foo --- bar converts to foo --- bar (1-character em-dash). +# +# ==== Links +# +# Certain strings in \RDoc text are converted to links. +# Any such link may be suppressed by prefixing a backslash. +# This section shows how to link to various +# targets. +# +# [Class] +# +# - On-page: DummyClass links to DummyClass. +# - Off-page: RDoc::Alias links to RDoc::Alias. +# +# Note: For poeple want to mark up code (such as class, module, +# constant, and method) as "+code+" (for interoperability +# with other MarkDown parsers mainly), such word that refers a known +# code object and is marked up entirely and separately as "monofont" +# is also converted to a link. +# +# - +DummyClass+ links to DummyClass +# - +DummyClass-object+ is not a link. +# +# [Module] +# +# - On-page: DummyModule links to DummyModule. +# - Off-page: RDoc links to RDoc. +# +# [Constant] +# +# - On-page: DUMMY_CONSTANT links to DUMMY_CONSTANT. +# - Off-page: RDoc::Text::MARKUP_FORMAT links to RDoc::Text::MARKUP_FORMAT. +# +# [Singleton Method] +# +# - On-page: ::dummy_singleton_method links to ::dummy_singleton_method. +# - Off-pageRDoc::TokenStream::to_html links to RDoc::TokenStream::to_html. +# +# Note: Occasionally \RDoc is not linked to a method whose name +# has only special characters. Check whether the links you were expecting +# are actually there. If not, you'll need to put in an explicit link; +# see below. +# +# Pro tip: The link to any method is available in the alphabetical table of contents +# at the top left of the page for the class or module. +# +# [Instance Method] +# +# - On-page: #dummy_instance_method links to #dummy_instance_method. +# - Off-page: RDoc::Alias#html_name links to RDoc::Alias#html_name. +# +# See the Note and Pro Tip immediately above. +# +# [Attribute] +# +# - On-page: #dummy_attribute links to #dummy_attribute. +# - Off-page: RDoc::Alias#name links to RDoc::Alias#name. +# +# [Alias] +# +# - On-page: #dummy_instance_alias links to #dummy_instance_alias. +# - Off-page: RDoc::Alias#new_name links to RDoc::Alias#new_name. +# +# [Protocol +http+] +# +# - Linked: http://yahoo.com links to http://yahoo.com. +# +# [Protocol +https+] +# +# - Linked: https://github.com links to https://github.com. +# +# [Protocol +ftp+] +# +# - Linked: ftp://nosuch.site links to ftp://nosuch.site. +# +# [Protocol +mailto+] +# +# - Linked: mailto:/foo@bar.com links to mailto://foo@bar.com. +# +# [Protocol +irc+] +# +# - link: irc://irc.freenode.net/ruby links to irc://irc.freenode.net/ruby. +# +# [Image Filename Extensions] +# +# - Link: https://www.ruby-lang.org/images/header-ruby-logo@2x.png is +# converted to an in-line HTML +img+ tag, which displays the image in the HTML: +# +# https://www.ruby-lang.org/images/header-ruby-logo@2x.png +# +# Also works for +bmp+, +gif+, +jpeg+, and +jpg+ files. +# +# Note: Works only for a fully qualified URL. +# +# [Heading] +# +# - Link: RDoc::RD@LICENSE links to RDoc::RDoc::RD@LICENSE. +# +# Note that spaces in the actual heading are represented by + characters +# in the linkable text. +# +# - Link: RDoc::Options@Saved+Options +# links to RDoc::Options@Saved+Options. +# +# Punctuation and other special characters must be escaped like CGI.escape. +# +# Pro tip: The link to any heading is available in the alphabetical table of contents +# at the top left of the page for the class or module. +# +# [Section] +# +# See {Directives for Organizing Documentation}[#class-RDoc::MarkupReference-label-Directives+for+Organizing+Documentation]. +# +# - Link: RDoc::Markup::ToHtml@Visitor links to RDoc::Markup::ToHtml@Visitor. +# +# If a section and a heading share the same name, the link target is the section. +# +# [Single-Word Text Link] +# +# Use square brackets to create single-word text link: +# +# - GitHub[https://github.com] links to GitHub[https://github.com]. +# +# [Multi-Word Text Link] +# +# Use square brackets and curly braces to create a multi-word text link. +# +# - {GitHub home page}[https://github.com] links to +# {GitHub home page}[https://github.com]. +# +# [rdoc-ref Scheme] +# +# A link with the rdoc-ref: scheme links to the referenced item, +# if that item exists. +# The referenced item may be a class, module, method, file, etc. +# +# - Class: Alias[rdoc-ref:RDoc::Alias] generates Alias[rdoc-ref:RDoc::Alias]. +# - Module: RDoc[rdoc-ref:RDoc] generates RDoc[rdoc-ref:RDoc]. +# - Method: foo[rdoc-ref:RDoc::MarkupReference#dummy_instance_method] +# generates foo[rdoc-ref:RDoc::MarkupReference#dummy_instance_method]. +# - Constant: bar[rdoc-ref:RDoc::MarkupReference::DUMMY_CONSTANT] +# generates bar[rdoc-ref:RDoc::MarkupReference::DUMMY_CONSTANT]. +# - Attribute: baz[rdoc-ref:RDoc::MarkupReference#dummy_attribute] +# generates baz[rdoc-ref:RDoc::MarkupReference#dummy_attribute]. +# - Alias: bad[rdoc-ref:RDoc::MarkupReference#dummy_instance_alias] +# generates bad[rdoc-ref:RDoc::MarkupReference#dummy_instance_alias]. +# +# If the referenced item does not exist, no link is generated +# and entire rdoc-ref: square-bracketed clause is removed +# from the resulting text. +# +# - Nosuch[rdoc-ref:RDoc::Nosuch] generates Nosuch. +# +# +# [rdoc-label Scheme] +# +# [Simple] +# +# You can specify a link target using this form, +# where the second part cites the id of an HTML element. +# +# This link refers to the constant +DUMMY_CONSTANT+ on this page: +# +# - {DUMMY_CONSTANT}[rdoc-label:DUMMY_CONSTANT] +# +# Thus: +# +# {DUMMY_CONSTANT}[rdoc-label:DUMMY_CONSTANT] +# +# [With Return] +# +# You can specify both a link target and a local label +# that can be used as the target for a return link. +# These two links refer to each other: +# +# - {go to addressee}[rdoc-label:addressee:sender] +# - {return to sender}[rdoc-label:sender:addressee] +# +# Thus: +# +# {go to addressee}[rdoc-label:addressee:sender] +# +# Some text. +# +# {return to sender}[rdoc-label:sender:addressee] +# +# [link: Scheme] +# +# - link:README_rdoc.html links to link:README_rdoc.html. +# +# [rdoc-image Scheme] +# +# Use the rdoc-image scheme to display an image that is also a link: +# +# # {rdoc-image:path/to/image}[link_target] +# +# - Link: {rdoc-image:https://www.ruby-lang.org/images/header-ruby-logo@2x.png}[https://www.ruby-lang.org] +# displays image https://www.ruby-lang.org/images/header-ruby-logo@2x.png +# as a link to https://www.ruby-lang.org. +# +# {rdoc-image:https://www.ruby-lang.org/images/header-ruby-logo@2x.png}[https://www.ruby-lang.org] +# +# A relative path as the target also works: +# +# - Link: {rdoc-image:https://www.ruby-lang.org/images/header-ruby-logo@2x.png}[./Alias.html] links to ./Alias.html +# +# {rdoc-image:https://www.ruby-lang.org/images/header-ruby-logo@2x.png}[./Alias.html] +# +# === Escaping Text +# +# Text that would otherwise be interpreted as markup +# can be "escaped," so that it is not interpreted as markup; +# the escape character is the backslash ('\\'). +# +# In a verbatim text block or a code block, +# the escape character is always preserved: +# +# Example input: +# +# This is not verbatim text. +# +# This is verbatim text, with an escape character \. +# +# This is not a code block. +# +# def foo +# 'String with an escape character.' +# end +# +# Rendered HTML: +# +# >>> +# This is not verbatim text. +# +# This is verbatim text, with an escape character \. +# +# This is not a code block. +# +# def foo +# 'This is a code block with an escape character \.' +# end +# +# In typeface markup (italic, bold, or monofont), +# an escape character is preserved unless it is immediately +# followed by nested typeface markup. +# +# Example input: +# +# This list is about escapes; it contains: +# +# - Monofont text with unescaped nested _italic_. +# - Monofont text with escaped nested \_italic_. +# - Monofont text with an escape character \. +# +# Rendered HTML: +# +# >>> +# This list is about escapes; it contains: +# +# - Monofont text with unescaped nested _italic_. +# - Monofont text with escaped nested \_italic_. +# - Monofont text with an escape character \ . +# +# In other text-bearing blocks +# (paragraphs, block quotes, list items, headings): +# +# - A single escape character immediately followed by markup +# escapes the markup. +# - A single escape character followed by whitespace is preserved. +# - A single escape character anywhere else is ignored. +# - A double escape character is rendered as a single backslash. +# +# Example input: +# +# This list is about escapes; it contains: +# +# - An unescaped class name, RDoc, that will become a link. +# - An escaped class name, \RDoc, that will not become a link. +# - An escape character followed by whitespace \ . +# - An escape character \that is ignored. +# - A double escape character \\ that is rendered +# as a single backslash. +# +# Rendered HTML: +# +# >>> +# This list is about escapes; it contains: +# +# - An unescaped class name, RDoc, that will become a link. +# - An escaped class name, \RDoc, that will not become a link. +# - An escape character followed by whitespace \ . +# - An escape character \that is ignored. +# - A double escape character \\ that is rendered +# as a single backslash. +# +# == Documentation Derived from Ruby Code +# +# [Class] +# +# By default, \RDoc documents: +# +# - \Class name. +# - Parent class. +# - Singleton methods. +# - Instance methods. +# - Aliases. +# - Constants. +# - Attributes. +# +# [Module] +# +# By default, \RDoc documents: +# +# - \Module name. +# - \Singleton methods. +# - Instance methods. +# - Aliases. +# - Constants. +# - Attributes. +# +# [Method] +# +# By default, \RDoc documents: +# +# - \Method name. +# - Arguments. +# - Yielded values. +# +# See #method. +# +# [Alias] +# +# By default, \RDoc documents: +# +# - Alias name. +# - Aliased name. +# +# See #dummy_instance_alias and #dummy_instance_method. +# +# [Constant] +# +# By default, \RDoc documents: +# +# - \Constant name. +# +# See DUMMY_CONSTANT. +# +# [Attribute] +# +# By default, \RDoc documents: +# +# - Attribute name. +# - Attribute type ([R], [W], or [RW]) +# +# See #dummy_attribute. +# +class RDoc::MarkupReference + + # Example class. + class DummyClass; end + + # Example module. + module DummyModule; end + + # Example singleton method. + def self.dummy_singleton_method(foo, bar); end + + # Example instance method. + def dummy_instance_method(foo, bar); end; + + alias dummy_instance_alias dummy_instance_method + + # Example attribute. + attr_accessor :dummy_attribute + + alias dummy_attribute_alias dummy_attribute + + # Example constant. + DUMMY_CONSTANT = '' + + # :call-seq: + # call_seq_directive(foo, bar) + # Can be anything -> bar + # Also anything more -> baz or bat + # + # The :call-seq: directive overrides the actual calling sequence + # found in the Ruby code. + # + # - It can specify anything at all. + # - It can have multiple calling sequences. + # + # This one includes Can be anything -> foo, which is nonsense. + # + # Note that the "arrow" is two characters, hyphen and right angle-bracket, + # which is made into a single character in the HTML. + # + # Click on the calling sequence to see the code. + # + # Here is the :call-seq: directive given for the method: + # + # :call-seq: + # call_seq_directive(foo, bar) + # Can be anything -> bar + # Also anything more -> baz or bat + # + def call_seq_directive + nil + end + + # The :args: directive overrides the actual arguments found in the Ruby code. + # + # Click on the calling sequence to see the code. + # + def args_directive(foo, bar) # :args: baz + nil + end + + # The :yields: directive overrides the actual yield found in the Ruby code. + # + # Click on the calling sequence to see the code. + # + def yields_directive(foo, bar) # :yields: 'bat' + yield 'baz' + end + + # This method is documented only by \RDoc, except for these comments. + # + # Click on the calling sequence to see the code. + # + def method(foo, bar) + yield 'baz' + end + +end diff --git a/bin/rdoc b/exe/rdoc similarity index 99% rename from bin/rdoc rename to exe/rdoc index aaa23292df..95b6eea277 100755 --- a/bin/rdoc +++ b/exe/rdoc @@ -41,4 +41,3 @@ rescue Exception => e exit 1 end - diff --git a/bin/ri b/exe/ri similarity index 100% rename from bin/ri rename to exe/ri diff --git a/lib/gauntlet_rdoc.rb b/lib/gauntlet_rdoc.rb deleted file mode 100644 index 16665da770..0000000000 --- a/lib/gauntlet_rdoc.rb +++ /dev/null @@ -1,84 +0,0 @@ -require 'rubygems' -Gem.load_yaml -require 'rdoc' -require 'gauntlet' -require 'fileutils' - -## -# Allows for testing of RDoc against every gem - -class RDoc::Gauntlet < Gauntlet - - def initialize # :nodoc: - super - - @args = nil - @type = nil - end - - ## - # Runs an RDoc generator for gem +name+ - - def run name - return if self.data.key? name - - dir = File.expand_path "~/.gauntlet/data/#{@type}/#{name}" - FileUtils.rm_rf dir if File.exist? dir - - yaml = File.read 'gemspec' - begin - spec = Gem::Specification.from_yaml yaml - rescue Psych::SyntaxError - puts "bad spec #{name}" - self.data[name] = false - return - end - - args = @args.dup - args << '--op' << dir - args.concat spec.rdoc_options - args << spec.require_paths - args << spec.extra_rdoc_files - args = args.flatten.map { |a| a.to_s } - args.delete '--quiet' - - puts "#{name} - rdoc #{args.join ' '}" - - self.dirty = true - r = RDoc::RDoc.new - - begin - r.document args - self.data[name] = true - puts 'passed' - FileUtils.rm_rf dir - rescue Interrupt, StandardError, RDoc::Error, SystemStackError => e - puts "failed - (#{e.class}) #{e.message}" - self.data[name] = false - end - rescue Gem::Exception - puts "bad gem #{name}" - ensure - puts - end - - ## - # Runs the gauntlet with the given +type+ (rdoc or ri) and +filter+ for - # which gems to run - - def run_the_gauntlet type = 'rdoc', filter = nil - @type = type || 'rdoc' - @args = type == 'rdoc' ? [] : %w[--ri] - @data_file = "#{DATADIR}/#{@type}-data.yml" - - super filter - end - -end - -type = ARGV.shift -filter = ARGV.shift -filter = /#{filter}/ if filter - -RDoc::Gauntlet.new.run_the_gauntlet type, filter - diff --git a/lib/rdoc.rb b/lib/rdoc.rb index be917e3bae..b42059c712 100644 --- a/lib/rdoc.rb +++ b/lib/rdoc.rb @@ -1,7 +1,6 @@ +# frozen_string_literal: true $DEBUG_RDOC = nil -# :main: README.rdoc - ## # RDoc produces documentation for Ruby source files by parsing the source and # extracting the definition for classes, modules, methods, includes and @@ -20,7 +19,7 @@ # see RDoc::Markup and refer to rdoc --help for command line usage. # # If you want to set the default markup format see -# RDoc::Markup@Supported+Formats +# RDoc::Markup@Markup+Formats # # If you want to store rdoc configuration in your gem (such as the default # markup format) see RDoc::Options@Saved+Options @@ -61,10 +60,7 @@ module RDoc class Error < RuntimeError; end - ## - # RDoc version you are using - - VERSION = '4.3.0' + require_relative 'rdoc/version' ## # Method visibilities @@ -122,65 +118,94 @@ def self.load_yaml end end - autoload :RDoc, 'rdoc/rdoc' + ## + # Searches and returns the directory for settings. + # + # 1. $HOME/.rdoc directory, if it exists. + # 2. The +rdoc+ directory under the path specified by the + # +XDG_DATA_HOME+ environment variable, if it is set. + # 3. $HOME/.local/share/rdoc directory. + # + # Other than the home directory, the containing directory will be + # created automatically. + + def self.home + rdoc_dir = begin + File.expand_path('~/.rdoc') + rescue ArgumentError + end + + if File.directory?(rdoc_dir) + rdoc_dir + else + require 'fileutils' + begin + # XDG + xdg_data_home = ENV["XDG_DATA_HOME"] || File.join(File.expand_path("~"), '.local', 'share') + unless File.exist?(xdg_data_home) + FileUtils.mkdir_p xdg_data_home + end + File.join xdg_data_home, "rdoc" + rescue Errno::EACCES + end + end + end - autoload :TestCase, 'rdoc/test_case' + autoload :RDoc, "#{__dir__}/rdoc/rdoc" - autoload :CrossReference, 'rdoc/cross_reference' - autoload :ERBIO, 'rdoc/erbio' - autoload :ERBPartial, 'rdoc/erb_partial' - autoload :Encoding, 'rdoc/encoding' - autoload :Generator, 'rdoc/generator' - autoload :Options, 'rdoc/options' - autoload :Parser, 'rdoc/parser' - autoload :Servlet, 'rdoc/servlet' - autoload :RI, 'rdoc/ri' - autoload :Stats, 'rdoc/stats' - autoload :Store, 'rdoc/store' - autoload :Task, 'rdoc/task' - autoload :Text, 'rdoc/text' + autoload :CrossReference, "#{__dir__}/rdoc/cross_reference" + autoload :ERBIO, "#{__dir__}/rdoc/erbio" + autoload :ERBPartial, "#{__dir__}/rdoc/erb_partial" + autoload :Encoding, "#{__dir__}/rdoc/encoding" + autoload :Generator, "#{__dir__}/rdoc/generator" + autoload :Options, "#{__dir__}/rdoc/options" + autoload :Parser, "#{__dir__}/rdoc/parser" + autoload :Servlet, "#{__dir__}/rdoc/servlet" + autoload :RI, "#{__dir__}/rdoc/ri" + autoload :Stats, "#{__dir__}/rdoc/stats" + autoload :Store, "#{__dir__}/rdoc/store" + autoload :Task, "#{__dir__}/rdoc/task" + autoload :Text, "#{__dir__}/rdoc/text" - autoload :Markdown, 'rdoc/markdown' - autoload :Markup, 'rdoc/markup' - autoload :RD, 'rdoc/rd' - autoload :TomDoc, 'rdoc/tom_doc' + autoload :Markdown, "#{__dir__}/rdoc/markdown" + autoload :Markup, "#{__dir__}/rdoc/markup" + autoload :RD, "#{__dir__}/rdoc/rd" + autoload :TomDoc, "#{__dir__}/rdoc/tom_doc" - autoload :KNOWN_CLASSES, 'rdoc/known_classes' + autoload :KNOWN_CLASSES, "#{__dir__}/rdoc/known_classes" - autoload :RubyLex, 'rdoc/ruby_lex' - autoload :RubyToken, 'rdoc/ruby_token' - autoload :TokenStream, 'rdoc/token_stream' + autoload :TokenStream, "#{__dir__}/rdoc/token_stream" - autoload :Comment, 'rdoc/comment' + autoload :Comment, "#{__dir__}/rdoc/comment" - autoload :I18n, 'rdoc/i18n' + require_relative 'rdoc/i18n' # code objects # # We represent the various high-level code constructs that appear in Ruby # programs: classes, modules, methods, and so on. - autoload :CodeObject, 'rdoc/code_object' - - autoload :Context, 'rdoc/context' - autoload :TopLevel, 'rdoc/top_level' - - autoload :AnonClass, 'rdoc/anon_class' - autoload :ClassModule, 'rdoc/class_module' - autoload :NormalClass, 'rdoc/normal_class' - autoload :NormalModule, 'rdoc/normal_module' - autoload :SingleClass, 'rdoc/single_class' - - autoload :Alias, 'rdoc/alias' - autoload :AnyMethod, 'rdoc/any_method' - autoload :MethodAttr, 'rdoc/method_attr' - autoload :GhostMethod, 'rdoc/ghost_method' - autoload :MetaMethod, 'rdoc/meta_method' - autoload :Attr, 'rdoc/attr' - - autoload :Constant, 'rdoc/constant' - autoload :Mixin, 'rdoc/mixin' - autoload :Include, 'rdoc/include' - autoload :Extend, 'rdoc/extend' - autoload :Require, 'rdoc/require' + autoload :CodeObject, "#{__dir__}/rdoc/code_object" + + autoload :Context, "#{__dir__}/rdoc/code_object/context" + autoload :TopLevel, "#{__dir__}/rdoc/code_object/top_level" + + autoload :AnonClass, "#{__dir__}/rdoc/code_object/anon_class" + autoload :ClassModule, "#{__dir__}/rdoc/code_object/class_module" + autoload :NormalClass, "#{__dir__}/rdoc/code_object/normal_class" + autoload :NormalModule, "#{__dir__}/rdoc/code_object/normal_module" + autoload :SingleClass, "#{__dir__}/rdoc/code_object/single_class" + + autoload :Alias, "#{__dir__}/rdoc/code_object/alias" + autoload :AnyMethod, "#{__dir__}/rdoc/code_object/any_method" + autoload :MethodAttr, "#{__dir__}/rdoc/code_object/method_attr" + autoload :GhostMethod, "#{__dir__}/rdoc/code_object/ghost_method" + autoload :MetaMethod, "#{__dir__}/rdoc/code_object/meta_method" + autoload :Attr, "#{__dir__}/rdoc/code_object/attr" + + autoload :Constant, "#{__dir__}/rdoc/code_object/constant" + autoload :Mixin, "#{__dir__}/rdoc/code_object/mixin" + autoload :Include, "#{__dir__}/rdoc/code_object/include" + autoload :Extend, "#{__dir__}/rdoc/code_object/extend" + autoload :Require, "#{__dir__}/rdoc/code_object/require" end diff --git a/lib/rdoc/code_object.rb b/lib/rdoc/code_object.rb index 4620fa586d..388863b06c 100644 --- a/lib/rdoc/code_object.rb +++ b/lib/rdoc/code_object.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # Base class for the RDoc code tree. # @@ -20,9 +21,10 @@ # * RDoc::MetaMethod # * RDoc::Alias # * RDoc::Constant +# * RDoc::Require # * RDoc::Mixin -# * RDoc::Require # * RDoc::Include +# * RDoc::Extend class RDoc::CodeObject @@ -68,13 +70,6 @@ class RDoc::CodeObject attr_reader :metadata - ## - # Offset in #file where this CodeObject was defined - #-- - # TODO character or byte? - - attr_accessor :offset - ## # Sets the parent CodeObject @@ -96,11 +91,9 @@ class RDoc::CodeObject attr_reader :store ## - # We are the model of the code, but we know that at some point we will be - # worked on by viewers. By implementing the Viewable protocol, viewers can - # associated themselves with these objects. + # When mixed-in to a class, this points to the Context in which it was originally defined. - attr_accessor :viewer + attr_accessor :mixin_from ## # Creates a new CodeObject that will document itself and its children @@ -117,6 +110,7 @@ def initialize @full_name = nil @store = nil @track_visibility = true + @mixin_from = nil initialize_visibility end @@ -141,7 +135,6 @@ def initialize_visibility # :nodoc: def comment=(comment) @comment = case comment when NilClass then '' - when RDoc::Markup::Document then comment when RDoc::Comment then comment.normalize else if comment and not comment.empty? then @@ -149,9 +142,8 @@ def comment=(comment) else # HACK correct fix is to have #initialize create @comment # with the correct encoding - if String === @comment and - Object.const_defined? :Encoding and @comment.empty? then - @comment.force_encoding comment.encoding + if String === @comment and @comment.empty? then + @comment = RDoc::Encoding.change_encoding @comment, comment.encoding end @comment end @@ -218,20 +210,6 @@ def done_documenting=(value) @document_children = @document_self end - ## - # Yields each parent of this CodeObject. See also - # RDoc::ClassModule#each_ancestor - - def each_parent - code_object = self - - while code_object = code_object.parent do - yield code_object - end - - self - end - ## # File name where this CodeObject was found. # @@ -258,7 +236,7 @@ def force_documentation=(value) # # Set to +nil+ to clear RDoc's cached value - def full_name= full_name + def full_name=(full_name) @full_name = full_name end @@ -302,11 +280,7 @@ def ignored? # This is used by Text#snippet def options - if @store and @store.rdoc then - @store.rdoc.options - else - RDoc::Options.new - end + @store&.options || RDoc::Options.new end ## @@ -332,13 +306,6 @@ def parent end end - ## - # File name of our parent - - def parent_file_name - @parent ? @parent.base_name : '(unknown)' - end - ## # Name of our parent @@ -349,7 +316,7 @@ def parent_name ## # Records the RDoc::TopLevel (file) where this code object was defined - def record_location top_level + def record_location(top_level) @ignored = false @suppressed = false @file = top_level @@ -391,7 +358,7 @@ def stop_doc ## # Sets the +store+ that contains this CodeObject - def store= store + def store=(store) @store = store return unless @track_visibility @@ -426,4 +393,3 @@ def suppressed? end end - diff --git a/lib/rdoc/alias.rb b/lib/rdoc/code_object/alias.rb similarity index 86% rename from lib/rdoc/alias.rb rename to lib/rdoc/code_object/alias.rb index 39d2694817..bd5b3ec6b5 100644 --- a/lib/rdoc/alias.rb +++ b/lib/rdoc/code_object/alias.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # Represent an alias, which is an old_name/new_name pair associated with a # particular context @@ -22,7 +23,7 @@ class RDoc::Alias < RDoc::CodeObject ## # Is this an alias declared in a singleton context? - attr_accessor :singleton + attr_reader :singleton ## # Source file token stream @@ -33,7 +34,7 @@ class RDoc::Alias < RDoc::CodeObject # Creates a new Alias with a token stream of +text+ that aliases +old_name+ # to +new_name+, has +comment+ and is a +singleton+ context. - def initialize(text, old_name, new_name, comment, singleton = false) + def initialize(text, old_name, new_name, comment, singleton: false) super() @text = text @@ -58,18 +59,11 @@ def aref "#alias-#{type}-#{html_name}" end - ## - # Full old name including namespace - - def full_old_name - @full_name || "#{parent.name}#{pretty_old_name}" - end - ## # HTML id-friendly version of +#new_name+. def html_name - CGI.escape(@new_name.gsub('-', '-2D')).gsub('%','-').sub(/^-/, '') + CGI.escape(@new_name.gsub('-', '-2D')).gsub('%', '-').sub(/^-/, '') end def inspect # :nodoc: @@ -108,4 +102,3 @@ def to_s # :nodoc: end end - diff --git a/lib/rdoc/anon_class.rb b/lib/rdoc/code_object/anon_class.rb similarity index 82% rename from lib/rdoc/anon_class.rb rename to lib/rdoc/code_object/anon_class.rb index c23d8e5d96..3c2f0e1877 100644 --- a/lib/rdoc/anon_class.rb +++ b/lib/rdoc/code_object/anon_class.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # An anonymous class like: # @@ -7,4 +8,3 @@ class RDoc::AnonClass < RDoc::ClassModule end - diff --git a/lib/rdoc/any_method.rb b/lib/rdoc/code_object/any_method.rb similarity index 72% rename from lib/rdoc/any_method.rb rename to lib/rdoc/code_object/any_method.rb index ae022d72f8..b319f0d0dd 100644 --- a/lib/rdoc/any_method.rb +++ b/lib/rdoc/code_object/any_method.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # AnyMethod is the base class for objects representing methods @@ -25,15 +26,8 @@ class RDoc::AnyMethod < RDoc::MethodAttr attr_accessor :c_function - ## - # Different ways to call this method - - attr_reader :call_seq - - ## - # Parameters for this method - - attr_accessor :params + # The section title of the method (if defined in a C file via +:category:+) + attr_accessor :section_title ## # If true this method uses +super+ to call a superclass version @@ -45,8 +39,8 @@ class RDoc::AnyMethod < RDoc::MethodAttr ## # Creates a new AnyMethod with a token stream +text+ and +name+ - def initialize text, name - super + def initialize(text, name, singleton: false) + super(text, name, singleton: singleton) @c_function = nil @dont_rename_initialize = false @@ -58,11 +52,10 @@ def initialize text, name ## # Adds +an_alias+ as an alias for this method in +context+. - def add_alias an_alias, context = nil - method = self.class.new an_alias.text, an_alias.new_name + def add_alias(an_alias, context = nil) + method = self.class.new an_alias.text, an_alias.new_name, singleton: singleton method.record_location an_alias.file - method.singleton = self.singleton method.params = self.params method.visibility = self.visibility method.comment = an_alias.comment @@ -92,18 +85,38 @@ def arglists end end + ## + # Different ways to call this method + + def call_seq + unless call_seq = _call_seq + call_seq = is_alias_for._call_seq if is_alias_for + end + + return unless call_seq + + deduplicate_call_seq(call_seq) + end + ## # Sets the different ways you can call this method. If an empty +call_seq+ # is given nil is assumed. # # See also #param_seq - def call_seq= call_seq - return if call_seq.empty? + def call_seq=(call_seq) + return if call_seq.nil? || call_seq.empty? @call_seq = call_seq end + ## + # Whether the method has a call-seq. + + def has_call_seq? + !!(@call_seq || is_alias_for&._call_seq) + end + ## # Loads is_alias_for from the internal name. Returns nil if the alias # cannot be found. @@ -163,7 +176,7 @@ def marshal_dump # * #full_name # * #parent_name - def marshal_load array + def marshal_load(array) initialize_visibility @dont_rename_initialize = nil @@ -180,7 +193,7 @@ def marshal_load array @full_name = array[2] @singleton = array[3] @visibility = array[4] - @comment = array[5] + @comment = RDoc::Comment.from_document array[5] @call_seq = array[6] @block_params = array[7] # 8 handled below @@ -192,8 +205,8 @@ def marshal_load array @section_title = array[14] @is_alias_for = array[15] - array[8].each do |new_name, comment| - add_alias RDoc::Alias.new(nil, @name, new_name, comment, @singleton) + array[8].each do |new_name, document| + add_alias RDoc::Alias.new(nil, @name, new_name, RDoc::Comment.from_document(document), singleton: @singleton) end @parent_name ||= if @full_name =~ /#/ then @@ -243,9 +256,9 @@ def param_list if @block_params then # If this method has explicit block parameters, remove any explicit # &block - params.sub!(/,?\s*&\w+/, '') + params = params.sub(/,?\s*&\w+/, '') else - params.sub!(/\&(\w+)/, '\1') + params = params.sub(/\&(\w+)/, '\1') end params = params.gsub(/\s+/, '').split(',').reject(&:empty?) @@ -264,7 +277,7 @@ def param_seq params = params.sub(/(\|[^|]+\|)\s*\.\.\.\s*(end|\})/, '\1 \2') elsif @params then params = @params.gsub(/\s*\#.*/, '') - params = params.tr("\n", " ").squeeze(" ") + params = params.tr_s("\n ", " ") params = "(#{params})" unless params[0] == ?( else params = '' @@ -273,12 +286,11 @@ def param_seq if @block_params then # If this method has explicit block parameters, remove any explicit # &block - params.sub!(/,?\s*&\w+/, '') + params = params.sub(/,?\s*&\w+/, '') - block = @block_params.gsub(/\s*\#.*/, '') - block = block.tr("\n", " ").squeeze(" ") + block = @block_params.tr_s("\n ", " ") if block[0] == ?( - block.sub!(/^\(/, '').sub!(/\)/, '') + block = block.sub(/^\(/, '').sub(/\)/, '') end params << " { |#{block}| ... }" end @@ -286,10 +298,18 @@ def param_seq params end + ## + # Whether to skip the method description, true for methods that have + # aliases with a call-seq that doesn't include the method name. + + def skip_description? + has_call_seq? && call_seq.nil? && !!(is_alias_for || !aliases.empty?) + end + ## # Sets the store for this method and its referenced code objects. - def store= store + def store=(store) super @file = @store.add_file @file.full_name if @file @@ -312,5 +332,43 @@ def superclass_method @superclass_method end -end + protected + + ## + # call_seq without deduplication and alias lookup. + + def _call_seq + @call_seq if defined?(@call_seq) && @call_seq + end + + private + + ## + # call_seq with alias examples information removed, if this + # method is an alias method. + + def deduplicate_call_seq(call_seq) + return call_seq unless is_alias_for || !aliases.empty? + + method_name = self.name + method_name = method_name[0, 1] if method_name =~ /\A\[/ + + entries = call_seq.split "\n" + + ignore = aliases.map(&:name) + if is_alias_for + ignore << is_alias_for.name + ignore.concat is_alias_for.aliases.map(&:name) + end + ignore.map! { |n| n =~ /\A\[/ ? /\[.*\]/ : n} + ignore.delete(method_name) + ignore = Regexp.union(ignore) + + matching = entries.reject do |entry| + entry =~ /^\w*\.?#{ignore}[$\(\s]/ or + entry =~ /\s#{ignore}\s/ + end + matching.empty? ? nil : matching.join("\n") + end +end diff --git a/lib/rdoc/attr.rb b/lib/rdoc/code_object/attr.rb similarity index 90% rename from lib/rdoc/attr.rb rename to lib/rdoc/code_object/attr.rb index 960e1d1107..969b18346d 100644 --- a/lib/rdoc/attr.rb +++ b/lib/rdoc/code_object/attr.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # An attribute created by \#attr, \#attr_reader, \#attr_writer or # \#attr_accessor @@ -21,18 +22,17 @@ class RDoc::Attr < RDoc::MethodAttr # Creates a new Attr with body +text+, +name+, read/write status +rw+ and # +comment+. +singleton+ marks this as a class attribute. - def initialize(text, name, rw, comment, singleton = false) - super text, name + def initialize(text, name, rw, comment, singleton: false) + super(text, name, singleton: singleton) @rw = rw - @singleton = singleton self.comment = comment end ## # Attributes are equal when their names, singleton and rw are identical - def == other + def ==(other) self.class == other.class and self.name == other.name and self.rw == other.rw and @@ -43,9 +43,7 @@ def == other # Add +an_alias+ as an attribute in +context+. def add_alias(an_alias, context) - new_attr = self.class.new(self.text, an_alias.new_name, self.rw, - self.comment, self.singleton) - + new_attr = self.class.new(text, an_alias.new_name, rw, comment, singleton: singleton) new_attr.record_location an_alias.file new_attr.visibility = self.visibility new_attr.is_alias_for = self @@ -120,7 +118,7 @@ def marshal_dump # * #full_name # * #parent_name - def marshal_load array + def marshal_load(array) initialize_visibility @aliases = [] @@ -135,7 +133,7 @@ def marshal_load array @full_name = array[2] @rw = array[3] @visibility = array[4] - @comment = array[5] + @comment = RDoc::Comment.from_document array[5] @singleton = array[6] || false # MARSHAL_VERSION == 0 # 7 handled below @parent_name = array[8] @@ -147,7 +145,7 @@ def marshal_load array @parent_name ||= @full_name.split('#', 2).first end - def pretty_print q # :nodoc: + def pretty_print(q) # :nodoc: q.group 2, "[#{self.class.name} #{full_name} #{rw} #{visibility}", "]" do unless comment.empty? then q.breakable @@ -172,4 +170,3 @@ def token_stream # :nodoc: end end - diff --git a/lib/rdoc/class_module.rb b/lib/rdoc/code_object/class_module.rb similarity index 81% rename from lib/rdoc/class_module.rb rename to lib/rdoc/code_object/class_module.rb index 71566f050a..f6b0abb2f5 100644 --- a/lib/rdoc/class_module.rb +++ b/lib/rdoc/code_object/class_module.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # ClassModule is the base class for objects representing either a class or a # module. @@ -33,8 +34,6 @@ class RDoc::ClassModule < RDoc::Context attr_accessor :comment_location - attr_accessor :diagram # :nodoc: - ## # Class or module this constant is an alias for @@ -46,7 +45,7 @@ class RDoc::ClassModule < RDoc::Context #-- # TODO move to RDoc::NormalClass (I think) - def self.from_module class_type, mod + def self.from_module(class_type, mod) klass = class_type.new mod.name mod.comment_location.each do |comment, location| @@ -55,7 +54,6 @@ def self.from_module class_type, mod klass.parent = mod.parent klass.section = mod.section - klass.viewer = mod.viewer klass.attributes.concat mod.attributes klass.method_list.concat mod.method_list @@ -109,7 +107,6 @@ def self.from_module class_type, mod def initialize(name, superclass = nil) @constant_aliases = [] - @diagram = nil @is_alias_for = nil @name = name @superclass = superclass @@ -123,7 +120,7 @@ def initialize(name, superclass = nil) # method is preferred over #comment= since it allows ri data to be updated # across multiple runs. - def add_comment comment, location + def add_comment(comment, location) return unless document_self original = comment @@ -135,14 +132,16 @@ def add_comment comment, location normalize_comment comment end - @comment_location.delete_if { |(_, l)| l == location } + if location.parser == RDoc::Parser::C + @comment_location.delete_if { |(_, l)| l == location } + end @comment_location << [comment, location] self.comment = original end - def add_things my_things, other_things # :nodoc: + def add_things(my_things, other_things) # :nodoc: other_things.each do |group, things| my_things[group].each { |thing| yield false, thing } if my_things.include? group @@ -199,7 +198,7 @@ def clear_comment # Appends +comment+ to the current comment, but separated by a rule. Works # more like +=. - def comment= comment # :nodoc: + def comment=(comment) # :nodoc: comment = case comment when RDoc::Comment then comment.normalize @@ -207,7 +206,7 @@ def comment= comment # :nodoc: normalize_comment comment end - comment = "#{@comment}\n---\n#{comment}" unless @comment.empty? + comment = "#{@comment.to_s}\n---\n#{comment.to_s}" unless @comment.empty? super comment end @@ -217,10 +216,12 @@ def comment= comment # :nodoc: # # See RDoc::Store#complete - def complete min_visibility + def complete(min_visibility) update_aliases remove_nodoc_children + embed_mixins update_includes + update_extends remove_invisible min_visibility end @@ -258,7 +259,7 @@ def each_ancestor # :yields: module ## # Looks for a symbol in the #ancestors. See Context#find_local_symbol. - def find_ancestor_local_symbol symbol + def find_ancestor_local_symbol(symbol) each_ancestor do |m| res = m.find_local_symbol(symbol) return res if res @@ -270,7 +271,7 @@ def find_ancestor_local_symbol symbol ## # Finds a class or module with +name+ in this namespace or its descendants - def find_class_named name + def find_class_named(name) return self if full_name == name return self if @name == name @@ -291,6 +292,25 @@ def full_name end end + ## + # Return array of full_name splitted by +::+. + + def nesting_namespaces + @namespaces ||= full_name.split("::").reject(&:empty?) + end + + ## + # Return array of fully qualified nesting namespaces. + # + # For example, if full_name is +A::B::C+, this method returns ["A", "A::B", "A::B::C"] + + def fully_qualified_nesting_namespaces + return nesting_namespaces if nesting_namespaces.length < 2 + @fqns ||= nesting_namespaces.inject([]) do |list, n| + list << (list.empty? ? n : "#{list.last}::#{n}") + end + end + ## # TODO: filter included items by #display? @@ -340,7 +360,7 @@ def marshal_dump # :nodoc: ] end - def marshal_load array # :nodoc: + def marshal_load(array) # :nodoc: initialize_visibility initialize_methods_etc @current_section = nil @@ -355,37 +375,39 @@ def marshal_load array # :nodoc: @name = array[1] @full_name = array[2] @superclass = array[3] - @comment = array[4] + document = array[4] - @comment_location = if RDoc::Markup::Document === @comment.parts.first then - @comment + @comment = RDoc::Comment.from_document document + + @comment_location = if RDoc::Markup::Document === document.parts.first then + document else - RDoc::Markup::Document.new @comment + RDoc::Markup::Document.new document end array[5].each do |name, rw, visibility, singleton, file| singleton ||= false visibility ||= :public - attr = RDoc::Attr.new nil, name, rw, nil, singleton + attr = RDoc::Attr.new nil, name, rw, nil, singleton: singleton add_attribute attr attr.visibility = visibility attr.record_location RDoc::TopLevel.new file end - array[6].each do |constant, comment, file| + array[6].each do |constant, document, file| case constant when RDoc::Constant then add_constant constant else - constant = add_constant RDoc::Constant.new(constant, nil, comment) + constant = add_constant RDoc::Constant.new(constant, nil, RDoc::Comment.from_document(document)) constant.record_location RDoc::TopLevel.new file end end - array[7].each do |name, comment, file| - incl = add_include RDoc::Include.new(name, comment) + array[7].each do |name, document, file| + incl = add_include RDoc::Include.new(name, RDoc::Comment.from_document(document)) incl.record_location RDoc::TopLevel.new file end @@ -394,16 +416,15 @@ def marshal_load array # :nodoc: @visibility = visibility methods.each do |name, file| - method = RDoc::AnyMethod.new nil, name - method.singleton = true if type == 'class' + method = RDoc::AnyMethod.new nil, name, singleton: type == 'class' method.record_location RDoc::TopLevel.new file add_method method end end end - array[9].each do |name, comment, file| - ext = add_extend RDoc::Extend.new(name, comment) + array[9].each do |name, document, file| + ext = add_extend RDoc::Extend.new(name, RDoc::Comment.from_document(document)) ext.record_location RDoc::TopLevel.new file end if array[9] # Support Marshal version 1 @@ -429,7 +450,7 @@ def marshal_load array # :nodoc: # # The data in +class_module+ is preferred over the receiver. - def merge class_module + def merge(class_module) @parent = class_module.parent @parent_name = class_module.parent_name @@ -440,7 +461,8 @@ def merge class_module document = document.merge other_document - @comment = @comment_location = document + @comment = RDoc::Comment.from_document(document) + @comment_location = document end cm = class_module @@ -513,7 +535,7 @@ def merge class_module # end # end - def merge_collections mine, other, other_files, &block # :nodoc: + def merge_collections(mine, other, other_files, &block) # :nodoc: my_things = mine. group_by { |thing| thing.file } other_things = other.group_by { |thing| thing.file } @@ -525,7 +547,7 @@ def merge_collections mine, other, other_files, &block # :nodoc: # Merges the comments in this ClassModule with the comments in the other # ClassModule +cm+. - def merge_sections cm # :nodoc: + def merge_sections(cm) # :nodoc: my_sections = sections.group_by { |section| section.title } other_sections = cm.sections.group_by { |section| section.title } @@ -573,7 +595,7 @@ def module? # # Used for modules and classes that are constant aliases. - def name= new_name + def name=(new_name) @name = new_name end @@ -581,7 +603,7 @@ def name= new_name # Parses +comment_location+ into an RDoc::Markup::Document composed of # multiple RDoc::Markup::Documents with their file set. - def parse comment_location + def parse(comment_location) case comment_location when String then super @@ -608,7 +630,9 @@ def parse comment_location # Path to this class or module for use with HTML generator output. def path - http_url @store.rdoc.generator.class_dir + prefix = options.class_module_path_prefix + return http_url unless prefix + File.join(prefix, http_url) end ## @@ -651,7 +675,7 @@ def remove_nodoc_children end end - def remove_things my_things, other_files # :nodoc: + def remove_things(my_things, other_files) # :nodoc: my_things.delete_if do |file, things| next false unless other_files.include? file @@ -681,7 +705,7 @@ def search_record ## # Sets the store for this class or module and its contained code objects. - def store= store + def store=(store) super @attributes .each do |attr| attr.store = store end @@ -701,10 +725,37 @@ def superclass ## # Set the superclass of this class to +superclass+ + # + # where +superclass+ is one of: + # + # - +nil+ + # - a String containing the full name of the superclass + # - the RDoc::ClassModule representing the superclass def superclass=(superclass) raise NoMethodError, "#{full_name} is a module" if module? - @superclass = superclass + case superclass + when RDoc::ClassModule + @superclass = superclass.full_name + when nil, String + @superclass = superclass + else + raise TypeError, "superclass must be a String or RDoc::ClassModule, not #{superclass.class}" + end + end + + ## + # Get all super classes of this class in an array. The last element might be + # a string if the name is unknown. + + def super_classes + result = [] + parent = self + while parent = parent.superclass + result << parent + return result if parent.is_a?(String) + end + result end def to_s # :nodoc: @@ -795,5 +846,43 @@ def update_extends extends.uniq! end -end + def embed_mixins + return unless options.embed_mixins + + includes.each do |include| + next if String === include.module + include.module.method_list.each do |code_object| + add_method(prepare_to_embed(code_object)) + end + include.module.constants.each do |code_object| + add_constant(prepare_to_embed(code_object)) + end + include.module.attributes.each do |code_object| + add_attribute(prepare_to_embed(code_object)) + end + end + extends.each do |ext| + next if String === ext.module + ext.module.method_list.each do |code_object| + add_method(prepare_to_embed(code_object, true)) + end + ext.module.attributes.each do |code_object| + add_attribute(prepare_to_embed(code_object, true)) + end + end + end + + private + + def prepare_to_embed(code_object, singleton=false) + code_object = code_object.dup + code_object.mixin_from = code_object.parent + code_object.singleton = true if singleton + set_current_section(code_object.section.title, code_object.section.comment) + # add_method and add_attribute will reassign self's visibility back to the method/attribute + # so we need to sync self's visibility with the object's to properly retain that information + self.visibility = code_object.visibility + code_object + end +end diff --git a/lib/rdoc/constant.rb b/lib/rdoc/code_object/constant.rb similarity index 92% rename from lib/rdoc/constant.rb rename to lib/rdoc/code_object/constant.rb index 97985cbf99..d5f54edb67 100644 --- a/lib/rdoc/constant.rb +++ b/lib/rdoc/code_object/constant.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # A constant @@ -35,7 +36,7 @@ def initialize(name, value, comment) @value = value @is_alias_for = nil - @visibility = nil + @visibility = :public self.comment = comment end @@ -43,7 +44,7 @@ def initialize(name, value, comment) ## # Constants are ordered by name - def <=> other + def <=>(other) return unless self.class === other [parent_name, name] <=> [other.parent_name, other.name] @@ -52,7 +53,7 @@ def <=> other ## # Constants are equal when their #parent and #name is the same - def == other + def ==(other) self.class == other.class and @parent == other.parent and @name == other.name @@ -131,11 +132,11 @@ def marshal_dump # * #full_name # * #parent_name - def marshal_load array - initialize array[1], nil, array[5] + def marshal_load(array) + initialize array[1], nil, RDoc::Comment.from_document(array[5]) @full_name = array[2] - @visibility = array[3] + @visibility = array[3] || :public @is_alias_for = array[4] # 5 handled above # 6 handled below @@ -153,7 +154,7 @@ def path "#{@parent.path}##{@name}" end - def pretty_print q # :nodoc: + def pretty_print(q) # :nodoc: q.group 2, "[#{self.class.name} #{full_name}", "]" do unless comment.empty? then q.breakable @@ -167,7 +168,7 @@ def pretty_print q # :nodoc: ## # Sets the store for this class or module and its contained code objects. - def store= store + def store=(store) super @file = @store.add_file @file.full_name if @file @@ -183,4 +184,3 @@ def to_s # :nodoc: end end - diff --git a/lib/rdoc/context.rb b/lib/rdoc/code_object/context.rb similarity index 89% rename from lib/rdoc/context.rb rename to lib/rdoc/code_object/context.rb index 5eb86ddc92..3a4dd0ec68 100644 --- a/lib/rdoc/context.rb +++ b/lib/rdoc/code_object/context.rb @@ -1,5 +1,4 @@ -require 'cgi' - +# frozen_string_literal: true ## # A Context is something that can hold modules, classes, methods, attributes, # aliases, requires, and includes. Classes, modules, and files are all @@ -97,6 +96,11 @@ class RDoc::Context < RDoc::CodeObject attr_accessor :visibility + ## + # Current visibility of this line + + attr_writer :current_line_visibility + ## # Hash of registered methods. Attributes are also registered here, # twice if they are RW. @@ -147,6 +151,7 @@ def initialize_methods_etc @extends = [] @constants = [] @external_aliases = [] + @current_line_visibility = nil # This Hash maps a method name to a list of unmatched aliases (aliases of # a method not yet encountered). @@ -175,7 +180,7 @@ def <=>(other) # # Currently only RDoc::Extend and RDoc::Include are supported. - def add klass, name, comment + def add(klass, name, comment) if RDoc::Extend == klass then ext = RDoc::Extend.new name, comment add_extend ext @@ -190,7 +195,7 @@ def add klass, name, comment ## # Adds +an_alias+ that is automatically resolved - def add_alias an_alias + def add_alias(an_alias) return an_alias unless @document_self method_attr = find_method(an_alias.old_name, an_alias.singleton) || @@ -217,7 +222,7 @@ def add_alias an_alias # if method +foo+ exists, but attr_accessor :foo will be registered # if method +foo+ exists, but foo= does not. - def add_attribute attribute + def add_attribute(attribute) return attribute unless @document_self # mainly to check for redefinition of an attribute as a method @@ -232,7 +237,7 @@ def add_attribute attribute if known then known.comment = attribute.comment if known.comment.empty? - elsif registered = @methods_hash[attribute.pretty_name << '='] and + elsif registered = @methods_hash[attribute.pretty_name + '='] and RDoc::Attr === registered then registered.rw = 'RW' else @@ -242,7 +247,7 @@ def add_attribute attribute end if attribute.rw.index 'W' then - key = attribute.pretty_name << '=' + key = attribute.pretty_name + '=' known = @methods_hash[key] if known then @@ -280,7 +285,7 @@ def add_attribute attribute # unless it later sees class Container. +add_class+ automatically # upgrades +given_name+ to a class in this case. - def add_class class_type, given_name, superclass = '::Object' + def add_class(class_type, given_name, superclass = '::Object') # superclass +nil+ is passed by the C parser in the following cases: # - registering Object in 1.8 (correct) # - registering BasicObject in 1.9 (correct) @@ -326,7 +331,7 @@ def add_class class_type, given_name, superclass = '::Object' if full_name == 'BasicObject' then superclass = nil elsif full_name == 'Object' then - superclass = defined?(::BasicObject) ? '::BasicObject' : nil + superclass = '::BasicObject' end # find the superclass full name @@ -396,10 +401,11 @@ def add_class class_type, given_name, superclass = '::Object' # unless #done_documenting is +true+. Sets the #parent of +mod+ # to +self+, and its #section to #current_section. Returns +mod+. - def add_class_or_module mod, self_hash, all_hash + def add_class_or_module(mod, self_hash, all_hash) mod.section = current_section # TODO declaring context? something is # wrong here... mod.parent = self + mod.full_name = nil mod.store = @store unless @done_documenting then @@ -407,6 +413,10 @@ def add_class_or_module mod, self_hash, all_hash # this must be done AFTER adding mod to its parent, so that the full # name is correct: all_hash[mod.full_name] = mod + if @store.unmatched_constant_alias[mod.full_name] then + to, file = @store.unmatched_constant_alias[mod.full_name] + add_module_alias mod, mod.name, to, file + end end mod @@ -416,7 +426,7 @@ def add_class_or_module mod, self_hash, all_hash # Adds +constant+ if not already there. If it is, updates the comment, # value and/or is_alias_for of the known constant if they were empty/nil. - def add_constant constant + def add_constant(constant) return constant unless @document_self # HACK: avoid duplicate 'PI' & 'E' in math.c (1.8.7 source code) @@ -441,7 +451,7 @@ def add_constant constant ## # Adds included module +include+ which should be an RDoc::Include - def add_include include + def add_include(include) add_to @includes, include include @@ -450,7 +460,7 @@ def add_include include ## # Adds extension module +ext+ which should be an RDoc::Extend - def add_extend ext + def add_extend(ext) add_to @extends, ext ext @@ -460,7 +470,7 @@ def add_extend ext # Adds +method+ if not already there. If it is (as method or attribute), # updates the comment if it was empty. - def add_method method + def add_method(method) return method unless @document_self # HACK: avoid duplicate 'new' in io.c & struct.c (1.8.7 source code) @@ -472,12 +482,16 @@ def add_method method known.comment = method.comment if known.comment.empty? previously = ", previously in #{known.file}" unless method.file == known.file - @store.rdoc.options.warn \ + @store.options.warn \ "Duplicate method #{known.full_name} in #{method.file}#{previously}" end else @methods_hash[key] = method - method.visibility = @visibility + if @current_line_visibility + method.visibility, @current_line_visibility = @current_line_visibility, nil + else + method.visibility = @visibility + end add_to @method_list, method resolve_aliases method end @@ -499,41 +513,53 @@ def add_module(class_type, name) add_class_or_module mod, @modules, @store.modules_hash end + ## + # Adds a module by +RDoc::NormalModule+ instance. See also #add_module. + + def add_module_by_normal_module(mod) + add_class_or_module mod, @modules, @store.modules_hash + end + ## # Adds an alias from +from+ (a class or module) to +name+ which was defined # in +file+. - def add_module_alias from, name, file + def add_module_alias(from, from_name, to, file) return from if @done_documenting - to_name = child_name name + to_full_name = child_name to.name # if we already know this name, don't register an alias: # see the metaprogramming in lib/active_support/basic_object.rb, # where we already know BasicObject is a class when we find # BasicObject = BlankSlate - return from if @store.find_class_or_module to_name + return from if @store.find_class_or_module to_full_name + + unless from + @store.unmatched_constant_alias[child_name(from_name)] = [to, file] + return to + end - to = from.dup - to.name = name - to.full_name = nil + new_to = from.dup + new_to.name = to.name + new_to.full_name = nil - if to.module? then - @store.modules_hash[to_name] = to - @modules[name] = to + if new_to.module? then + @store.modules_hash[to_full_name] = new_to + @modules[to.name] = new_to else - @store.classes_hash[to_name] = to - @classes[name] = to + @store.classes_hash[to_full_name] = new_to + @classes[to.name] = new_to end # Registers a constant for this alias. The constant value and comment # will be updated later, when the Ruby parser adds the constant - const = RDoc::Constant.new name, nil, to.comment + const = RDoc::Constant.new to.name, nil, new_to.comment const.record_location file const.is_alias_for = from add_constant const - to + new_to end ## @@ -557,7 +583,7 @@ def add_require(require) # # See also RDoc::Context::Section - def add_section title, comment = nil + def add_section(title, comment = nil) if section = @sections[title] then section.add_comment comment if comment else @@ -571,7 +597,7 @@ def add_section title, comment = nil ## # Adds +thing+ to the collection +array+ - def add_to array, thing + def add_to(array, thing) array << thing if @document_self thing.parent = self @@ -603,7 +629,7 @@ def any_content(includes = true) ## # Creates the full name for a child with +name+ - def child_name name + def child_name(name) if name =~ /^:+/ $' #' elsif RDoc::TopLevel === self then @@ -662,13 +688,6 @@ def current_section section end - ## - # Is part of this thing was defined in +file+? - - def defined_in?(file) - @in_files.include?(file) - end - def display(method_attr) # :nodoc: if method_attr.is_a? RDoc::Attr "#{method_attr.definition} #{method_attr.pretty_name}" @@ -684,14 +703,7 @@ def display(method_attr) # :nodoc: # This method exists to make it easy to work with Context subclasses that # aren't part of RDoc. - def each_ancestor # :nodoc: - end - - ## - # Iterator for attributes - - def each_attribute # :yields: attribute - @attributes.each { |a| yield a } + def each_ancestor(&_) # :nodoc: end ## @@ -701,27 +713,6 @@ def each_classmodule(&block) # :yields: module classes_and_modules.sort.each(&block) end - ## - # Iterator for constants - - def each_constant # :yields: constant - @constants.each {|c| yield c} - end - - ## - # Iterator for included modules - - def each_include # :yields: include - @includes.each do |i| yield i end - end - - ## - # Iterator for extension modules - - def each_extend # :yields: extend - @extends.each do |e| yield e end - end - ## # Iterator for methods @@ -751,7 +742,7 @@ def each_section # :yields: section, constants, attributes attributes.default = [] sort_sections.each do |section| - yield section, constants[section].sort, attributes[section].sort + yield section, constants[section].select(&:display?).sort, attributes[section].select(&:display?).sort end end @@ -788,7 +779,9 @@ def find_class_method_named(name) # Finds a constant with +name+ in this context def find_constant_named(name) - @constants.find {|m| m.name == name} + @constants.find do |m| + m.name == name || m.full_name == name + end end ## @@ -819,13 +812,6 @@ def find_external_alias_named(name) end end - ## - # Finds a file with +name+ in this context - - def find_file_named name - @store.find_file_named name - end - ## # Finds an instance method with +name+ in this context @@ -843,14 +829,20 @@ def find_local_symbol(symbol) find_attribute_named(symbol) or find_external_alias_named(symbol) or find_module_named(symbol) or - find_file_named(symbol) + @store.find_file_named(symbol) end ## # Finds a method named +name+ with singleton value +singleton+. def find_method(name, singleton) - @method_list.find { |m| m.name == name && m.singleton == singleton } + @method_list.find { |m| + if m.singleton + m.name == name && m.singleton == singleton + else + m.name == name && !m.singleton && !singleton + end + } end ## @@ -939,10 +931,10 @@ def fully_documented? ## # URL for this with a +prefix+ - def http_url(prefix) + def http_url path = name_for_path path = path.gsub(/<<\s*(\w*)/, 'from-\1') if path =~ /<" % [self.class, object_id, title] end + def hash # :nodoc: + @title.hash + end + ## # The files comments in this section come from def in_files - return [] if @comments.empty? - - case @comments - when Array then - @comments.map do |comment| - comment.file - end - when RDoc::Markup::Document then - @comment.parts.map do |document| - document.file - end - else - raise RDoc::Error, "BUG: unknown comment class #{@comments.class}" - end + @comments.map(&:file) end ## @@ -162,11 +138,11 @@ def marshal_dump ## # De-serializes this Section. The section parent must be restored manually. - def marshal_load array + def marshal_load(array) @parent = nil @title = array[1] - @comments = array[2] + @comments = array[2].parts.map { |doc| RDoc::Comment.from_document(doc) } end ## @@ -174,26 +150,7 @@ def marshal_load array # multiple RDoc::Markup::Documents with their file set. def parse - case @comments - when String then - super - when Array then - docs = @comments.map do |comment, location| - doc = super comment - doc.file = location if location - doc - end - - RDoc::Markup::Document.new(*docs) - when RDoc::Comment then - doc = super @comments.text, comments.format - doc.file = @comments.location - doc - when RDoc::Markup::Document then - return @comments - else - raise ArgumentError, "unknown comment class #{comments.class}" - end + RDoc::Markup::Document.new(*@comments.map(&:parse)) end ## @@ -209,30 +166,10 @@ def plain_html # Removes a comment from this section if it is from the same file as # +comment+ - def remove_comment comment - return if @comments.empty? - - case @comments - when Array then - @comments.delete_if do |my_comment| - my_comment.file == comment.file - end - when RDoc::Markup::Document then - @comments.parts.delete_if do |document| - document.file == comment.file.name - end - else - raise RDoc::Error, "BUG: unknown comment class #{@comments.class}" + def remove_comment(target_comment) + @comments.delete_if do |stored_comment| + stored_comment.file == target_comment.file end end - ## - # Section sequence number (deprecated) - - def sequence - warn "RDoc::Context::Section#sequence is deprecated, use #aref" - @sequence - end - end - diff --git a/lib/rdoc/extend.rb b/lib/rdoc/code_object/extend.rb similarity index 82% rename from lib/rdoc/extend.rb rename to lib/rdoc/code_object/extend.rb index efa2c69bee..7d57433de6 100644 --- a/lib/rdoc/extend.rb +++ b/lib/rdoc/code_object/extend.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # A Module extension to a class with \#extend # @@ -6,4 +7,3 @@ class RDoc::Extend < RDoc::Mixin end - diff --git a/lib/rdoc/ghost_method.rb b/lib/rdoc/code_object/ghost_method.rb similarity index 79% rename from lib/rdoc/ghost_method.rb rename to lib/rdoc/code_object/ghost_method.rb index 7eb2d93167..25f951e35e 100644 --- a/lib/rdoc/ghost_method.rb +++ b/lib/rdoc/code_object/ghost_method.rb @@ -1,6 +1,6 @@ +# frozen_string_literal: true ## # GhostMethod represents a method referenced only by a comment class RDoc::GhostMethod < RDoc::AnyMethod end - diff --git a/lib/rdoc/include.rb b/lib/rdoc/code_object/include.rb similarity index 82% rename from lib/rdoc/include.rb rename to lib/rdoc/code_object/include.rb index 75ed9c7bff..c3e0d45e47 100644 --- a/lib/rdoc/include.rb +++ b/lib/rdoc/code_object/include.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # A Module included in a class with \#include # @@ -6,4 +7,3 @@ class RDoc::Include < RDoc::Mixin end - diff --git a/lib/rdoc/meta_method.rb b/lib/rdoc/code_object/meta_method.rb similarity index 76% rename from lib/rdoc/meta_method.rb rename to lib/rdoc/code_object/meta_method.rb index 68ba8109e0..8c95a0f78c 100644 --- a/lib/rdoc/meta_method.rb +++ b/lib/rdoc/code_object/meta_method.rb @@ -1,6 +1,6 @@ +# frozen_string_literal: true ## # MetaMethod represents a meta-programmed method class RDoc::MetaMethod < RDoc::AnyMethod end - diff --git a/lib/rdoc/method_attr.rb b/lib/rdoc/code_object/method_attr.rb similarity index 88% rename from lib/rdoc/method_attr.rb rename to lib/rdoc/code_object/method_attr.rb index a0ea851dc5..3dd60719d0 100644 --- a/lib/rdoc/method_attr.rb +++ b/lib/rdoc/code_object/method_attr.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # Abstract class representing either a method or an attribute. @@ -62,19 +63,13 @@ class RDoc::MethodAttr < RDoc::CodeObject attr_reader :arglists - ## - # Pretty parameter list for this method - - attr_reader :param_seq - - ## # Creates a new MethodAttr from token stream +text+ and method or attribute # name +name+. # # Usually this is called by super from a subclass. - def initialize text, name + def initialize(text, name, singleton: false) super() @text = text @@ -83,21 +78,20 @@ def initialize text, name @aliases = [] @is_alias_for = nil @parent_name = nil - @singleton = nil + @singleton = singleton @visibility = :public @see = false @arglists = nil @block_params = nil @call_seq = nil - @param_seq = nil @params = nil end ## # Resets cached data for the object so it can be rebuilt by accessor methods - def initialize_copy other # :nodoc: + def initialize_copy(other) # :nodoc: @full_name = nil end @@ -113,11 +107,11 @@ def <=>(other) return unless other.respond_to?(:singleton) && other.respond_to?(:name) - [ @singleton ? 0 : 1, name] <=> - [other.singleton ? 0 : 1, other.name] + [@singleton ? 0 : 1, name_ord_range, name] <=> + [other.singleton ? 0 : 1, other.name_ord_range, other.name] end - def == other # :nodoc: + def ==(other) # :nodoc: equal?(other) or self.class == other.class and full_name == other.full_name end @@ -156,7 +150,7 @@ def see ## # Sets the store for this class or module and its contained code objects. - def store= store + def store=(store) super @file = @store.add_file @file.full_name if @file @@ -174,7 +168,7 @@ def find_see # :nodoc: return find_method_or_attribute name[0..-2] end - def find_method_or_attribute name # :nodoc: + def find_method_or_attribute(name) # :nodoc: return nil unless parent.respond_to? :ancestors searched = parent.ancestors @@ -187,7 +181,7 @@ def find_method_or_attribute name # :nodoc: next if String === ancestor next if parent == ancestor - other = ancestor.find_method_named('#' << name) || + other = ancestor.find_method_named('#' + name) || ancestor.find_attribute_named(name) return other if other @@ -267,8 +261,8 @@ def block_params=(value) when 'const_get' then 'const' when 'new' then $1.split('::').last. # ClassName => class_name - gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). - gsub(/([a-z\d])([A-Z])/,'\1_\2'). + gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2'). + gsub(/([a-z\d])([A-Z])/, '\1_\2'). downcase else $2 @@ -288,9 +282,9 @@ def block_params=(value) # HTML id-friendly method/attribute name def html_name - require 'cgi' + require 'cgi/escape' - CGI.escape(@name.gsub('-', '-2D')).gsub('%','-').sub(/^-/, '') + CGI.escape(@name.gsub('-', '-2D')).gsub('%', '-').sub(/^-/, '') end ## @@ -319,19 +313,6 @@ def name_prefix @singleton ? '::' : '#' end - ## - # Name for output to HTML. For class methods the full name with a "." is - # used like +SomeClass.method_name+. For instance methods the class name is - # used if +context+ does not match the parent. - # - # This is to help prevent people from using :: to call class methods. - - def output_name context - return "#{name_prefix}#{@name}" if context == parent - - "#{parent_name}#{@singleton ? '.' : '#'}#{@name}" - end - ## # Method/attribute name with class/instance indicator @@ -360,7 +341,7 @@ def parent_name @parent_name || super end - def pretty_print q # :nodoc: + def pretty_print(q) # :nodoc: alias_for = if @is_alias_for.respond_to? :name then "alias for #{@is_alias_for.name}" @@ -414,5 +395,16 @@ def to_s # :nodoc: end end + def name_ord_range # :nodoc: + case name.ord + when 0..64 # anything below "A" + 1 + when 91..96 # the symbols between "Z" and "a" + 2 + when 123..126 # 7-bit symbols above "z": "{", "|", "}", "~" + 3 + else # everythig else can be sorted as normal + 4 + end + end end - diff --git a/lib/rdoc/mixin.rb b/lib/rdoc/code_object/mixin.rb similarity index 96% rename from lib/rdoc/mixin.rb rename to lib/rdoc/code_object/mixin.rb index 547744f870..9b425efd2e 100644 --- a/lib/rdoc/mixin.rb +++ b/lib/rdoc/code_object/mixin.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # A Mixin adds features from a module into another context. RDoc::Include and # RDoc::Extend are both mixins. @@ -22,13 +23,13 @@ def initialize(name, comment) ## # Mixins are sorted by name - def <=> other + def <=>(other) return unless self.class === other name <=> other.name end - def == other # :nodoc: + def ==(other) # :nodoc: self.class === other and @name == other.name end @@ -106,7 +107,7 @@ def module ## # Sets the store for this class or module and its contained code objects. - def store= store + def store=(store) super @file = @store.add_file @file.full_name if @file @@ -117,4 +118,3 @@ def to_s # :nodoc: end end - diff --git a/lib/rdoc/normal_class.rb b/lib/rdoc/code_object/normal_class.rb similarity index 87% rename from lib/rdoc/normal_class.rb rename to lib/rdoc/code_object/normal_class.rb index 7589e2686c..6b68d6db56 100644 --- a/lib/rdoc/normal_class.rb +++ b/lib/rdoc/code_object/normal_class.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # A normal class, neither singleton nor anonymous @@ -46,16 +47,16 @@ def inspect # :nodoc: def to_s # :nodoc: display = "#{self.class.name} #{self.full_name}" if superclass - display << ' < ' << (superclass.is_a?(String) ? superclass : superclass.full_name) + display += ' < ' + (superclass.is_a?(String) ? superclass : superclass.full_name) end - display << ' -> ' << is_alias_for.to_s if is_alias_for + display += ' -> ' + is_alias_for.to_s if is_alias_for display end - def pretty_print q # :nodoc: + def pretty_print(q) # :nodoc: superclass = @superclass ? " < #{@superclass}" : nil - q.group 2, "[class #{full_name}#{superclass} ", "]" do + q.group 2, "[class #{full_name}#{superclass}", "]" do q.breakable q.text "includes:" q.breakable @@ -89,4 +90,3 @@ def pretty_print q # :nodoc: end end - diff --git a/lib/rdoc/normal_module.rb b/lib/rdoc/code_object/normal_module.rb similarity index 92% rename from lib/rdoc/normal_module.rb rename to lib/rdoc/code_object/normal_module.rb index 961c431ed6..677a9dc3bd 100644 --- a/lib/rdoc/normal_module.rb +++ b/lib/rdoc/code_object/normal_module.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # A normal module, like NormalClass @@ -28,8 +29,8 @@ def module? true end - def pretty_print q # :nodoc: - q.group 2, "[module #{full_name}: ", "]" do + def pretty_print(q) # :nodoc: + q.group 2, "[module #{full_name}:", "]" do q.breakable q.text "includes:" q.breakable @@ -70,4 +71,3 @@ def superclass end end - diff --git a/lib/rdoc/require.rb b/lib/rdoc/code_object/require.rb similarity index 92% rename from lib/rdoc/require.rb rename to lib/rdoc/code_object/require.rb index a3d4bd18c0..f47e3b1534 100644 --- a/lib/rdoc/require.rb +++ b/lib/rdoc/code_object/require.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # A file loaded by \#require @@ -23,7 +24,7 @@ def inspect # :nodoc: self.class, object_id, @name, - parent_file_name, + @parent ? @parent.base_name : '(unknown)' ] end @@ -48,4 +49,3 @@ def top_level end end - diff --git a/lib/rdoc/single_class.rb b/lib/rdoc/code_object/single_class.rb similarity index 73% rename from lib/rdoc/single_class.rb rename to lib/rdoc/code_object/single_class.rb index 358e1f38eb..88a93a0c5f 100644 --- a/lib/rdoc/single_class.rb +++ b/lib/rdoc/code_object/single_class.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # A singleton class @@ -21,5 +22,9 @@ def definition "class << #{full_name}" end + def pretty_print(q) # :nodoc: + q.group 2, "[class << #{full_name}", "]" do + next + end + end end - diff --git a/lib/rdoc/top_level.rb b/lib/rdoc/code_object/top_level.rb similarity index 81% rename from lib/rdoc/top_level.rb rename to lib/rdoc/code_object/top_level.rb index 64d81d20c1..eeeff026a1 100644 --- a/lib/rdoc/top_level.rb +++ b/lib/rdoc/code_object/top_level.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # A TopLevel context is a representation of the contents of a single file @@ -5,11 +6,6 @@ class RDoc::TopLevel < RDoc::Context MARSHAL_VERSION = 0 # :nodoc: - ## - # This TopLevel's File::Stat struct - - attr_accessor :file_stat - ## # Relative name of this file @@ -27,34 +23,39 @@ class RDoc::TopLevel < RDoc::Context attr_reader :classes_or_modules - attr_accessor :diagram # :nodoc: - ## # The parser class that processed this file - attr_accessor :parser + attr_reader :parser ## # Creates a new TopLevel for the file at +absolute_name+. If documentation # is being generated outside the source dir +relative_name+ is relative to # the source directory. - def initialize absolute_name, relative_name = absolute_name + def initialize(absolute_name, relative_name = absolute_name) super() @name = nil @absolute_name = absolute_name @relative_name = relative_name - @file_stat = File.stat(absolute_name) rescue nil # HACK for testing - @diagram = nil @parser = nil @classes_or_modules = [] end + ## + # Sets the parser for this toplevel context, also the store. + + def parser=(val) + @parser = val + @store.update_parser_of_file(absolute_name, val) if @store + @parser + end + ## # An RDoc::TopLevel is equal to another with the same relative_name - def == other + def ==(other) self.class === other and @relative_name == other.relative_name end @@ -72,7 +73,7 @@ def add_alias(an_alias) ## # Adds +constant+ to +Object+ instead of +self+. - def add_constant constant + def add_constant(constant) object_class.record_location self return constant unless @document_self object_class.add_constant constant @@ -100,7 +101,7 @@ def add_method(method) # Adds class or module +mod+. Used in the building phase # by the Ruby parser. - def add_to_classes_or_modules mod + def add_to_classes_or_modules(mod) @classes_or_modules << mod end @@ -127,7 +128,7 @@ def display? # TODO Why do we search through all classes/modules found, not just the # ones of this instance? - def find_class_or_module name + def find_class_or_module(name) @store.find_class_or_module name end @@ -163,28 +164,19 @@ def hash ## # URL for this with a +prefix+ - def http_url(prefix) - path = [prefix, @relative_name.tr('.', '_')] - - File.join(*path.compact) + '.html' + def http_url + @relative_name.tr('.', '_') + '.html' end def inspect # :nodoc: "#<%s:0x%x %p modules: %p classes: %p>" % [ self.class, object_id, base_name, - @modules.map { |n,m| m }, - @classes.map { |n,c| c } + @modules.map { |n, m| m }, + @classes.map { |n, c| c } ] end - ## - # Time this file was last modified, if known - - def last_modified - @file_stat ? file_stat.mtime : nil - end - ## # Dumps this TopLevel for use by ri. See also #marshal_load @@ -200,13 +192,11 @@ def marshal_dump ## # Loads this TopLevel from +array+. - def marshal_load array # :nodoc: + def marshal_load(array) # :nodoc: initialize array[1] @parser = array[2] - @comment = array[3] - - @file_stat = nil + @comment = RDoc::Comment.from_document array[3] end ## @@ -236,16 +226,18 @@ def page_name # Path to this file for use with HTML generator output. def path - http_url @store.rdoc.generator.file_dir + prefix = options.file_path_prefix + return http_url unless prefix + File.join(prefix, http_url) end - def pretty_print q # :nodoc: + def pretty_print(q) # :nodoc: q.group 2, "[#{self.class}: ", "]" do q.text "base name: #{base_name.inspect}" q.breakable - items = @modules.map { |n,m| m } - items.concat @modules.map { |n,c| c } + items = @modules.map { |n, m| m } + items.concat @modules.map { |n, c| c } q.seplist items do |mod| q.pp mod end end end @@ -271,7 +263,7 @@ def search_record # Is this TopLevel from a text file instead of a source code file? def text? - @parser and @parser.ancestors.include? RDoc::Parser::Text + @parser and @parser.include? RDoc::Parser::Text end def to_s # :nodoc: @@ -279,4 +271,3 @@ def to_s # :nodoc: end end - diff --git a/lib/rdoc/code_objects.rb b/lib/rdoc/code_objects.rb index f1a626cd2e..d5f2f920ad 100644 --- a/lib/rdoc/code_objects.rb +++ b/lib/rdoc/code_objects.rb @@ -1,5 +1,5 @@ +# frozen_string_literal: true # This file was used to load all the RDoc::CodeObject subclasses at once. Now # autoload handles this. -require 'rdoc' - +require_relative '../rdoc' diff --git a/lib/rdoc/comment.rb b/lib/rdoc/comment.rb index 33ced18b5a..b269ec4845 100644 --- a/lib/rdoc/comment.rb +++ b/lib/rdoc/comment.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # A comment holds the text comment for a RDoc::CodeObject and provides a # unified way of cleaning it up and parsing it into an RDoc::Markup::Document. @@ -5,8 +6,8 @@ # Each comment may have a different markup format set by #format=. By default # 'rdoc' is used. The :markup: directive tells RDoc which format to use. # -# See RDoc::Markup@Other+directives for instructions on adding an alternate -# format. +# See RDoc::MarkupReference@Directive+for+Specifying+RDoc+Source+Format. + class RDoc::Comment @@ -22,6 +23,11 @@ class RDoc::Comment attr_accessor :location + ## + # Line where this Comment was written + + attr_accessor :line + ## # For duck-typing when merging classes at load time @@ -32,6 +38,11 @@ class RDoc::Comment attr_reader :text + ## + # Alias for text + + alias to_s text + ## # Overrides the content returned by #parse. Use when there is no #text # source for this comment @@ -42,9 +53,10 @@ class RDoc::Comment # Creates a new comment with +text+ that is found in the RDoc::TopLevel # +location+. - def initialize text = nil, location = nil + def initialize(text = nil, location = nil, language = nil) @location = location - @text = text + @text = text.nil? ? nil : text.dup + @language = language @document = nil @format = 'rdoc' @@ -55,11 +67,11 @@ def initialize text = nil, location = nil #-- # TODO deep copy @document - def initialize_copy copy # :nodoc: + def initialize_copy(copy) # :nodoc: @text = copy.text.dup end - def == other # :nodoc: + def ==(other) # :nodoc: self.class === other and other.text == @text and other.location == @location end @@ -80,66 +92,52 @@ def == other # :nodoc: # # ARGF.to_a(limit) -> array # # ARGF.to_a(sep, limit) -> array - def extract_call_seq method + def extract_call_seq # we must handle situations like the above followed by an unindented first # comment. The difficulty is to make sure not to match lines starting # with ARGF at the same indent, but that are after the first description # paragraph. - if @text =~ /^\s*:?call-seq:(.*?(?:\S).*?)^\s*$/m then + if /^(? ((?!\n)\s)*+ (?# whitespaces except newline)) + :?call-seq: + (? \g(?\n|\z) (?# trailing spaces))? + (? + (\g(?!\w)\S.*\g)* + (?> + (? \g\w+ (?# ' # ARGF' in the example above)) + .*\g)? + (\g\S.*\g (?# other non-blank line))*+ + (\g+(\k.*\g (?# ARGF.to_a lines))++)*+ + ) + (?m:^\s*$|\z) + /x =~ @text + seq = $~[:seq] + all_start, all_stop = $~.offset(0) - seq_start, seq_stop = $~.offset(1) - - # we get the following lines that start with the leading word at the - # same indent, even if they have blank lines before - if $1 =~ /(^\s*\n)+^(\s*\w+)/m then - leading = $2 # ' * ARGF' in the example above - re = %r% - \A( - (^\s*\n)+ - (^#{Regexp.escape leading}.*?\n)+ - )+ - ^\s*$ - %xm - - if @text[seq_stop..-1] =~ re then - all_stop = seq_stop + $~.offset(0).last - seq_stop = seq_stop + $~.offset(1).last - end - end - - seq = @text[seq_start..seq_stop] - seq.gsub!(/^\s*(\S|\n)/m, '\1') @text.slice! all_start...all_stop - method.call_seq = seq.chomp - - elsif @text.sub!(/^\s*:?call-seq:(.*?)(^\s*$|\z)/m, '') then - seq = $1 seq.gsub!(/^\s*/, '') - method.call_seq = seq end - - method end ## # A comment is empty if its text String is empty. def empty? - @text.empty? + @text.empty? && (@document.nil? || @document.empty?) end ## # HACK dubious - def force_encoding encoding - @text.force_encoding encoding + def encode!(encoding) + @text = String.new @text, encoding: encoding + self end ## # Sets the format of this comment and resets any parsed document - def format= format + def format=(format) @format = format @document = nil end @@ -199,7 +197,7 @@ def parse def remove_private # Workaround for gsub encoding for Ruby 1.9.2 and earlier empty = '' - empty.force_encoding @text.encoding if Object.const_defined? :Encoding + empty = RDoc::Encoding.change_encoding empty, @text.encoding @text = @text.gsub(%r%^\s*([#*]?)--.*?^\s*(\1)\+\+\n?%m, empty) @text = @text.sub(%r%^\s*[#*]?--.*%m, '') @@ -210,12 +208,12 @@ def remove_private # # An error is raised if the comment contains a document but no text. - def text= text + def text=(text) raise RDoc::Error, 'replacing document-only comment is not allowed' if @text.nil? and @document @document = nil - @text = text + @text = text.nil? ? nil : text.dup end ## @@ -225,5 +223,14 @@ def tomdoc? @format == 'tomdoc' end -end + ## + # Create a new parsed comment from a document + + def self.from_document(document) # :nodoc: + comment = RDoc::Comment.new('') + comment.document = document + comment.location = RDoc::TopLevel.new(document.file) if document.file + comment + end +end diff --git a/lib/rdoc/cross_reference.rb b/lib/rdoc/cross_reference.rb index 5b08d5202d..a942d33c96 100644 --- a/lib/rdoc/cross_reference.rb +++ b/lib/rdoc/cross_reference.rb @@ -1,3 +1,7 @@ +# frozen_string_literal: true + +require_relative 'markup/attribute_manager' # for PROTECT_ATTR + ## # RDoc::CrossReference is a reusable way to create cross references for names. @@ -13,32 +17,39 @@ class RDoc::CrossReference CLASS_REGEXP_STR = '\\\\?((?:\:{2})?[A-Z]\w*(?:\:\:\w+)*)' + ## + # Regular expression to match a single method argument. + + METHOD_ARG_REGEXP_STR = '[\w.+*/=<>-]+' + + ## + # Regular expression to match method arguments. + + METHOD_ARGS_REGEXP_STR = /(?:\((?:#{METHOD_ARG_REGEXP_STR}(?:,\s*#{METHOD_ARG_REGEXP_STR})*)?\))?/.source + ## # Regular expression to match method references. # # See CLASS_REGEXP_STR - METHOD_REGEXP_STR = '([a-z]\w*[!?=]?|%|===|\[\]=?|<<|>>)(?:\([\w.+*/=<>-]*\))?' + METHOD_REGEXP_STR = /( + (?!\d)[\w#{RDoc::Markup::AttributeManager::PROTECT_ATTR}]+[!?=]?| + %|=(?:==?|~)|![=~]|\[\]=?|<(?:<|=>?)?|>[>=]?|[-+!]@?|\*\*?|[\/%\`|&^~] + )#{METHOD_ARGS_REGEXP_STR}/.source.delete("\n ").freeze ## # Regular expressions matching text that should potentially have - # cross-reference links generated are passed to add_special. Note that - # these expressions are meant to pick up text for which cross-references + # cross-reference links generated are passed to add_regexp_handling. Note + # that these expressions are meant to pick up text for which cross-references # have been suppressed, since the suppression characters are removed by the # code that is triggered. - CROSSREF_REGEXP = /(?:^|\s) + CROSSREF_REGEXP = /(?:^|[\s()]) ( (?: # A::B::C.meth #{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR} - # Stand-alone method (preceded by a #) - | \\?\##{METHOD_REGEXP_STR} - - # Stand-alone method (preceded by ::) - | ::#{METHOD_REGEXP_STR} - # A::B::C # The stuff after CLASS_REGEXP_STR is a # nasty hack. CLASS_REGEXP_STR unfortunately matches @@ -55,6 +66,12 @@ class RDoc::CrossReference # marker. | #{CLASS_REGEXP_STR}(?=[@\s).?!,;<\000]|\z) + # Stand-alone method (preceded by a #) + | \\?\##{METHOD_REGEXP_STR} + + # Stand-alone method (preceded by ::) + | ::#{METHOD_REGEXP_STR} + # Things that look like filenames # The key thing is that there must be at least # one special character (period, slash, or @@ -75,18 +92,18 @@ class RDoc::CrossReference # Version of CROSSREF_REGEXP used when --hyperlink-all is specified. ALL_CROSSREF_REGEXP = / - (?:^|\s) + (?:^|[\s()]) ( (?: # A::B::C.meth #{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR} - # Stand-alone method - | \\?#{METHOD_REGEXP_STR} - # A::B::C | #{CLASS_REGEXP_STR}(?=[@\s).?!,;<\000]|\z) + # Stand-alone method + | \\?#{METHOD_REGEXP_STR} + # Things that look like filenames | (?:\.\.\/)*[-\/\w]+[_\/.][-\w\/.]+ @@ -107,7 +124,7 @@ class RDoc::CrossReference # Allows cross-references to be created based on the given +context+ # (RDoc::Context). - def initialize context + def initialize(context) @context = context @store = context.store @@ -115,46 +132,75 @@ def initialize context end ## - # Returns a reference to +name+. - # - # If the reference is found and +name+ is not documented +text+ will be - # returned. If +name+ is escaped +name+ is returned. If +name+ is not - # found +text+ is returned. + # Returns a method reference to +name+. - def resolve name, text - return @seen[name] if @seen.include? name + def resolve_method(name) + ref = nil if /#{CLASS_REGEXP_STR}([.#]|::)#{METHOD_REGEXP_STR}/o =~ name then type = $2 - type = '' if type == '.' # will find either #method or ::method - method = "#{type}#{$3}" + if '.' == type # will find either #method or ::method + method = $3 + else + method = "#{type}#{$3}" + end container = @context.find_symbol_module($1) elsif /^([.#]|::)#{METHOD_REGEXP_STR}/o =~ name then type = $1 - type = '' if type == '.' - method = "#{type}#{$2}" + if '.' == type + method = $2 + else + method = "#{type}#{$2}" + end container = @context else + type = nil container = nil end if container then - ref = container.find_local_symbol method - - unless ref || RDoc::TopLevel === container then - ref = container.find_ancestor_local_symbol method + unless RDoc::TopLevel === container then + if '.' == type then + if 'new' == method then # AnyClassName.new will be class method + ref = container.find_local_symbol method + ref = container.find_ancestor_local_symbol method unless ref + else + ref = container.find_local_symbol "::#{method}" + ref = container.find_ancestor_local_symbol "::#{method}" unless ref + ref = container.find_local_symbol "##{method}" unless ref + ref = container.find_ancestor_local_symbol "##{method}" unless ref + end + else + ref = container.find_local_symbol method + ref = container.find_ancestor_local_symbol method unless ref + end end end + ref + end + + ## + # Returns a reference to +name+. + # + # If the reference is found and +name+ is not documented +text+ will be + # returned. If +name+ is escaped +name+ is returned. If +name+ is not + # found +text+ is returned. + + def resolve(name, text) + return @seen[name] if @seen.include? name + ref = case name when /^\\(#{CLASS_REGEXP_STR})$/o then @context.find_symbol $1 else @context.find_symbol name - end unless ref + end + + ref = resolve_method name unless ref # Try a page name - ref = @store.page name if not ref and name =~ /^\w+$/ + ref = @store.page name if not ref and name =~ /^[\w.]+$/ ref = nil if RDoc::Alias === ref # external alias, can't link to it @@ -180,4 +226,3 @@ def resolve name, text end end - diff --git a/lib/rdoc/encoding.rb b/lib/rdoc/encoding.rb index b3515a435f..78dbe87d0c 100644 --- a/lib/rdoc/encoding.rb +++ b/lib/rdoc/encoding.rb @@ -1,4 +1,5 @@ # coding: US-ASCII +# frozen_string_literal: true ## # This class is a wrapper around File IO and Encoding that helps RDoc load @@ -6,6 +7,18 @@ module RDoc::Encoding + HEADER_REGEXP = /^ + (?: + \A\#!.*\n + | + ^\#\s+frozen[-_]string[-_]literal[=:].+\n + | + ^\#[^\n]+\b(?:en)?coding[=:]\s*(?[^\s;]+).*\n + | + <\?xml[^?]*encoding=(?["'])(?.*?)\k.*\n + )+ + /xi # :nodoc: + ## # Reads the contents of +filename+ and handles any encoding directives in # the file. @@ -16,51 +29,51 @@ module RDoc::Encoding # If +force_transcode+ is true the document will be transcoded and any # unknown character in the target encoding will be replaced with '?' - def self.read_file filename, encoding, force_transcode = false - content = open filename, "rb" do |f| f.read end + def self.read_file(filename, encoding, force_transcode = false) + content = File.open filename, "rb" do |f| f.read end content.gsub!("\r\n", "\n") if RUBY_PLATFORM =~ /mswin|mingw/ utf8 = content.sub!(/\A\xef\xbb\xbf/, '') - RDoc::Encoding.set_encoding content - - if Object.const_defined? :Encoding then - begin - encoding ||= Encoding.default_external - orig_encoding = content.encoding - - if not orig_encoding.ascii_compatible? then - content.encode! encoding - elsif utf8 then - content.force_encoding Encoding::UTF_8 - content.encode! encoding - else - # assume the content is in our output encoding - content.force_encoding encoding - end - - unless content.valid_encoding? then - # revert and try to transcode - content.force_encoding orig_encoding - content.encode! encoding - end - - unless content.valid_encoding? then - warn "unable to convert #{filename} to #{encoding}, skipping" - content = nil - end - rescue Encoding::InvalidByteSequenceError, - Encoding::UndefinedConversionError => e - if force_transcode then - content.force_encoding orig_encoding - content.encode!(encoding, - :invalid => :replace, :undef => :replace, - :replace => '?') - return content - else - warn "unable to convert #{e.message} for #{filename}, skipping" - return nil - end + enc = RDoc::Encoding.detect_encoding content + content = RDoc::Encoding.change_encoding content, enc if enc + + begin + encoding ||= Encoding.default_external + orig_encoding = content.encoding + + if not orig_encoding.ascii_compatible? then + content = content.encode encoding + elsif utf8 then + content = RDoc::Encoding.change_encoding content, Encoding::UTF_8 + content = content.encode encoding + else + # assume the content is in our output encoding + content = RDoc::Encoding.change_encoding content, encoding + end + + unless content.valid_encoding? then + # revert and try to transcode + content = RDoc::Encoding.change_encoding content, orig_encoding + content = content.encode encoding + end + + unless content.valid_encoding? then + warn "unable to convert #{filename} to #{encoding}, skipping" + content = nil + end + rescue Encoding::InvalidByteSequenceError, + Encoding::UndefinedConversionError => e + if force_transcode then + content = RDoc::Encoding.change_encoding content, orig_encoding + content = content.encode(encoding, + :invalid => :replace, + :undef => :replace, + :replace => '?') + return content + else + warn "unable to convert #{e.message} for #{filename}, skipping" + return nil end end @@ -74,26 +87,34 @@ def self.read_file filename, encoding, force_transcode = false end ## - # Sets the encoding of +string+ based on the magic comment - - def self.set_encoding string - string =~ /\A(?:#!.*\n)?(.*\n)/ + # Detects the encoding of +string+ based on the magic comment - first_line = $1 + def self.detect_encoding(string) + result = HEADER_REGEXP.match string + name = result && result[:name] - name = case first_line - when /^<\?xml[^?]*encoding=(["'])(.*?)\1/ then $2 - when /\b(?:en)?coding[=:]\s*([^\s;]+)/i then $1 - else return - end + name ? Encoding.find(name) : nil + end - string.sub! first_line, '' + ## + # Removes magic comments and shebang - return unless Object.const_defined? :Encoding + def self.remove_magic_comment(string) + string.sub HEADER_REGEXP do |s| + s.gsub(/[^\n]/, '') + end + end - enc = Encoding.find name - string.force_encoding enc if enc + ## + # Changes encoding based on +encoding+ without converting and returns new + # string + + def self.change_encoding(text, encoding) + if text.kind_of? RDoc::Comment + text.encode! encoding + else + String.new text, encoding: encoding + end end end - diff --git a/lib/rdoc/erb_partial.rb b/lib/rdoc/erb_partial.rb index 910d1e0351..bad02ea706 100644 --- a/lib/rdoc/erb_partial.rb +++ b/lib/rdoc/erb_partial.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # Allows an ERB template to be rendered in the context (binding) of an # existing ERB template evaluation. @@ -8,11 +9,10 @@ class RDoc::ERBPartial < ERB # Overrides +compiler+ startup to set the +eoutvar+ to an empty string only # if it isn't already set. - def set_eoutvar compiler, eoutvar = '_erbout' + def set_eoutvar(compiler, eoutvar = '_erbout') super - compiler.pre_cmd = ["#{eoutvar} ||= ''"] + compiler.pre_cmd = ["#{eoutvar} ||= +''"] end end - diff --git a/lib/rdoc/erbio.rb b/lib/rdoc/erbio.rb index 04a89fbd34..e955eed811 100644 --- a/lib/rdoc/erbio.rb +++ b/lib/rdoc/erbio.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true require 'erb' ## @@ -8,7 +9,7 @@ # # erbio = RDoc::ERBIO.new '<%= "hello world" %>', nil, nil # -# open 'hello.txt', 'w' do |io| +# File.open 'hello.txt', 'w' do |io| # erbio.result binding # end # @@ -19,14 +20,14 @@ class RDoc::ERBIO < ERB ## # Defaults +eoutvar+ to 'io', otherwise is identical to ERB's initialize - def initialize str, safe_level = nil, trim_mode = nil, eoutvar = 'io' - super + def initialize(str, trim_mode: nil, eoutvar: 'io') + super(str, trim_mode: trim_mode, eoutvar: eoutvar) end ## # Instructs +compiler+ how to write to +io_variable+ - def set_eoutvar compiler, io_variable + def set_eoutvar(compiler, io_variable) compiler.put_cmd = "#{io_variable}.write" compiler.insert_cmd = "#{io_variable}.write" compiler.pre_cmd = [] @@ -34,4 +35,3 @@ def set_eoutvar compiler, io_variable end end - diff --git a/lib/rdoc/generator.rb b/lib/rdoc/generator.rb index 7d3989d42f..a769cf8ac0 100644 --- a/lib/rdoc/generator.rb +++ b/lib/rdoc/generator.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # RDoc uses generators to turn parsed source code in the form of an # RDoc::CodeObject tree into some form of output. RDoc comes with the HTML @@ -40,12 +41,11 @@ module RDoc::Generator - autoload :Markup, 'rdoc/generator/markup' + autoload :Markup, "#{__dir__}/generator/markup" - autoload :Darkfish, 'rdoc/generator/darkfish' - autoload :JsonIndex, 'rdoc/generator/json_index' - autoload :RI, 'rdoc/generator/ri' - autoload :POT, 'rdoc/generator/pot' + autoload :Darkfish, "#{__dir__}/generator/darkfish" + autoload :JsonIndex, "#{__dir__}/generator/json_index" + autoload :RI, "#{__dir__}/generator/ri" + autoload :POT, "#{__dir__}/generator/pot" end - diff --git a/lib/rdoc/generator/darkfish.rb b/lib/rdoc/generator/darkfish.rb index 024040466d..7fec36500f 100644 --- a/lib/rdoc/generator/darkfish.rb +++ b/lib/rdoc/generator/darkfish.rb @@ -1,9 +1,10 @@ +# frozen_string_literal: true # -*- mode: ruby; ruby-indent-level: 2; tab-width: 2 -*- require 'erb' require 'fileutils' require 'pathname' -require 'rdoc/generator/markup' +require_relative 'markup' ## # Darkfish RDoc HTML Generator @@ -72,12 +73,6 @@ class RDoc::Generator::Darkfish css/rdoc.css ] - ## - # Path to this file's parent directory. Used to find templates and other - # resources. - - GENERATOR_DIR = File.join 'rdoc', 'generator' - ## # Release Version @@ -155,7 +150,7 @@ class RDoc::Generator::Darkfish ## # Initialize a few instance variables before we start - def initialize store, options + def initialize(store, options) @store = store @options = options @@ -183,22 +178,6 @@ def debug_msg *msg $stderr.puts(*msg) end - ## - # Directory where generated class HTML files live relative to the output - # dir. - - def class_dir - nil - end - - ## - # Directory where generated class HTML files live relative to the output - # dir. - - def file_dir - nil - end - ## # Create the directories the generated docs will live in if they don't # already exist. @@ -219,8 +198,8 @@ def write_style_sheet install_rdoc_static_file @template_dir + item, "./#{item}", options end - @options.template_stylesheets.each do |stylesheet| - FileUtils.cp stylesheet, '.', options + unless @options.template_stylesheets.empty? + FileUtils.cp @options.template_stylesheets, '.', **options end Dir[(@template_dir + "{js,images}/**/*").to_s].each do |path| @@ -268,7 +247,7 @@ def copy_static @options.static_path.each do |path| unless File.directory? path then - FileUtils.install path, @outputdir, fu_options.merge(:mode => 0644) + FileUtils.install path, @outputdir, **fu_options.merge(:mode => 0644) next end @@ -277,9 +256,9 @@ def copy_static dest_file = @outputdir + entry if File.directory? entry then - FileUtils.mkdir_p entry, fu_options + FileUtils.mkdir_p entry, **fu_options else - FileUtils.install entry, dest_file, fu_options.merge(:mode => 0644) + FileUtils.install entry, dest_file, **fu_options.merge(:mode => 0644) end end end @@ -290,7 +269,7 @@ def copy_static # Return a list of the documented modules sorted by salience first, then # by name. - def get_sorted_module_list classes + def get_sorted_module_list(classes) classes.select do |klass| klass.display? end.sort @@ -300,8 +279,6 @@ def get_sorted_module_list classes # Generate an index page which lists all the classes which are documented. def generate_index - setup - template_file = @template_dir + 'index.rhtml' return unless template_file.exist? @@ -312,12 +289,19 @@ def generate_index search_index_rel_prefix = rel_prefix search_index_rel_prefix += @asset_rel_path if @file_output - # suppress 1.9.3 warning - asset_rel_prefix = asset_rel_prefix = rel_prefix + @asset_rel_path + asset_rel_prefix = rel_prefix + @asset_rel_path @title = @options.title + @main_page = @files.find { |f| f.full_name == @options.main_page } - render_template template_file, out_file do |io| binding end + render_template template_file, out_file do |io| + here = binding + # suppress 1.9.3 warning + here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) + # some partials rely on the presence of current variable to render + here.local_variable_set(:current, @main_page) if @main_page + here + end rescue => e error = RDoc::Error.new \ "error generating index.html: #{e.message} (#{e.class})" @@ -329,9 +313,7 @@ def generate_index ## # Generates a class file for +klass+ - def generate_class klass, template_file = nil - setup - + def generate_class(klass, template_file = nil) current = klass template_file ||= @template_dir + 'class.rhtml' @@ -342,22 +324,26 @@ def generate_class klass, template_file = nil search_index_rel_prefix = rel_prefix search_index_rel_prefix += @asset_rel_path if @file_output - # suppress 1.9.3 warning - asset_rel_prefix = asset_rel_prefix = rel_prefix + @asset_rel_path - svninfo = svninfo = get_svninfo(current) + asset_rel_prefix = rel_prefix + @asset_rel_path + + breadcrumb = # used in templates + breadcrumb = generate_nesting_namespaces_breadcrumb(current, rel_prefix) @title = "#{klass.type} #{klass.full_name} - #{@options.title}" debug_msg " rendering #{out_file}" - render_template template_file, out_file do |io| binding end + render_template template_file, out_file do |io| + here = binding + # suppress 1.9.3 warning + here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) + here + end end ## # Generate a documentation file for each class and module def generate_class_files - setup - template_file = @template_dir + 'class.rhtml' template_file = @template_dir + 'classpage.rhtml' unless template_file.exist? @@ -383,8 +369,6 @@ def generate_class_files # Generate a documentation file for each file def generate_file_files - setup - page_file = @template_dir + 'page.rhtml' fileinfo_file = @template_dir + 'fileinfo.rhtml' @@ -415,8 +399,7 @@ def generate_file_files search_index_rel_prefix = rel_prefix search_index_rel_prefix += @asset_rel_path if @file_output - # suppress 1.9.3 warning - asset_rel_prefix = asset_rel_prefix = rel_prefix + @asset_rel_path + asset_rel_prefix = rel_prefix + @asset_rel_path unless filepage_file then if file.text? then @@ -433,7 +416,13 @@ def generate_file_files @title += " - #{@options.title}" template_file ||= filepage_file - render_template template_file, out_file do |io| binding end + render_template template_file, out_file do |io| + here = binding + # suppress 1.9.3 warning + here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) + here.local_variable_set(:current, current) + here + end end rescue => e error = @@ -446,9 +435,7 @@ def generate_file_files ## # Generate a page file for +file+ - def generate_page file - setup - + def generate_page(file) template_file = @template_dir + 'page.rhtml' out_file = @outputdir + file.path @@ -457,22 +444,25 @@ def generate_page file search_index_rel_prefix = rel_prefix search_index_rel_prefix += @asset_rel_path if @file_output - # suppress 1.9.3 warning - current = current = file - asset_rel_prefix = asset_rel_prefix = rel_prefix + @asset_rel_path + current = file + asset_rel_prefix = rel_prefix + @asset_rel_path @title = "#{file.page_name} - #{@options.title}" debug_msg " rendering #{out_file}" - render_template template_file, out_file do |io| binding end + render_template template_file, out_file do |io| + here = binding + # suppress 1.9.3 warning + here.local_variable_set(:current, current) + here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) + here + end end ## # Generates the 404 page for the RDoc servlet - def generate_servlet_not_found message - setup - + def generate_servlet_not_found(message) template_file = @template_dir + 'servlet_not_found.rhtml' return unless template_file.exist? @@ -482,12 +472,16 @@ def generate_servlet_not_found message search_index_rel_prefix = rel_prefix search_index_rel_prefix += @asset_rel_path if @file_output - # suppress 1.9.3 warning - asset_rel_prefix = asset_rel_prefix = '' + asset_rel_prefix = '' @title = 'Not Found' - render_template template_file do |io| binding end + render_template template_file do |io| + here = binding + # suppress 1.9.3 warning + here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) + here + end rescue => e error = RDoc::Error.new \ "error generating servlet_not_found: #{e.message} (#{e.class})" @@ -499,9 +493,7 @@ def generate_servlet_not_found message ## # Generates the servlet root page for the RDoc servlet - def generate_servlet_root installed - setup - + def generate_servlet_root(installed) template_file = @template_dir + 'servlet_root.rhtml' return unless template_file.exist? @@ -527,8 +519,6 @@ def generate_servlet_root installed # Generate an index page which lists all the classes which are documented. def generate_table_of_contents - setup - template_file = @template_dir + 'table_of_contents.rhtml' return unless template_file.exist? @@ -539,12 +529,16 @@ def generate_table_of_contents search_index_rel_prefix = rel_prefix search_index_rel_prefix += @asset_rel_path if @file_output - # suppress 1.9.3 warning - asset_rel_prefix = asset_rel_prefix = rel_prefix + @asset_rel_path + asset_rel_prefix = rel_prefix + @asset_rel_path @title = "Table of Contents - #{@options.title}" - render_template template_file, out_file do |io| binding end + render_template template_file, out_file do |io| + here = binding + # suppress 1.9.3 warning + here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) + here + end rescue => e error = RDoc::Error.new \ "error generating table_of_contents.html: #{e.message} (#{e.class})" @@ -553,20 +547,20 @@ def generate_table_of_contents raise error end - def install_rdoc_static_file source, destination, options # :nodoc: + def install_rdoc_static_file(source, destination, options) # :nodoc: return unless source.exist? begin - FileUtils.mkdir_p File.dirname(destination), options + FileUtils.mkdir_p File.dirname(destination), **options begin - FileUtils.ln source, destination, options + FileUtils.ln source, destination, **options rescue Errno::EEXIST FileUtils.rm destination retry end rescue - FileUtils.cp source, destination, options + FileUtils.cp source, destination, **options end end @@ -582,85 +576,30 @@ def setup @classes = @store.all_classes_and_modules.sort @files = @store.all_files.sort - @methods = @classes.map { |m| m.method_list }.flatten.sort + @methods = @classes.flat_map { |m| m.method_list }.sort @modsort = get_sorted_module_list @classes end - ## - # Return a string describing the amount of time in the given number of - # seconds in terms a human can understand easily. - - def time_delta_string seconds - return 'less than a minute' if seconds < 60 - return "#{seconds / 60} minute#{seconds / 60 == 1 ? '' : 's'}" if - seconds < 3000 # 50 minutes - return 'about one hour' if seconds < 5400 # 90 minutes - return "#{seconds / 3600} hours" if seconds < 64800 # 18 hours - return 'one day' if seconds < 86400 # 1 day - return 'about one day' if seconds < 172800 # 2 days - return "#{seconds / 86400} days" if seconds < 604800 # 1 week - return 'about one week' if seconds < 1209600 # 2 week - return "#{seconds / 604800} weeks" if seconds < 7257600 # 3 months - return "#{seconds / 2419200} months" if seconds < 31536000 # 1 year - return "#{seconds / 31536000} years" - end - - # %q$Id: darkfish.rb 52 2009-01-07 02:08:11Z deveiant $" - SVNID_PATTERN = / - \$Id:\s - (\S+)\s # filename - (\d+)\s # rev - (\d{4}-\d{2}-\d{2})\s # Date (YYYY-MM-DD) - (\d{2}:\d{2}:\d{2}Z)\s # Time (HH:MM:SSZ) - (\w+)\s # committer - \$$ - /x - - ## - # Try to extract Subversion information out of the first constant whose - # value looks like a subversion Id tag. If no matching constant is found, - # and empty hash is returned. - - def get_svninfo klass - constants = klass.constants or return {} - - constants.find { |c| c.value =~ SVNID_PATTERN } or return {} - - filename, rev, date, time, committer = $~.captures - commitdate = Time.parse "#{date} #{time}" - - return { - :filename => filename, - :rev => Integer(rev), - :commitdate => commitdate, - :commitdelta => time_delta_string(Time.now - commitdate), - :committer => committer, - } - end - ## # Creates a template from its components and the +body_file+. # # For backwards compatibility, if +body_file+ contains " - + #{head_file.read} #{body} - -#{footer_file.read} TEMPLATE end @@ -668,7 +607,7 @@ def assemble_template body_file # Renders the ERb contained in +file_name+ relative to the template # directory and returns the result based on the current context. - def render file_name + def render(file_name) template_file = @template_dir + file_name template = template_for template_file, false, RDoc::ERBPartial @@ -686,7 +625,7 @@ def render file_name # # An io will be yielded which must be captured by binding in the caller. - def render_template template_file, out_file = nil # :yield: io + def render_template(template_file, out_file = nil) # :yield: io io_output = out_file && !@dry_run && @file_output erb_klass = io_output ? RDoc::ERBIO : ERB @@ -697,7 +636,7 @@ def render_template template_file, out_file = nil # :yield: io out_file.dirname.mkpath out_file.open 'w', 0644 do |io| - io.set_encoding @options.encoding if Object.const_defined? :Encoding + io.set_encoding @options.encoding @context = yield io @@ -720,7 +659,7 @@ def render_template template_file, out_file = nil # :yield: io # Creates the result for +template+ with +context+. If an error is raised a # Pathname +template_file+ will indicate the file where the error occurred. - def template_result template, context, template_file + def template_result(template, context, template_file) template.filename = template_file.to_s template.result context rescue NoMethodError => e @@ -733,7 +672,7 @@ def template_result template, context, template_file ## # Retrieves a cache template for +file+, if present, or fills the cache. - def template_for file, page = true, klass = ERB + def template_for(file, page = true, klass = ERB) template = @template_cache[file] return template if template @@ -743,18 +682,131 @@ def template_for file, page = true, klass = ERB erbout = 'io' else template = file.read - template = template.encode @options.encoding if - Object.const_defined? :Encoding + template = template.encode @options.encoding file_var = File.basename(file).sub(/\..*/, '') erbout = "_erbout_#{file_var}" end - template = klass.new template, nil, '<>', erbout + template = klass.new template, trim_mode: '-', eoutvar: erbout @template_cache[file] = template template end -end + # :stopdoc: + ParagraphExcerptRegexpOther = %r[\b\w[^./:]++\.] + # use \p/\P{letter} instead of \w/\W in Unicode + ParagraphExcerptRegexpUnicode = %r[\b\p{letter}[^./:]++\.] + # :startdoc: + + # Returns an excerpt of the comment for usage in meta description tags + def excerpt(comment) + text = case comment + when RDoc::Comment + comment.text + else + comment + end + + # Match from a capital letter to the first period, discarding any links, so + # that we don't end up matching badges in the README + pattern = ParagraphExcerptRegexpUnicode + begin + first_paragraph_match = text.match(pattern) + rescue Encoding::CompatibilityError + # The doc is non-ASCII text and encoded in other than Unicode base encodings. + raise if pattern == ParagraphExcerptRegexpOther + pattern = ParagraphExcerptRegexpOther + retry + end + return text[0...150].tr_s("\n", " ").squeeze(" ") unless first_paragraph_match + + extracted_text = first_paragraph_match[0] + second_paragraph = text.match(pattern, first_paragraph_match.end(0)) + extracted_text << " " << second_paragraph[0] if second_paragraph + + extracted_text[0...150].tr_s("\n", " ").squeeze(" ") + end + + def generate_ancestor_list(ancestors, klass) + return '' if ancestors.empty? + + ancestor = ancestors.shift + content = +'
  • ' + + if ancestor.is_a?(RDoc::NormalClass) + content << "#{ancestor.full_name}" + else + content << ancestor.to_s + end + + # Recursively call the method for the remaining ancestors + content << generate_ancestor_list(ancestors, klass) + + content << '
' + end + + def generate_class_link(klass, rel_prefix) + if klass.display? + %(#{klass.name}) + else + %(#{klass.name}) + end + end + + def generate_class_index_content(classes, rel_prefix) + grouped_classes = group_classes_by_namespace_for_sidebar(classes) + return '' unless top = grouped_classes[nil] + + solo = top.one? { |klass| klass.display? } + traverse_classes(top, grouped_classes, rel_prefix, solo) + end + + def traverse_classes(klasses, grouped_classes, rel_prefix, solo = false) + content = +'" + end + + def group_classes_by_namespace_for_sidebar(classes) + grouped_classes = classes.group_by do |klass| + klass.full_name[/\A[^:]++(?:::[^:]++(?=::))*+(?=::[^:]*+\z)/] + end.select do |_, klasses| + klasses.any?(&:display?) + end + grouped_classes.values.each(&:uniq!) + grouped_classes + end + + private + + def nesting_namespaces_to_class_modules(klass) + tree = {} + + klass.nesting_namespaces.zip(klass.fully_qualified_nesting_namespaces) do |ns, fqns| + tree[ns] = @store.classes_hash[fqns] || @store.modules_hash[fqns] + end + + tree + end + + def generate_nesting_namespaces_breadcrumb(klass, rel_prefix) + nesting_namespaces_to_class_modules(klass).map do |namespace, class_module| + path = class_module ? (rel_prefix + class_module.path).to_s : "" + { name: namespace, path: path, self: klass.full_name == class_module&.full_name } + end + end +end diff --git a/lib/rdoc/generator/json_index.rb b/lib/rdoc/generator/json_index.rb index c4c5830bb8..065caa47ea 100644 --- a/lib/rdoc/generator/json_index.rb +++ b/lib/rdoc/generator/json_index.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true require 'json' begin require 'zlib' @@ -85,12 +86,10 @@ class RDoc::Generator::JsonIndex attr_reader :index # :nodoc: ## - # Creates a new generator. +parent_generator+ is used to determine the - # class_dir and file_dir of links in the output index. - # + # Creates a new generator. # +options+ are the same options passed to the parent generator. - def initialize parent_generator, options + def initialize(parent_generator, options) @parent_generator = parent_generator @store = parent_generator.store @options = options @@ -141,17 +140,20 @@ def generate FileUtils.mkdir_p index_file.dirname, :verbose => $DEBUG_RDOC index_file.open 'w', 0644 do |io| - io.set_encoding Encoding::UTF_8 if Object.const_defined? :Encoding + io.set_encoding Encoding::UTF_8 io.write 'var search_data = ' JSON.dump data, io, 0 end + unless ENV['SOURCE_DATE_EPOCH'].nil? + index_file.utime index_file.atime, Time.at(ENV['SOURCE_DATE_EPOCH'].to_i).gmtime + end Dir.chdir @template_dir do Dir['**/*.js'].each do |source| dest = File.join out_dir, source - FileUtils.install source, dest, :mode => 0644, :verbose => $DEBUG_RDOC + FileUtils.install source, dest, :mode => 0644, :preserve => true, :verbose => $DEBUG_RDOC end end end @@ -160,7 +162,7 @@ def generate # Compress the search_index.js file using gzip def generate_gzipped - return unless defined?(Zlib) + return if @options.dry_run or not defined?(Zlib) debug_msg "Compressing generated JSON index" out_dir = @base_dir + @options.op_dir @@ -169,7 +171,7 @@ def generate_gzipped outfile = out_dir + "#{search_index_file}.gz" debug_msg "Reading the JSON index file from %s" % search_index_file - search_index = search_index_file.read + search_index = search_index_file.read(mode: 'r:utf-8') debug_msg "Writing gzipped search index to %s" % outfile @@ -226,9 +228,9 @@ def index_classes def index_methods debug_msg " generating method search index" - list = @classes.uniq.map do |klass| + list = @classes.uniq.flat_map do |klass| klass.method_list - end.flatten.sort_by do |method| + end.sort_by do |method| [method.name, method.parent.full_name] end @@ -261,21 +263,7 @@ def index_pages end end - ## - # The directory classes are written to - - def class_dir - @parent_generator.class_dir - end - - ## - # The directory files are written to - - def file_dir - @parent_generator.file_dir - end - - def reset files, classes # :nodoc: + def reset(files, classes) # :nodoc: @files = files @classes = classes @@ -289,9 +277,8 @@ def reset files, classes # :nodoc: ## # Removes whitespace and downcases +string+ - def search_string string + def search_string(string) string.downcase.gsub(/\s/, '') end end - diff --git a/lib/rdoc/generator/markup.rb b/lib/rdoc/generator/markup.rb index 788e5a485d..1c39687040 100644 --- a/lib/rdoc/generator/markup.rb +++ b/lib/rdoc/generator/markup.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # Handle common RDoc::Markup tasks for various CodeObjects # @@ -33,7 +34,7 @@ def description def formatter return @formatter if defined? @formatter - options = @store.rdoc.options + options = @store.options this = RDoc::Context === self ? self : @parent @formatter = RDoc::Markup::ToHtmlCrossref.new options, this.path, this @@ -54,6 +55,18 @@ def cvs_url(url, full_path) end end + ## + # The preferred URL for this object. + + def canonical_url + options = @store.options + if path + File.join(options.canonical_root, path.to_s) + else + options.canonical_root + end + end + end class RDoc::CodeObject @@ -64,16 +77,6 @@ class RDoc::CodeObject class RDoc::MethodAttr - @add_line_numbers = false - - class << self - ## - # Allows controlling whether #markup_code adds line numbers to - # the source code. - - attr_accessor :add_line_numbers - end - ## # Prepend +src+ with line numbers. Relies on the first line of a source # code listing having: @@ -105,7 +108,7 @@ def add_line_numbers(src) ## # Turns the method's token stream into HTML. # - # Prepends line numbers if +add_line_numbers+ is true. + # Prepends line numbers if +options.line_numbers+ is true. def markup_code return '' unless @token_stream @@ -118,14 +121,14 @@ def markup_code lines.shift if src =~ /\A.*#\ *File/i # remove '# File' comment lines.each do |line| if line =~ /^ *(?=\S)/ - n = $&.length + n = $~.end(0) indent = n if n < indent break if n == 0 end end src.gsub!(/^#{' ' * indent}/, '') if indent > 0 - add_line_numbers(src) if RDoc::MethodAttr.add_line_numbers + add_line_numbers(src) if options.line_numbers src end @@ -156,7 +159,7 @@ class RDoc::TopLevel # command line option to set. def cvs_url - url = @store.rdoc.options.webcvs + url = @store.options.webcvs if /%s/ =~ url then url % @relative_name @@ -166,4 +169,3 @@ def cvs_url end end - diff --git a/lib/rdoc/generator/pot.rb b/lib/rdoc/generator/pot.rb index db6f3a0354..a20fde077b 100644 --- a/lib/rdoc/generator/pot.rb +++ b/lib/rdoc/generator/pot.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # Generates a POT file. # @@ -64,7 +65,7 @@ class RDoc::Generator::POT ## # Set up a new .pot generator - def initialize store, options #:not-new: + def initialize(store, options) #:not-new: @options = options @store = store end @@ -80,18 +81,14 @@ def generate end end - def class_dir - nil - end - private def extract_messages extractor = MessageExtractor.new(@store) extractor.extract end - autoload :MessageExtractor, 'rdoc/generator/pot/message_extractor' - autoload :PO, 'rdoc/generator/pot/po' - autoload :POEntry, 'rdoc/generator/pot/po_entry' + require_relative 'pot/message_extractor' + require_relative 'pot/po' + require_relative 'pot/po_entry' end diff --git a/lib/rdoc/generator/pot/message_extractor.rb b/lib/rdoc/generator/pot/message_extractor.rb index ceabc5262a..ee6d847bd6 100644 --- a/lib/rdoc/generator/pot/message_extractor.rb +++ b/lib/rdoc/generator/pot/message_extractor.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # Extracts message from RDoc::Store @@ -6,7 +7,7 @@ class RDoc::Generator::POT::MessageExtractor ## # Creates a message extractor for +store+. - def initialize store + def initialize(store) @store = store @po = RDoc::Generator::POT::PO.new end @@ -24,21 +25,21 @@ def extract private - def extract_from_klass klass + def extract_from_klass(klass) extract_text(klass.comment_location, klass.full_name) klass.each_section do |section, constants, attributes| - extract_text(section.title ,"#{klass.full_name}: section title") + extract_text(section.title, "#{klass.full_name}: section title") section.comments.each do |comment| extract_text(comment, "#{klass.full_name}: #{section.title}") end end - klass.each_constant do |constant| + klass.constants.each do |constant| extract_text(constant.comment, constant.full_name) end - klass.each_attribute do |attribute| + klass.attributes.each do |attribute| extract_text(attribute.comment, attribute.full_name) end @@ -47,7 +48,7 @@ def extract_from_klass klass end end - def extract_text text, comment, location = nil + def extract_text(text, comment, location = nil) return if text.nil? options = { @@ -60,7 +61,7 @@ def extract_text text, comment, location = nil end end - def entry msgid, options + def entry(msgid, options) RDoc::Generator::POT::POEntry.new(msgid, options) end diff --git a/lib/rdoc/generator/pot/po.rb b/lib/rdoc/generator/pot/po.rb index 6a6b5821f3..447cb60ead 100644 --- a/lib/rdoc/generator/pot/po.rb +++ b/lib/rdoc/generator/pot/po.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # Generates a PO format text @@ -14,7 +15,7 @@ def initialize ## # Adds a PO entry to the PO. - def add entry + def add(entry) existing_entry = @entries[entry.msgid] if existing_entry entry = existing_entry.merge(entry) @@ -28,8 +29,8 @@ def add entry def to_s po = '' sort_entries.each do |entry| - po << "\n" unless po.empty? - po << entry.to_s + po += "\n" unless po.empty? + po += entry.to_s end po end diff --git a/lib/rdoc/generator/pot/po_entry.rb b/lib/rdoc/generator/pot/po_entry.rb index d4cef59ee9..8de260eef1 100644 --- a/lib/rdoc/generator/pot/po_entry.rb +++ b/lib/rdoc/generator/pot/po_entry.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # A PO entry in PO @@ -22,10 +23,10 @@ class RDoc::Generator::POT::POEntry attr_reader :flags ## - # Creates a PO entry for +msgid+. Other valus can be specified by + # Creates a PO entry for +msgid+. Other values can be specified by # +options+. - def initialize msgid, options = {} + def initialize(msgid, options = {}) @msgid = msgid @msgstr = options[:msgstr] || "" @translator_comment = options[:translator_comment] @@ -39,11 +40,11 @@ def initialize msgid, options = {} def to_s entry = '' - entry << format_translator_comment - entry << format_extracted_comment - entry << format_references - entry << format_flags - entry << <<-ENTRY + entry += format_translator_comment + entry += format_extracted_comment + entry += format_references + entry += format_flags + entry += <<-ENTRY msgid #{format_message(@msgid)} msgstr #{format_message(@msgstr)} ENTRY @@ -52,7 +53,7 @@ def to_s ## # Merges the PO entry with +other_entry+. - def merge other_entry + def merge(other_entry) options = { :extracted_comment => merge_string(@extracted_comment, other_entry.extracted_comment), @@ -68,15 +69,15 @@ def merge other_entry private - def format_comment mark, comment + def format_comment(mark, comment) return '' unless comment return '' if comment.empty? formatted_comment = '' comment.each_line do |line| - formatted_comment << "#{mark} #{line}" + formatted_comment += "#{mark} #{line}" end - formatted_comment << "\n" unless formatted_comment.end_with?("\n") + formatted_comment += "\n" unless formatted_comment.end_with?("\n") formatted_comment end @@ -93,7 +94,7 @@ def format_references formatted_references = '' @references.sort.each do |file, line| - formatted_references << "\#: #{file}:#{line}\n" + formatted_references += "\#: #{file}:#{line}\n" end formatted_references end @@ -105,18 +106,18 @@ def format_flags "\#, #{formatted_flags}\n" end - def format_message message + def format_message(message) return "\"#{escape(message)}\"" unless message.include?("\n") formatted_message = '""' message.each_line do |line| - formatted_message << "\n" - formatted_message << "\"#{escape(line)}\"" + formatted_message += "\n" + formatted_message += "\"#{escape(line)}\"" end formatted_message end - def escape string + def escape(string) string.gsub(/["\\\t\n]/) do |special_character| case special_character when "\t" @@ -129,11 +130,11 @@ def escape string end end - def merge_string string1, string2 + def merge_string(string1, string2) [string1, string2].compact.join("\n") end - def merge_array array1, array2 + def merge_array(array1, array2) (array1 + array2).uniq end diff --git a/lib/rdoc/generator/ri.rb b/lib/rdoc/generator/ri.rb index b9c4141a5e..32f518ac71 100644 --- a/lib/rdoc/generator/ri.rb +++ b/lib/rdoc/generator/ri.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ## # Generates ri data files @@ -13,7 +14,7 @@ class RDoc::Generator::RI ## # Set up a new ri generator - def initialize store, options #:not-new: + def initialize(store, options) #:not-new: @options = options @store = store @store.path = '.' @@ -27,4 +28,3 @@ def generate end end - diff --git a/lib/rdoc/generator/template/darkfish/_footer.rhtml b/lib/rdoc/generator/template/darkfish/_footer.rhtml index fe5822cc6b..9791b42901 100644 --- a/lib/rdoc/generator/template/darkfish/_footer.rhtml +++ b/lib/rdoc/generator/template/darkfish/_footer.rhtml @@ -1,5 +1,5 @@ diff --git a/lib/rdoc/generator/template/darkfish/_head.rhtml b/lib/rdoc/generator/template/darkfish/_head.rhtml index 70f1c188d6..7376fc390e 100644 --- a/lib/rdoc/generator/template/darkfish/_head.rhtml +++ b/lib/rdoc/generator/template/darkfish/_head.rhtml @@ -1,19 +1,48 @@ + <%= h @title %> +<%- if defined?(klass) -%> + "> + + <%- if klass.comment.empty? -%> + "> + <%- else -%> + "> + <%- end -%> +<%- elsif defined?(file) -%> + + "> +<%- elsif @title -%> + + + <%- if @options.main_page and + main_page = @files.find { |f| f.full_name == @options.main_page } then %> + "> + <%- else -%> + + <%- end -%> +<%- end -%> + +<%- if canonical_url = @options.canonical_root -%> +<% canonical_url = current.canonical_url if defined?(current) %> + +<%- end -%> + - - - - - -<% if @options.template_stylesheets.flatten.any? then %> -<% @options.template_stylesheets.flatten.each do |stylesheet| %> - -<% end %> -<% end %> + + + + + + + +<%- @options.template_stylesheets.each do |stylesheet| -%> + +<%- end -%> diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml deleted file mode 100644 index e889f8063d..0000000000 --- a/lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml +++ /dev/null @@ -1,19 +0,0 @@ -<% if !svninfo.empty? then %> - -<% end %> diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml index fe54d8339f..d33ecd43f7 100644 --- a/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml +++ b/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml @@ -1,9 +1,5 @@ diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml index 2bd8efee99..067bd62edd 100644 --- a/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +++ b/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml @@ -1,15 +1,15 @@ -<% unless klass.extends.empty? then %> +<%- unless klass.extends.empty? then %> -<% end %> +<%- end -%> diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml deleted file mode 100644 index 0ba1d2be80..0000000000 --- a/lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml index d141098ecd..04846f84fb 100644 --- a/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +++ b/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml @@ -1,15 +1,15 @@ -<% unless klass.includes.empty? then %> +<%- unless klass.includes.empty? then %> -<% end %> +<%- end -%> diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml index 1285bfd732..faed7e0a94 100644 --- a/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +++ b/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml @@ -2,14 +2,14 @@

Documentation

    - <% installed.each do |name, href, exists, type, _| %> - <% next if type == :extra %> + <%- installed.each do |name, href, exists, type, _| -%> + <%- next if type == :extra -%>
  • - <% if exists then %> + <%- if exists then -%> <%= h name %> - <% else %> + <%- else -%> <%= h name %> - <% end %> - <% end %> + <%- end -%> + <%- end -%>
diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml index 45df08d8fe..d09216a0f6 100644 --- a/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml +++ b/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml @@ -1,12 +1,21 @@ -<% unless klass.method_list.empty? then %> - - +<% if (instance_methods = klass.instance_methods.sort).any? %> + <% end %> diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml index 5f39825f08..3f68f0c0dc 100644 --- a/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +++ b/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml @@ -1,12 +1,32 @@ -<% simple_files = @files.select { |f| f.text? } %> -<% unless simple_files.empty? then %> +<%- simple_files = @files.select { |f| f.text? } %> +<%- if defined?(current) -%> + <%- dir = current.full_name[%r{\A[^/]+(?=/)}] || current.page_name -%> +<%- end -%> +<%- unless simple_files.empty? then -%> -<% end %> +<%- end -%> diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml index cc04852652..6808b2bf87 100644 --- a/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml +++ b/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml @@ -1,11 +1,6 @@ -<% if klass.type == 'class' then %> +<%- if klass.type == 'class' && (ancestors = klass.super_classes).any? -%> -<% end %> +<%- end -%> diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml index 9c49b31376..afc7f7b88d 100644 --- a/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml +++ b/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml @@ -3,7 +3,7 @@
diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml index 15ff78ba91..6dcd2ae81f 100644 --- a/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +++ b/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml @@ -1,11 +1,11 @@ -<% unless klass.sections.length == 1 then %> +<%- unless klass.sections.length == 1 then %> -<% end %> +<%- end -%> diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml index b58e6b3c61..b1e047b5f7 100644 --- a/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +++ b/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml @@ -1,18 +1,39 @@ -<% comment = if current.respond_to? :comment_location then +<%- comment = if current.respond_to? :comment_location then current.comment_location else current.comment end - table = current.parse(comment).table_of_contents + table = current.parse(comment).table_of_contents.dup if table.length > 1 then %> -<% end %> +<%- end -%> diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_toggle.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_toggle.rhtml new file mode 100644 index 0000000000..ed2cbe31a0 --- /dev/null +++ b/lib/rdoc/generator/template/darkfish/_sidebar_toggle.rhtml @@ -0,0 +1,3 @@ + diff --git a/lib/rdoc/generator/template/darkfish/class.rhtml b/lib/rdoc/generator/template/darkfish/class.rhtml index b497000112..628945d886 100644 --- a/lib/rdoc/generator/template/darkfish/class.rhtml +++ b/lib/rdoc/generator/template/darkfish/class.rhtml @@ -1,23 +1,39 @@ -