diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..94143827 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +Dockerfile diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 00000000..802b7513 --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,39 @@ +--- +version: 2 +updates: + - package-ecosystem: 'bundler' + directory: '/' + schedule: + interval: 'weekly' + commit-message: + prefix: 'chore(deps)' + groups: + dependencies: + applies-to: version-updates + update-types: + - 'minor' + - 'patch' + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'weekly' + commit-message: + prefix: 'chore(deps)' + groups: + dependencies: + applies-to: version-updates + update-types: + - 'minor' + - 'patch' + - package-ecosystem: 'docker' + directory: '/' + schedule: + interval: 'weekly' + commit-message: + prefix: 'chore(deps)' + groups: + dependencies: + applies-to: version-updates + update-types: + - 'minor' + - 'patch' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..50ccc50b --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,61 @@ +name: CI +on: [push, pull_request] + +env: + JRUBY_OPTS: -Xcext.enabled=true + +permissions: + contents: read + +jobs: + build: + name: "Test / Ruby ${{ matrix.ruby }}" + runs-on: ubuntu-latest + strategy: + matrix: + ruby: + - "3.1" + - "3.2" + - "3.3" + - "3.4" + fail-fast: false + + steps: + - name: Checkout + uses: actions/checkout@v4.2.2 + with: + fetch-depth: 10 + + - uses: ruby/setup-ruby@354a1ad156761f5ee2b7b13fa8e09943a5e8d252 # v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + + - uses: actions/setup-python@v5.5.0 + with: + # This should match lib/github/markups.rb GitHub::Markups::MARKUP_RST + python-version: "3.x" + + - uses: actions/cache@v4.2.3 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip + + - name: Install Perl dependencies + run: | + curl -1sLf \ + 'https://dl.cloudsmith.io/public/nxadm-pkgs/rakudo-pkg/setup.deb.sh' \ + | sudo -E bash + sudo apt-get update -qq + sudo apt-get install perl rakudo-pkg + + curl -L http://cpanmin.us | perl - --sudo App::cpanminus + sudo cpanm --installdeps --notest Pod::Simple + + - name: Install Python dependencies + run: python -m pip install docutils + + - name: Run rake + run: | + export PATH=$PATH:/.perl6/bin:/opt/rakudo-pkg/bin + bundle exec rake diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 00000000..84cbf0ed --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,27 @@ +name: Mark stale issues and pull requests + +on: + schedule: + - cron: "0 12 * * *" + +jobs: + stale: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + + steps: + - uses: actions/stale@v9.1.0 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: > + This issue has been automatically marked as stale because it has not + had recent activity. It will be closed if no further activity occurs. + Thank you for your contributions. + stale-pr-message: > + This pull request has been automatically marked as stale because it has not + had recent activity. It will be closed if no further activity occurs. + Thank you for your contributions. + exempt-issue-labels: keep + exempt-pr-labels: keep diff --git a/.gitignore b/.gitignore index a08b381b..b0f0821c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,10 @@ *.pyc pkg/ .bundle -Gemfile.lock +.project +.buildpath +*~ vendor/ +.DS_Store +.venv +venv diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0a44f56e..00000000 --- a/.travis.yml +++ /dev/null @@ -1,11 +0,0 @@ -language: ruby -before_install: sudo pip install docutils -rvm: - - 1.9.3 - - 2.0.0 - - 2.1.1 - - jruby-19mode -jdk: - - oraclejdk8 -notifications: - email: false diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..16e77760 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [opensource@github.com](mailto:opensource@github.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [https://contributor-covenant.org/version/1/4][version] + +[homepage]: https://contributor-covenant.org +[version]: https://contributor-covenant.org/version/1/4/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 57ba6e97..2c83e31e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,65 +1,40 @@ # Contributing -Want to contribute? Great! +Contributions to this project are [released](https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license) to the public under the [project's open source license](LICENSE). -1. Fork it. -2. Create a branch (`git checkout -b my_markup`) -3. Commit your changes (`git commit -am "Added Snarkdown"`) -4. Push to the branch (`git push origin my_markup`) -5. Open a [Pull Request][1] -6. Enjoy a refreshing Diet Coke and wait - - -There are two ways to add markups. - -### Commands - -If your markup is in a language other than Ruby, drop a translator -script in `lib/github/commands` which accepts input on STDIN and -returns HTML on STDOUT. See [rest2html][r2h] for an example. +This project adheres to a [Code of Conduct][code-of-conduct]. By participating, you are expected to honor this code. -Once your script is in place, edit `lib/github/markups.rb` and tell -GitHub Markup about it. Again we look to [rest2html][r2hc] for -guidance: +[code-of-conduct]: CODE_OF_CONDUCT.md - command(:rest2html, /re?st(.txt)?/) +This library's only job is to decide which markup format to use and call out to an external library to convert the markup to HTML (see the [README](README.md) for more information on how markup is rendered on GitHub.com). -Here we're telling GitHub Markup of the existence of a `rest2html` -command which should be used for any file ending in `rest`, -`rst`, `rest.txt` or `rst.txt`. Any regular expression will do. +If you are having an issue with: -Finally add your [tests](#testing). +* **Syntax highlighting** - see [github/linguist](https://github.com/github/linguist/blob/master/CONTRIBUTING.md#fixing-syntax-highlighting) +* **Markdown on GitHub** - contact [GitHub Support](https://support.github.com/) +* **Styling issues on GitHub** - see [primer-markdown](https://github.com/primer/primer-css/tree/master/modules/primer-markdown) module in the [primer/primer-css](https://github.com/primer/primer-css) repository -### Classes +Anything else - [search open issues](https://github.com/github/markup/issues) or create an issue and and we'll help point you in the right direction. -If your markup can be translated using a Ruby library, that's -great. Check out `lib/github/markups.rb` for some -examples. Let's look at Markdown: +## Submitting a Pull Request - markup(:markdown, /md|mkdn?|markdown/) do |content| - Markdown.new(content).to_html - end - -We give the `markup` method three bits of information: the name of the -file to `require`, a regular expression for extensions to match, and a -block to run with unformatted markup which should return HTML. +1. Fork it. +2. Create a branch (`git checkout -b my_markup`) +3. Commit your changes (`git commit -am "Added Snarkdown"`) +4. Push to the branch (`git push origin my_markup`) +5. Open a [Pull Request][1] +6. Enjoy a refreshing Diet Coke and wait -If you need to monkeypatch a RubyGem or something, check out the -included RDoc example. +**dependencies** -Finally add your [tests](#testing). +You can run `script/bootstrap.contrib` to fetch them all. -### Testing +## Testing To run the tests: $ rake -When adding support for a new markup library, create a `README.extension` in `test/markups` along with a `README.extension.html`. As you may imagine, the `README.extension` should be your known input and the -`README.extension.html` should be the desired output. - -Now run the tests: `rake` - If nothing complains, congratulations! ## Releasing a new version diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..aa0f09aa --- /dev/null +++ b/Dockerfile @@ -0,0 +1,39 @@ +FROM ubuntu:trusty + +RUN apt-get update -qq +RUN apt-get install -y apt-transport-https + +RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 379CE192D401AB61 +RUN echo "deb https://dl.bintray.com/nxadm/rakudo-pkg-debs `lsb_release -cs` main" | tee -a /etc/apt/sources.list.d/rakudo-pkg.list +RUN apt-get update -qq + +RUN apt-get install -y \ + perl rakudo-pkg curl git build-essential python python-pip \ + libssl-dev libreadline-dev zlib1g-dev \ + libicu-dev cmake pkg-config + +ENV PATH $PATH:/opt/rakudo-pkg/bin +RUN install-zef-as-user && zef install Pod::To::HTML + +RUN curl -L http://cpanmin.us | perl - App::cpanminus +RUN cpanm --installdeps --notest Pod::Simple + +RUN pip install docutils + +ENV PATH $PATH:/root/.rbenv/bin:/root/.rbenv/shims +RUN curl -fsSL https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-installer | bash +RUN rbenv install 2.4.1 +RUN rbenv global 2.4.1 +RUN rbenv rehash + +RUN gem install bundler + +WORKDIR /data/github-markup +COPY github-markup.gemspec . +COPY Gemfile . +COPY Gemfile.lock . +COPY lib/github-markup.rb lib/github-markup.rb +RUN bundle + +ENV LC_ALL en_US.UTF-8 +RUN locale-gen en_US.UTF-8 diff --git a/Gemfile b/Gemfile index 2e980fcc..bcd13f88 100644 --- a/Gemfile +++ b/Gemfile @@ -1,13 +1,18 @@ -source "http://rubygems.org" +source "https://rubygems.org" gemspec -gem "posix-spawn", :platforms => :ruby gem "redcarpet", :platforms => :ruby gem "kramdown", :platforms => :jruby gem "RedCloth" -gem "rdoc", "~>3.6" -gem "org-ruby", "= 0.9.9" -gem "creole", "~>0.3.6" -gem "wikicloth", "=0.8.1", :platforms => :ruby -gem "asciidoctor", "= 0.1.4" -gem "rake" \ No newline at end of file +# using a tag version here because 0.18.3 was not published by the author to encourage users to upgrade. +# however we want to bump up to this version since this has a security patch +gem "commonmarker", git: "https://github.com/gjtorikian/commonmarker.git", tag: "v0.18.3" +gem "rdoc", "~> 6.13.1" +gem "org-ruby", "0.9.12" +gem "creole", "~>0.5.0" +gem "wikicloth", "=0.8.3" +gem "twitter-text", "~> 1.14" +gem "asciidoctor", "~> 2.0.5" +gem "rake" +gem "rexml" +gem "nokogiri", "~> 1.18.4" diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 00000000..7e738e4d --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,143 @@ +GIT + remote: https://github.com/gjtorikian/commonmarker.git + revision: 2838ebaa83ee0081d481c21f3bc0e4cb3e8de9da + tag: v0.18.3 + specs: + commonmarker (0.18.3) + ruby-enum (~> 0.5) + +PATH + remote: . + specs: + github-markup (5.0.1) + +GEM + remote: https://rubygems.org/ + specs: + RedCloth (4.3.4) + activesupport (7.1.5.1) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.0.2) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + mutex_m + securerandom (>= 0.3) + tzinfo (~> 2.0) + asciidoctor (2.0.23) + base64 (0.2.0) + benchmark (0.4.0) + bigdecimal (3.1.9) + builder (3.3.0) + cgi (0.4.2) + charlock_holmes (0.7.9) + concurrent-ruby (1.3.5) + connection_pool (2.5.0) + crass (1.0.6) + creole (0.5.0) + date (3.4.1) + drb (2.2.1) + expression_parser (0.9.0) + github-linguist (9.1.0) + cgi + charlock_holmes (~> 0.7.7) + mini_mime (~> 1.0) + rugged (~> 1.0) + html-pipeline (1.11.0) + activesupport (>= 2) + nokogiri (~> 1.4) + htmlentities (4.3.4) + i18n (1.14.7) + concurrent-ruby (~> 1.0) + logger (1.7.0) + mini_mime (1.1.5) + mini_portile2 (2.8.8) + minitest (5.25.5) + mutex_m (0.3.0) + nokogiri (1.18.7) + mini_portile2 (~> 2.8.2) + racc (~> 1.4) + nokogiri (1.18.7-aarch64-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.7-arm-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.7-arm64-darwin) + racc (~> 1.4) + nokogiri (1.18.7-x86_64-darwin) + racc (~> 1.4) + nokogiri (1.18.7-x86_64-linux-gnu) + racc (~> 1.4) + nokogiri-diff (0.3.0) + nokogiri (~> 1.5) + tdiff (~> 0.4) + org-ruby (0.9.12) + rubypants (~> 0.2) + psych (5.2.3) + date + stringio + racc (1.8.1) + rake (13.2.1) + rdoc (6.13.1) + psych (>= 4.0.0) + redcarpet (3.6.1) + rexml (3.4.1) + ruby-enum (0.9.0) + i18n + rubypants (0.7.1) + rugged (1.9.0) + sanitize (6.1.3) + crass (~> 1.0.2) + nokogiri (>= 1.12.0) + securerandom (0.3.2) + stringio (3.1.6) + tdiff (0.4.0) + twitter-text (1.14.7) + unf (~> 0.1.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unf (0.1.4) + unf_ext + unf_ext (0.0.9.1) + wikicloth (0.8.3) + builder + expression_parser + htmlentities + nokogiri + twitter-text + +PLATFORMS + aarch64-linux + arm-linux + arm64-darwin + x86-linux + x86_64-darwin + x86_64-linux + +DEPENDENCIES + RedCloth + activesupport (~> 7.1.5) + asciidoctor (~> 2.0.5) + commonmarker! + creole (~> 0.5.0) + github-linguist (>= 7.1.3) + github-markup! + html-pipeline (~> 1.0) + kramdown + minitest (~> 5.4, >= 5.4.3) + nokogiri (~> 1.18.4) + nokogiri-diff (~> 0.3.0) + org-ruby (= 0.9.12) + rake + rdoc (~> 6.13.1) + redcarpet + rexml + sanitize (>= 4.6.3) + twitter-text (~> 1.14) + wikicloth (= 0.8.3) + +BUNDLED WITH + 2.5.9 diff --git a/HISTORY.md b/HISTORY.md index 2c2ca4e2..745a9c1b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,123 @@ +## 5.0.1 - 2024-06-17 +* Bump activesupport from 4.0 to 7.1.3.4 + +## 5.0.0 - 2024-06-17 +* Drop support for Ruby versions < 3 +* Bump nokogiri from 1.8.1 to 1.16.5 +* Bump nokogiri-diff from 0.2.0 to 0.3.0 +* Bump rdoc from 3.6 to 6.7.0 +* Update CommandImplementation to better support large files (affecting RST and POD6 rendering) + +## 4.0.2 - 2023-10-10 +* Add support for .mdx files in markdown + +## 4.0.1 - 2022-03-07 +* Update to commonmarker 0.18.3; There isn't a version on RubyGems for this, so this is pointing to a [tag version on GitHub](https://github.com/gjtorikian/commonmarker/blob/v0.18.3/commonmarker.gemspec) + +## 4.0.0 - 2021-03-31 + +* Drop support for Python 2 in RST rendering [#1456](https://github.com/github/markup/pull/1456) + +## 3.0.5 - 2020-11-12 + +* Add commonmarker_exts to commonmarker options [#1268](https://github.com/github/markup/pull/1268) +* Check whether filename is set when rendering Asciidoc. [#1290](https://github.com/github/markup/pull/1290) + +## 3.0.4 - 2019-04-03 + +* Expose options in #render_s [#1249](https://github.com/github/markup/pull/1249) +* Upgrade to Asciidoctor 2.0.x [#1264](https://github.com/github/markup/pull/1264) + +## 3.0.3 - 2018-12-17 + +* Temporarily remove support for POD6 [#1248](https://github.com/github/markup/pull/1248) + +## 3.0.2 - 2018-12-12 + +* Add support for POD6 [#1173](https://github.com/github/markup/pull/1173) + +## 3.0.1 - 2018-10-19 + +* Remove linguist-detected RMarkdown files from the Markdown renderer [#1237](https://github.com/github/markup/pull/1237) + +## 3.0.0 - 2018-10-18 + +* Allow passing options through to CommonMarker [#1236](https://github.com/github/markup/pull/1236) +* Symlink option is now a keyword arg [#1236](https://github.com/github/markup/pull/1236) + +## 2.0.2 - 2018-10-15 + +* Don't render rmd files as Markdown [#1235](https://github.com/github/markup/pull/1235) + +## 2.0.1 - 2018-06-29 + +* Create anchor for every =item directive in POD files [#1165](https://github.com/github/markup/pull/1165) + +## 2.0.0 - 2018-01-31 + +* Remove filesystem access [#1157](https://github.com/github/markup/pull/1157) + +## 1.7.0 - 2018-01-30 + +### Changed + +* Updates for Linguist v6 [#1139](https://github.com/github/markup/pull/1139) +* Update to Nokogiri ~> 1.8; drop support for Ruby 2.0 [#1156](https://github.com/github/markup/pull/1156) + +## 1.6.2 - 2017-11-27 + +### Changed + +* Only report basename in usage [#1131](https://github.com/github/markup/pull/1131) +* rest2html parameter signature fix [#1082](https://github.com/github/markup/pull/1082) + +## 1.6.1 - 2017-07-25 + +### Changed + +* Added support for highlight directive in rST [#925](https://github.com/github/markup/pull/925) +* Fixes to documentation and code style [#1009](https://github.com/github/markup/pull/1009) [#1071](https://github.com/github/markup/pull/1071) [#1087](https://github.com/github/markup/pull/1087) +* Test against newer Ruby versions [#1086](https://github.com/github/markup/pull/1086) +* Upgrade to Asciidoctor 1.5.6.1 [#1088](https://github.com/github/markup/pull/1088) + +## 1.6.0 - 2017-04-03 + +### Changed + +* Added filename argument to all renderers for additional context +* Removed superfluous `rinku` dependency [#1035](https://github.com/github/markup/pull/1035) +* Enable source-to-source navigation for `.adoc` AsciiDoc files, plus additional attributes passed through [#1039](https://github.com/github/markup/pull/1039) and [#1041](https://github.com/github/markup/pull/1041) + +## 1.5.0 - 2017-03-27 + +### Added + +* Re-introduce [#537](https://github.com/github/markup/pull/537) to detect language of markup document + However `github-linguist` is optional and this gem will fallback to extensions for detection. + +[Full changelog](https://github.com/github/markup/compare/v1.4.9...v1.5.0) + +## 1.4.9 - 2017-03-27 + +### Changed + +* Reverted [#537](https://github.com/github/markup/pull/537) to avoid extra dependencies + +[Full changelog](https://github.com/github/markup/compare/v1.4.8...v1.4.9) + +## 1.3.3 (2015-02-17) + +* Address a slight typo with `POSIX` [#456](https://github.com/github/markup/pull/456) + +[Full changelog](https://github.com/github/markup/compare/v1.3.2...v1.3.3) + +## 1.3.2 (2015-02-17) + +* RST: Output code instead of tt for inline literals [#370](https://github.com/github/markup/pull/370) +* RST: Add IDs to headers so that `.. contents` works with `.. sectnum` [#391](https://github.com/github/markup/pull/391) + +[Full changelog](https://github.com/github/markup/compare/v1.3.1...v1.3.2) + ## 1.3.1 (2014-11-13) * Fix name error when trying to use newer versions of RedCarpet [#387](https://github.com/github/markup/pull/387) diff --git a/README.md b/README.md index 2b8f0911..12188dcb 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,17 @@ GitHub Markup ============= -We use this library on GitHub when rendering your README or any other -rich text file. The generated HTML is then run through filters in the [html-pipeline](https://github.com/jch/html-pipeline) to perform things like [sanitization](#html-sanitization) and [syntax highlighting](https://github.com/jch/html-pipeline/blob/master/lib/html/pipeline/syntax_highlight_filter.rb). +This library is the **first step** of a journey that every markup file in a repository goes on before it is rendered on GitHub.com: + +1. `github-markup` selects an _underlying library_ to convert the raw markup to HTML. See the list of [supported markup formats](#markups) below. +1. The HTML is sanitized, aggressively removing things that could harm you and your kin—such as `script` tags, inline-styles, and `class` or `id` attributes. +1. Syntax highlighting is performed on code blocks. See [github/linguist](https://github.com/github/linguist#syntax-highlighting) for more information about syntax highlighting. +1. The HTML is passed through other filters that add special sauce, such as emoji, task lists, named anchors, CDN caching for images, and autolinking. +1. The resulting HTML is rendered on GitHub.com. + +Please note that **only the first step** is covered by this gem — the rest happens on GitHub.com. In particular, `markup` itself does no sanitization of the resulting HTML, as it expects that to be covered by whatever pipeline is consuming the HTML. + +Please see our [contributing guidelines](CONTRIBUTING.md) before reporting an issue. Markups ------- @@ -10,63 +19,70 @@ Markups The following markups are supported. The dependencies listed are required if you wish to run the library. You can also run `script/bootstrap` to fetch them all. -* [.markdown, .mdown, .mkdn, .md](http://daringfireball.net/projects/markdown/) -- `gem install redcarpet` (https://github.com/vmg/redcarpet) -* [.textile](http://www.textism.com/tools/textile/) -- `gem install RedCloth` -* [.rdoc](http://rdoc.sourceforge.net/) -- `gem install rdoc -v 3.6.1` -* [.org](http://orgmode.org/) -- `gem install org-ruby` -* [.creole](http://wikicreole.org/) -- `gem install creole` -* [.mediawiki, .wiki](http://www.mediawiki.org/wiki/Help:Formatting) -- `gem install wikicloth` -* [.rst](http://docutils.sourceforge.net/rst.html) -- `easy_install docutils` +* [.markdown, .mdown, .mkdn, .md](http://daringfireball.net/projects/markdown/) -- `gem install commonmarker` (https://github.com/gjtorikian/commonmarker) +* [.textile](https://textile-lang.com/) -- `gem install RedCloth` (https://github.com/jgarber/redcloth) +* [.rdoc](https://ruby.github.io/rdoc/) -- `gem install rdoc -v 3.6.1` +* [.org](http://orgmode.org/) -- `gem install org-ruby` (https://github.com/wallyqs/org-ruby) +* [.creole](http://wikicreole.org/) -- `gem install creole` (https://github.com/larsch/creole) +* [.mediawiki, .wiki](http://www.mediawiki.org/wiki/Help:Formatting) -- `gem install wikicloth` (https://github.com/nricciar/wikicloth) +* [.rst](http://docutils.sourceforge.net/rst.html) -- `pip install docutils` * [.asciidoc, .adoc, .asc](http://asciidoc.org/) -- `gem install asciidoctor` (http://asciidoctor.org) -* [.pod](http://search.cpan.org/dist/perl/pod/perlpod.pod) -- `Pod::Simple::HTML` - comes with Perl >= 5.10. Lower versions should install [Pod::Simple](http://search.cpan.org/~dwheeler/Pod-Simple-3.28/lib/Pod/Simple.pod) from CPAN. +* [.pod](http://search.cpan.org/dist/perl/pod/perlpod.pod) -- `Pod::Simple::XHTML` + comes with Perl >= 5.10. Lower versions should install Pod::Simple from CPAN. Installation ----------- - gem install github-markup +``` +gem install github-markup +``` + +or + +``` +bundle install +``` + +from this directory. Usage ----- - require 'github/markup' - GitHub::Markup.render('README.markdown', "* One\n* Two") +Basic form: -Or, more realistically: +```ruby +require 'github/markup' - require 'github/markup' - GitHub::Markup.render(file, File.read(file)) +GitHub::Markup.render('README.markdown', "* One\n* Two") +``` -Contributing ------------- +More realistic form: -See [Contributing](CONTRIBUTING.md) +```ruby +require 'github/markup' -HTML sanitization ------------------ +GitHub::Markup.render(file, File.read(file)) +``` + +And a convenience form: -HTML rendered by the various markup language processors gets passed through an [HTML sanitization filter](https://github.com/jch/html-pipeline/blob/master/lib/html/pipeline/sanitization_filter.rb) for security reasons. HTML elements not in the whitelist are removed. HTML attributes not in the whitelist are removed from the preserved elements. +```ruby +require 'github/markup' -The following HTML elements, organized by category, are whitelisted: +GitHub::Markup.render_s(GitHub::Markups::MARKUP_MARKDOWN, "* One\n* Two") +``` -|Type | Elements -|------|---------- -|Headings | `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `h7`, `h8` -|Prose | `p`, `div`, `blockquote` -|Formatted | `pre` -| Inline | `b`, `i`, `strong`, `em`, `tt`, `code`, `ins`, `del`, `sup`, `sub`, `kbd`, `samp`, `q`, `var` -| Lists | `ol`, `ul`, `li`, `dl`, `dt`, `dd` -| Tables | `table`, `thead`, `tbody`, `tfoot`, `tr`, `td`, `th` -| Breaks | `br`, `hr` -| Ruby (East Asian) | `ruby`, `rt`, `rp` +Local Development +----------------- -The following attributes, organized by element, are whitelisted: +```sh +python3 -m venv .venv +source .venv/bin/activate +cd script +./bootstrap +``` -|Element | Attributes -|------|---------- -| `a` | `href` (`http://`, `https://`, `mailto://`, `github-windows://`, and `github-mac://` URI schemes and relative paths only) -| `img` | `src` (`http://` and `https://` URI schemes and relative paths only) -| `div` | `itemscope`, `itemtype` -| All | `abbr`, `accept`, `accept-charset`, `accesskey`, `action`, `align`, `alt`, `axis`, `border`, `cellpadding`, `cellspacing`, `char`, `charoff`, `charset`, `checked`, `cite`, `clear`, `cols`, `colspan`, `color`, `compact`, `coords`, `datetime`, `dir`, `disabled`, `enctype`, `for`, `frame`, `headers`, `height`, `hreflang`, `hspace`, `ismap`, `label`, `lang`, `longdesc`, `maxlength`, `media`, `method`, `multiple`, `name`, `nohref`, `noshade`, `nowrap`, `prompt`, `readonly`, `rel`, `rev`, `rows`, `rowspan`, `rules`, `scope`, `selected`, `shape`, `size`, `span`, `start`, `summary`, `tabindex`, `target`, `title`, `type`, `usemap`, `valign`, `value`, `vspace`, `width`, `itemprop` +Contributing +------------ -Note that the `id` attribute is *not* whitelisted. +See [Contributing](CONTRIBUTING.md). diff --git a/bin/github-markup b/bin/github-markup index 76e5e369..ec967359 100755 --- a/bin/github-markup +++ b/bin/github-markup @@ -1,10 +1,28 @@ #!/usr/bin/env ruby -$LOAD_PATH.unshift File.dirname(__FILE__) + "/../lib" +$LOAD_PATH.unshift File.dirname(File.realpath(__FILE__)) + "/../lib" require 'github/markup' -if ARGV[0] && File.exists?(file = ARGV[0]) - puts GitHub::Markup.render(file) -else - puts "usage: #$0 FILE" +if ARGV.size < 1 + print "usage: #{File.basename($0)} FILE [ FILES ... ]\n" + exit 1 end + +sources = [] + +ARGV.each { |s| + begin + file = File.open( s, "r" ) + sources.push [ s, file ] + rescue Exception => e + $stderr.print "error: #{e.message}\n" + exit 1 + ensure + end +} + +sources.each { |name, file| + print GitHub::Markup.render( name, file.read ) + file.close +} + diff --git a/github-markup.gemspec b/github-markup.gemspec index 62e4770b..4329a901 100644 --- a/github-markup.gemspec +++ b/github-markup.gemspec @@ -4,21 +4,28 @@ Gem::Specification.new do |s| s.name = "github-markup" s.version = GitHub::Markup::VERSION s.summary = "The code GitHub uses to render README.markup" - s.description = "This gem is used by GitHub to render any fancy markup such " + - "as Markdown, Textile, Org-Mode, etc. Fork it and add your own!" + s.description = <<~DESC + This gem is used by GitHub to render any fancy markup such as Markdown, + Textile, Org-Mode, etc. Fork it and add your own! + DESC s.authors = ["Chris Wanstrath"] s.email = "chris@ozmm.org" s.homepage = "https://github.com/github/markup" s.license = "MIT" + s.required_ruby_version = '>= 3.1.0' + s.files = `git ls-files`.split($\) s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) } s.test_files = s.files.grep(%r{^(test|spec|features)/}) s.require_paths = %w[lib] - s.add_development_dependency 'minitest', '~> 5.4.3' + s.add_development_dependency 'rake', '~> 12' + s.add_development_dependency 'activesupport', '~> 7.1.5' + s.add_development_dependency 'minitest', '~> 5.4', '>= 5.4.3' s.add_development_dependency 'html-pipeline', '~> 1.0' - s.add_development_dependency 'sanitize', '~> 2.1.0' - s.add_development_dependency 'nokogiri', '~> 1.6.1' - s.add_development_dependency 'nokogiri-diff', '~> 0.2.0' + s.add_development_dependency 'sanitize', '>= 4.6.3' + s.add_development_dependency 'nokogiri', '~> 1.18.4' + s.add_development_dependency 'nokogiri-diff', '~> 0.3.0' + s.add_development_dependency "github-linguist", ">= 7.1.3" end diff --git a/lib/github-markup.rb b/lib/github-markup.rb index 2f98a768..7c36ad17 100644 --- a/lib/github-markup.rb +++ b/lib/github-markup.rb @@ -1,6 +1,6 @@ module GitHub module Markup - VERSION = '1.3.1' + VERSION = '5.0.1' Version = VERSION end end diff --git a/lib/github/commands/pod2html b/lib/github/commands/pod2html new file mode 100755 index 00000000..aaed6022 --- /dev/null +++ b/lib/github/commands/pod2html @@ -0,0 +1,16 @@ +#!/usr/bin/env perl + +use strict; +use Pod::Simple::XHTML 3.11; + +my $p = Pod::Simple::XHTML->new; +$p->html_header(''); +$p->html_footer(''); +$p->perldoc_url_prefix('https://metacpan.org/pod/'); +$p->anchor_items(1); +$p->strip_verbatim_indent(sub { + my $lines = shift; + (my $indent = $lines->[0]) =~ s/\S.*//; + return $indent; +}); +$p->parse_from_file(shift); diff --git a/lib/github/commands/pod62html b/lib/github/commands/pod62html new file mode 100755 index 00000000..b2d27764 --- /dev/null +++ b/lib/github/commands/pod62html @@ -0,0 +1,5 @@ +#!/usr/bin/env perl6 + +use v6; + +slurp.put; diff --git a/lib/github/commands/rest2html b/lib/github/commands/rest2html index ca9f26ff..c6fc663e 100755 --- a/lib/github/commands/rest2html +++ b/lib/github/commands/rest2html @@ -31,9 +31,11 @@ import sys import os # This fixes docutils failing with unicode parameters to CSV-Table. The -S -# switch and the following 2 lines can be removed after upgrading to python 3. -reload(sys) -sys.setdefaultencoding('utf-8') +# switch and the following 3 lines can be removed after upgrading to python 3. +if sys.version_info[0] < 3: + reload(sys) + sys.setdefaultencoding('utf-8') + import site try: @@ -43,35 +45,162 @@ except: pass import codecs +import io +from docutils import nodes, utils +from docutils.parsers.rst import directives, roles +from docutils.parsers.rst.directives.body import CodeBlock, Directive from docutils.core import publish_parts from docutils.writers.html4css1 import Writer, HTMLTranslator +from docutils.parsers.rst.states import Body +from docutils import nodes + +# By default, docutils provides two choices for unknown directives: +# - Show errors if the reporting level is high enough +# - Silently do not display them otherwise +# Comments are not displayed, either. + +# This code monkey-patches docutils to show preformatted lines +# in both these cases. + +# Recommended practice for repositories with rst files: +# - If github is the preferred viewer for the rst files (e.g. README.rst), +# then design the files to properly display for github. E.g., do not +# include unknown directives or restructuredText comments. +# - If github is NOT the preferred viewer for the rst files (e.g. +# the files are designed to be used with sphinx extensions at readthedocs) +# then include a restructuredText comment at the top of the file +# explaining that the document will display much more nicely with its +# preferred viewer, e.g. at readthedocs. + +original_behavior = False # Documents original docutils behavior +github_display = True + +def extract_extension_options(field_list, option_spec): + """ + Overrides `utils.extract_extension_options` and inlines + `utils.assemble_option_dict` to make it ignore unknown options passed to + directives (i.e. ``:caption:`` for ``.. code-block:``). + """ + + dropped = set() + options = {} + for name, value in utils.extract_options(field_list): + convertor = option_spec.get(name) + if name in options or name in dropped: + raise utils.DuplicateOptionError('duplicate option "%s"' % name) + + # silently drop unknown options as long as they are not duplicates + if convertor is None: + dropped.add(name) + continue + + # continue as before + try: + options[name] = convertor(value) + except (ValueError, TypeError) as detail: + raise detail.__class__('(option: "%s"; value: %r)\n%s' + % (name, value, ' '.join(detail.args))) + return options + +utils.extract_extension_options = extract_extension_options + +def unknown_directive(self, type_name): + lineno = self.state_machine.abs_line_number() + indented, indent, offset, blank_finish = \ + self.state_machine.get_first_known_indented(0, strip_indent=False) + text = '\n'.join(indented) + if original_behavior: + error = self.reporter.error( + 'Unknown directive type "%s".' % type_name, + nodes.literal_block(text, text), line=lineno) + return [error], blank_finish + elif github_display: + cls = ['unknown_directive'] + result = [nodes.literal_block(text, text, classes=cls)] + return result, blank_finish + else: + return [nodes.comment(text, text)], blank_finish + +def comment(self, match): + if not match.string[match.end():].strip() \ + and self.state_machine.is_next_line_blank(): # an empty comment? + return [nodes.comment()], 1 # "A tiny but practical wart." + indented, indent, offset, blank_finish = \ + self.state_machine.get_first_known_indented(match.end()) + while indented and not indented[-1].strip(): + indented.trim_end() + if not original_behavior: + firstline = ''.join(indented[:1]).split() + if ' '.join(firstline[:2]) == 'github display': + if len(firstline) == 3 and firstline[2] in ('on', 'off'): + global github_display + github_display = firstline[2] == 'on' + if len(indented) == 1: + return [nodes.comment()], 1 + text = '\n'.join(indented[1:]) + cls = ['github_comment'] + result = [nodes.literal_block(text, text, classes=cls)] + return result, blank_finish + text = '\n'.join(indented) + return [nodes.comment(text, text)], blank_finish + +Body.comment = comment +Body.unknown_directive = unknown_directive + SETTINGS = { - 'cloak_email_addresses': True, + 'cloak_email_addresses': False, 'file_insertion_enabled': False, - 'raw_enabled': False, + 'raw_enabled': True, 'strip_comments': True, 'doctitle_xform': True, - 'sectsubtitle_xform': True, 'initial_header_level': 2, 'report_level': 5, - 'syntax_highlight' : 'none', - 'math_output' : 'latex', + 'syntax_highlight': 'none', + 'math_output': 'latex', 'field_name_limit': 50, } +default_highlight_language = None + +class HighlightDirective(Directive): + required_arguments = 1 + optional_arguments = 1 + option_spec = {} + def run(self): + """Track the default syntax highlighting language + """ + global default_highlight_language + default_highlight_language = self.arguments[0] + return [] + +class DoctestDirective(CodeBlock): + """Render Sphinx 'doctest:: [group]' blocks as 'code:: python' + """ + + def run(self): + """Discard any doctest group argument, render contents as python code + """ + self.arguments = ['python'] + return super(DoctestDirective, self).run() + + class GitHubHTMLTranslator(HTMLTranslator): + # removes the
, not
# this also avoids the generation of superfluous tags
def visit_literal(self, node):
@@ -97,32 +231,37 @@ class GitHubHTMLTranslator(HTMLTranslator):
def visit_table(self, node):
classes = ' '.join(['docutils', self.settings.table_style]).strip()
self.body.append(
- self.starttag(node, 'table', CLASS=classes))
+ self.starttag(node, 'table', CLASS=classes))
def depart_table(self, node):
self.body.append('\n')
def depart_image(self, node):
- uri = node['uri']
- ext = os.path.splitext(uri)[1].lower()
- # we need to swap RST's use of `object` with `img` tags
- # see http://git.io/5me3dA
- if ext == ".svg":
- # preserve essential attributes
- atts = {}
- for attribute, value in node.attributes.items():
- # we have no time for empty values
- if value:
- if attribute == "uri":
- atts['src'] = value
- else:
- atts[attribute] = value
-
- # toss off `object` tag
- self.body.pop()
- # add on `img` with attributes
- self.body.append(self.starttag(node, 'img', **atts))
- self.body.append(self.context.pop())
+ uri = node['uri']
+ ext = os.path.splitext(uri)[1].lower()
+ # we need to swap RST's use of `object` with `img` tags
+ # see http://git.io/5me3dA
+ if ext == ".svg":
+ # preserve essential attributes
+ atts = {}
+ for attribute, value in node.attributes.items():
+ # we have no time for empty values
+ if value:
+ if attribute == "uri":
+ atts['src'] = value
+ else:
+ atts[attribute] = value
+
+ # toss off `object` tag
+ self.body.pop()
+ # add on `img` with attributes
+ self.body.append(self.starttag(node, 'img', **atts))
+ HTMLTranslator.depart_image(self, node)
+
+
+def kbd(name, rawtext, text, lineno, inliner, options={}, content=[]):
+ return [nodes.raw('', '%s' % text, format='html')], []
+
def main():
"""
@@ -134,14 +273,26 @@ def main():
"""
try:
text = codecs.open(sys.argv[1], 'r', 'utf-8').read()
- except IOError: # given filename could not be found
+ except IOError: # given filename could not be found
return ''
- except IndexError: # no filename given
- text = sys.stdin.read()
+ except IndexError: # no filename given
+ if sys.version_info[0] < 3: # python 2.x
+ text = sys.stdin.read()
+ else: # python 3
+ input_stream = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')
+ text = input_stream.read()
writer = Writer()
writer.translator_class = GitHubHTMLTranslator
+ roles.register_canonical_role('kbd', kbd)
+
+ # Render source code in Sphinx doctest blocks
+ directives.register_directive('doctest', DoctestDirective)
+
+ # Set default highlight language
+ directives.register_directive('highlight', HighlightDirective)
+
parts = publish_parts(text, writer=writer, settings_overrides=SETTINGS)
if 'html_body' in parts:
html = parts['html_body']
@@ -155,5 +306,9 @@ def main():
return ''
if __name__ == '__main__':
- sys.stdout.write("%s%s" % (main(), "\n"))
+ if sys.version_info[0] < 3: # python 2.x
+ sys.stdout.write("%s%s" % (main(), "\n"))
+ else: # python 3
+ output_stream = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
+ output_stream.write("%s%s" % (main(), "\n"))
sys.stdout.flush()
diff --git a/lib/github/markup.rb b/lib/github/markup.rb
index 82de5172..1c63c8bd 100644
--- a/lib/github/markup.rb
+++ b/lib/github/markup.rb
@@ -1,51 +1,99 @@
+begin
+ require "linguist"
+rescue LoadError
+ # Rely on extensions instead.
+end
+
require "github/markup/command_implementation"
require "github/markup/gem_implementation"
module GitHub
+ module Markups
+ # all of supported markups:
+ MARKUP_ASCIIDOC = :asciidoc
+ MARKUP_CREOLE = :creole
+ MARKUP_MARKDOWN = :markdown
+ MARKUP_MEDIAWIKI = :mediawiki
+ MARKUP_ORG = :org
+ MARKUP_POD = :pod
+ MARKUP_RDOC = :rdoc
+ MARKUP_RST = :rst
+ MARKUP_TEXTILE = :textile
+ MARKUP_POD6 = :pod6
+ end
+
module Markup
extend self
- @@markups = []
+
+ @@markups = {}
def markups
@@markups
end
+ def markup_impls
+ markups.values
+ end
+
def preload!
- markups.each do |markup|
- markup.load
+ markup_impls.each(&:load)
+ end
+
+ def render(filename, content, symlink: false, options: {})
+ if (impl = renderer(filename, content, symlink: symlink))
+ impl.render(filename, content, options: options)
+ else
+ content
end
end
- def render(filename, content = nil)
- content ||= File.read(filename)
+ def render_s(symbol, content, options: {})
+ raise ArgumentError, 'Can not render a nil.' if content.nil?
- if impl = renderer(filename)
- impl.render(content)
+ if markups.key?(symbol)
+ markups[symbol].render(nil, content, options: options)
else
content
end
end
- def markup(file, pattern, opts = {}, &block)
- markups << GemImplementation.new(pattern, file, &block)
+ def markup(symbol, gem_name, regexp, languages, opts = {}, &block)
+ impl = GemImplementation.new(regexp, languages, gem_name, &block)
+ markup_impl(symbol, impl)
+ end
+
+ def markup_impl(symbol, impl)
+ if markups.key?(symbol)
+ raise ArgumentError, "The '#{symbol}' symbol is already defined."
+ end
+ markups[symbol] = impl
end
- def command(command, regexp, &block)
+ def command(symbol, command, regexp, languages, name, &block)
if File.exist?(file = File.dirname(__FILE__) + "/commands/#{command}")
command = file
end
- markups << CommandImplementation.new(regexp, command, &block)
+ impl = CommandImplementation.new(regexp, languages, command, name, &block)
+ markup_impl(symbol, impl)
end
- def can_render?(filename)
- !!renderer(filename)
+ def can_render?(filename, content, symlink: false)
+ renderer(filename, content, symlink: symlink) != nil
end
- def renderer(filename)
- markups.find { |impl|
- impl.match?(filename)
- }
+ def renderer(filename, content, symlink: false)
+ language = language(filename, content, symlink: symlink)
+ markup_impls.find do |impl|
+ impl.match?(filename, language)
+ end
+ end
+
+ def language(filename, content, symlink: false)
+ return unless defined?(::Linguist)
+
+ blob = Linguist::Blob.new(filename, content, symlink: symlink)
+ Linguist.detect(blob, allow_empty: true)
end
# Define markups
diff --git a/lib/github/markup/command_implementation.rb b/lib/github/markup/command_implementation.rb
index 1b43dd71..b55f1735 100644
--- a/lib/github/markup/command_implementation.rb
+++ b/lib/github/markup/command_implementation.rb
@@ -1,26 +1,23 @@
-begin
- require "posix-spawn"
-rescue LoadError
- require "open3"
-end
-
+require "open3"
require "github/markup/implementation"
+
module GitHub
module Markup
class CommandError < RuntimeError
end
class CommandImplementation < Implementation
- attr_reader :command, :block
+ attr_reader :command, :block, :name
- def initialize(regexp, command, &block)
- super regexp
+ def initialize(regexp, languages, command, name, &block)
+ super(regexp, languages)
@command = command.to_s
@block = block
+ @name = name
end
- def render(content)
+ def render(filename, content, options: {})
rendered = execute(command, content)
rendered = rendered.to_s.empty? ? content : rendered
call_block(rendered, content)
@@ -36,35 +33,20 @@ def call_block(rendered, content)
rendered
end
end
-
- if defined?(Posix::Spawn)
- def execute(command, target)
- spawn = POSIX::Spawn::Child.new(*command, :input => target)
- if spawn.status.success?
- sanitize(spawn.out, target.encoding)
- else
- raise CommandError.new(spawn.err.strip)
- end
- end
- else
- def execute(command, target)
- output = Open3.popen3(*command) do |stdin, stdout, stderr, wait_thr|
- stdin.puts target
- stdin.close
- if wait_thr.value.success?
- stdout.readlines
- else
- raise CommandError.new(stderr.readlines.join('').strip)
- end
- end
- sanitize(output.join(''), target.encoding)
- end
+
+ def execute(command, target)
+ # capture3 blocks until both buffers are written to and the process terminates, but
+ # it won't allow either buffer to fill up
+ stdout, stderr, status = Open3.capture3(*command, stdin_data: target)
+
+ raise CommandError.new(stderr) unless status.success?
+ sanitize(stdout, target.encoding)
end
-
+
def sanitize(input, encoding)
input.gsub("\r", '').force_encoding(encoding)
end
-
+
end
end
end
diff --git a/lib/github/markup/gem_implementation.rb b/lib/github/markup/gem_implementation.rb
index a9f80b75..843717e6 100644
--- a/lib/github/markup/gem_implementation.rb
+++ b/lib/github/markup/gem_implementation.rb
@@ -5,21 +5,25 @@ module Markup
class GemImplementation < Implementation
attr_reader :gem_name, :renderer
- def initialize(regexp, gem_name, &renderer)
- super regexp
+ def initialize(regexp, languages, gem_name, &renderer)
+ super(regexp, languages)
@gem_name = gem_name.to_s
@renderer = renderer
end
def load
- return if @loaded
+ return if defined?(@loaded) && @loaded
require gem_name
@loaded = true
end
- def render(content)
+ def render(filename, content, options: {})
load
- renderer.call(content)
+ renderer.call(filename, content, options: options)
+ end
+
+ def name
+ gem_name
end
end
end
diff --git a/lib/github/markup/implementation.rb b/lib/github/markup/implementation.rb
index 463a39d4..458ab0d8 100644
--- a/lib/github/markup/implementation.rb
+++ b/lib/github/markup/implementation.rb
@@ -2,24 +2,38 @@ module GitHub
module Markup
class Implementation
attr_reader :regexp
+ attr_reader :languages
- def initialize(regexp)
+ def initialize(regexp, languages)
@regexp = regexp
+
+ if defined?(::Linguist)
+ @languages = languages.map do |l|
+ lang = Linguist::Language[l]
+ raise "no match for language #{l.inspect}" if lang.nil?
+ lang
+ end
+ end
end
def load
# no-op by default
end
- def render(content)
+ def render(filename, content, options: {})
raise NotImplementedError, "subclasses of GitHub::Markup::Implementation must define #render"
end
- def match?(filename)
- file_ext_regexp =~ filename
+ def match?(filename, language)
+ if defined?(::Linguist)
+ languages.include? language
+ else
+ file_ext_regexp =~ filename
+ end
end
- private
+ private
+
def file_ext_regexp
@file_ext_regexp ||= /\.(#{regexp})\z/
end
diff --git a/lib/github/markup/markdown.rb b/lib/github/markup/markdown.rb
index f2744ca3..dcf93229 100644
--- a/lib/github/markup/markdown.rb
+++ b/lib/github/markup/markdown.rb
@@ -4,28 +4,35 @@ module GitHub
module Markup
class Markdown < Implementation
MARKDOWN_GEMS = {
- "github/markdown" => proc { |content|
+ "commonmarker" => proc { |content, options: {}|
+ commonmarker_opts = [:GITHUB_PRE_LANG].concat(options.fetch(:commonmarker_opts, []))
+ commonmarker_exts = options.fetch(:commonmarker_exts, [:tagfilter, :autolink, :table, :strikethrough])
+ CommonMarker.render_html(content, commonmarker_opts, commonmarker_exts)
+ },
+ "github/markdown" => proc { |content, options: {}|
GitHub::Markdown.render(content)
},
- "redcarpet" => proc { |content|
+ "redcarpet" => proc { |content, options: {}|
Redcarpet::Markdown.new(Redcarpet::Render::HTML).render(content)
},
- "rdiscount" => proc { |content|
+ "rdiscount" => proc { |content, options: {}|
RDiscount.new(content).to_html
},
- "maruku" => proc { |content|
+ "maruku" => proc { |content, options: {}|
Maruku.new(content).to_html
},
- "kramdown" => proc { |content|
+ "kramdown" => proc { |content, options: {}|
Kramdown::Document.new(content).to_html
},
- "bluecloth" => proc { |content|
+ "bluecloth" => proc { |content, options: {}|
BlueCloth.new(content).to_html
},
}
def initialize
- super(/md|rmd|mkdn?|mdwn|mdown|markdown|litcoffee/i)
+ super(
+ /md|mkdn?|mdwn|mdown|markdown|mdx|litcoffee/i,
+ ["Markdown", "MDX", "Literate CoffeeScript"])
end
def load
@@ -39,9 +46,13 @@ def load
raise LoadError, "no suitable markdown gem found"
end
- def render(content)
+ def render(filename, content, options: {})
load
- @renderer.call(content)
+ @renderer.call(content, options: options)
+ end
+
+ def name
+ "markdown"
end
private
diff --git a/lib/github/markup/rdoc.rb b/lib/github/markup/rdoc.rb
index 5bf14639..32cb4194 100644
--- a/lib/github/markup/rdoc.rb
+++ b/lib/github/markup/rdoc.rb
@@ -1,20 +1,25 @@
+require "github/markup/implementation"
require "rdoc"
require "rdoc/markup/to_html"
module GitHub
module Markup
- class RDoc
- def initialize(content)
- @content = content
+ class RDoc < Implementation
+ def initialize
+ super(/rdoc/, ["RDoc"])
end
- def to_html
+ def render(filename, content, options: {})
if ::RDoc::VERSION.to_i >= 4
h = ::RDoc::Markup::ToHtml.new(::RDoc::Options.new)
else
h = ::RDoc::Markup::ToHtml.new
end
- h.convert(@content)
+ h.convert(content)
+ end
+
+ def name
+ "rdoc"
end
end
end
diff --git a/lib/github/markups.rb b/lib/github/markups.rb
index eb562909..2c30c99d 100644
--- a/lib/github/markups.rb
+++ b/lib/github/markups.rb
@@ -1,44 +1,59 @@
require "github/markup/markdown"
+require "github/markup/rdoc"
require "shellwords"
-markups << GitHub::Markup::Markdown.new
+markup_impl(::GitHub::Markups::MARKUP_MARKDOWN, ::GitHub::Markup::Markdown.new)
-markup(:redcloth, /textile/) do |content|
+markup(::GitHub::Markups::MARKUP_TEXTILE, :redcloth, /textile/, ["Textile"]) do |filename, content, options: {}|
RedCloth.new(content).to_html
end
-markup('github/markup/rdoc', /rdoc/) do |content|
- GitHub::Markup::RDoc.new(content).to_html
-end
+markup_impl(::GitHub::Markups::MARKUP_RDOC, GitHub::Markup::RDoc.new)
-markup('org-ruby', /org/) do |content|
- Orgmode::Parser.new(content, {
- :allow_include_files => false,
+markup(::GitHub::Markups::MARKUP_ORG, 'org-ruby', /org/, ["Org"]) do |filename, content, options: {}|
+ Orgmode::Parser.new(content, {
+ :allow_include_files => false,
:skip_syntax_highlight => true
}).to_html
end
-markup(:creole, /creole/) do |content|
+markup(::GitHub::Markups::MARKUP_CREOLE, :creole, /creole/, ["Creole"]) do |filename, content, options: {}|
Creole.creolize(content)
end
-markup(:wikicloth, /mediawiki|wiki/) do |content|
- WikiCloth::WikiCloth.new(:data => content).to_html(:noedit => true)
+markup(::GitHub::Markups::MARKUP_MEDIAWIKI, :wikicloth, /mediawiki|wiki/, ["MediaWiki"]) do |filename, content, options: {}|
+ wikicloth = WikiCloth::WikiCloth.new(:data => content)
+ WikiCloth::WikiBuffer::HTMLElement::ESCAPED_TAGS << 'tt' unless WikiCloth::WikiBuffer::HTMLElement::ESCAPED_TAGS.include?('tt')
+ wikicloth.to_html(:noedit => true)
end
-markup(:asciidoctor, /adoc|asc(iidoc)?/) do |content|
- Asciidoctor.render(content, :safe => :secure, :attributes => %w(showtitle idprefix idseparator=- env=github env-github source-highlighter=html-pipeline))
+markup(::GitHub::Markups::MARKUP_ASCIIDOC, :asciidoctor, /adoc|asc(iidoc)?/, ["AsciiDoc"]) do |filename, content, options: {}|
+ attributes = {
+ 'showtitle' => '@',
+ 'idprefix' => '',
+ 'idseparator' => '-',
+ 'sectanchors' => nil,
+ 'env' => 'github',
+ 'env-github' => '',
+ 'source-highlighter' => 'html-pipeline'
+ }
+ if filename
+ attributes['docname'] = File.basename(filename, (extname = File.extname(filename)))
+ attributes['docfilesuffix'] = attributes['outfilesuffix'] = extname
+ else
+ attributes['outfilesuffix'] = '.adoc'
+ end
+ Asciidoctor::Compliance.unique_id_start_index = 1
+ Asciidoctor.convert(content, :safe => :secure, :attributes => attributes)
end
-command("python2 -S #{Shellwords.escape(File.dirname(__FILE__))}/commands/rest2html", /re?st(\.txt)?/)
+command(
+ ::GitHub::Markups::MARKUP_RST,
+ "python3 #{Shellwords.escape(File.dirname(__FILE__))}/commands/rest2html",
+ /re?st(\.txt)?/,
+ ["reStructuredText"],
+ "restructuredtext"
+)
-# pod2html is nice enough to generate a full-on HTML document for us,
-# so we return the favor by ripping out the good parts.
-#
-# Any block passed to `command` will be handed the command's STDOUT for
-# post processing.
-command('/usr/bin/env perl -MPod::Simple::HTML -e Pod::Simple::HTML::go', /pod/) do |rendered|
- if rendered =~ /\s*(.+)\s*/mi
- $1
- end
-end
+command(::GitHub::Markups::MARKUP_POD6, :pod62html, /pod6/, ["Pod 6"], "pod6")
+command(::GitHub::Markups::MARKUP_POD, :pod2html, /pod/, ["Pod"], "pod")
diff --git a/script/bootstrap b/script/bootstrap
index 8092d517..f89f3181 100755
--- a/script/bootstrap
+++ b/script/bootstrap
@@ -5,4 +5,4 @@ set -e
cd $(dirname "$0")/..
bundle install
-easy_install docutils
+pip3 install docutils
diff --git a/script/bootstrap.contrib b/script/bootstrap.contrib
new file mode 100755
index 00000000..834b6b61
--- /dev/null
+++ b/script/bootstrap.contrib
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+set -e
+
+cd $(dirname "$0")/..
+
+bundle install --path vendor/bundle
+virtualenv vendor/python && source vendor/python/bin/activate
+pip install docutils
+
+echo ""
+echo "*** DONE ***"
+echo ""
+echo "activate python environment with 'source vendor/python/bin/activate'"
+echo "run tests with 'bundle exec rake'"
diff --git a/test/markup_test.rb b/test/markup_test.rb
index 3d24b7a6..ced0b5f8 100644
--- a/test/markup_test.rb
+++ b/test/markup_test.rb
@@ -1,4 +1,4 @@
-# encoding: UTF-8
+# encoding: utf-8
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../lib"
@@ -9,11 +9,10 @@
require 'nokogiri/diff'
def normalize_html(text)
- text.strip!
- text.gsub!(/\s\s+/,' ')
- text.gsub!(/\p{Pi}|\p{Pf}|"/u,'"')
- text.gsub!("\u2026",'...')
- text
+ text.strip
+ .gsub(/\s\s+/,' ')
+ .gsub(/\p{Pi}|\p{Pf}|"/u,'"')
+ .gsub("\u2026",'...')
end
def assert_html_equal(expected, actual, msg = nil)
@@ -53,7 +52,6 @@ def call
define_method "test_#{markup}" do
skip "Skipping MediaWiki test because wikicloth is currently not compatible with JRuby." if markup == "mediawiki" && RUBY_PLATFORM == "java"
-
source = File.read(readme)
expected_file = "#{readme}.html"
expected = File.read(expected_file).rstrip
@@ -69,6 +67,10 @@ def call
f.read
end
+ if ENV['UPDATE']
+ File.open(expected_file, 'w') { |f| f.write actual }
+ end
+
assert_html_equal expected, actual, <Title')
+ assert_equal true, GitHub::Markup.can_render?('README.markdown', '=== Title')
+ assert_equal false, GitHub::Markup.can_render?('README.cmd', 'echo 1')
+ assert_equal true, GitHub::Markup.can_render?('README.litcoffee', 'Title')
+ end
+
+ def test_each_render_has_a_name
+ assert_equal "markdown", GitHub::Markup.renderer('README.md', '=== Title').name
+ assert_equal "redcloth", GitHub::Markup.renderer('README.textile', '* One').name
+ assert_equal "rdoc", GitHub::Markup.renderer('README.rdoc', '* One').name
+ assert_equal "org-ruby", GitHub::Markup.renderer('README.org', '* Title').name
+ assert_equal "creole", GitHub::Markup.renderer('README.creole', '= Title =').name
+ assert_equal "wikicloth", GitHub::Markup.renderer('README.wiki', 'Title
').name
+ assert_equal "asciidoctor", GitHub::Markup.renderer('README.adoc', '== Title').name
+ assert_equal "restructuredtext", GitHub::Markup.renderer('README.rst', 'Title').name
+ assert_equal "pod", GitHub::Markup.renderer('README.pod', '=head1').name
+ assert_equal "pod6", GitHub::Markup.renderer('README.pod6', '=begin pod').name
+ end
+
+ def test_rendering_by_symbol
+ markup = '`test`'
+ result = /test<\/code><\/p>/
+ assert_match result, GitHub::Markup.render_s(GitHub::Markups::MARKUP_MARKDOWN, markup).strip
+ assert_match result, GitHub::Markup.render_s(GitHub::Markups::MARKUP_ASCIIDOC, markup).split.join
end
def test_raises_error_if_command_exits_non_zero
- GitHub::Markup.command('test/fixtures/fail.sh', /fail/)
- assert GitHub::Markup.can_render?('README.fail')
+ GitHub::Markup.command(:doesntmatter, 'test/fixtures/fail.sh', /fail/, ['Java'], 'fail')
+ assert GitHub::Markup.can_render?('README.java', 'stop swallowing errors')
begin
- GitHub::Markup.render('README.fail', "stop swallowing errors")
+ GitHub::Markup.render('README.java', "stop swallowing errors", symlink: false)
rescue GitHub::Markup::CommandError => e
- assert_equal "failure message", e.message
+ assert_equal "failure message", e.message.strip
else
fail "an exception was expected but was not raised"
end
@@ -101,4 +121,18 @@ def test_preserve_markup
content = "Noël"
assert_equal content.encoding.name, GitHub::Markup.render('Foo.rst', content).encoding.name
end
+
+ def test_commonmarker_options
+ assert_equal "hello world
\n", GitHub::Markup.render("test.md", "hello world")
+ assert_equal "hello world
\n", GitHub::Markup.render("test.md", "hello world", options: {commonmarker_opts: [:UNSAFE]})
+
+ assert_equal "hello world
\n", GitHub::Markup.render_s(GitHub::Markups::MARKUP_MARKDOWN, "hello world")
+ assert_equal "hello world
\n", GitHub::Markup.render_s(GitHub::Markups::MARKUP_MARKDOWN, "hello world", options: {commonmarker_opts: [:UNSAFE]})
+
+ assert_equal "<style>.red{color: red;}</style>\n", GitHub::Markup.render("test.md", "", options: {commonmarker_opts: [:UNSAFE]})
+ assert_equal "\n", GitHub::Markup.render("test.md", "", options: {commonmarker_opts: [:UNSAFE], commonmarker_exts: [:autolink, :table, :strikethrough]})
+
+ assert_equal "<style>.red{color: red;}</style>\n", GitHub::Markup.render_s(GitHub::Markups::MARKUP_MARKDOWN, "", options: {commonmarker_opts: [:UNSAFE]})
+ assert_equal "\n", GitHub::Markup.render_s(GitHub::Markups::MARKUP_MARKDOWN, "", options: {commonmarker_opts: [:UNSAFE], commonmarker_exts: [:autolink, :table, :strikethrough]})
+ end
end
diff --git a/test/markups/README.asciidoc b/test/markups/README.asciidoc
index 6a0462cb..5f65dd2b 100644
--- a/test/markups/README.asciidoc
+++ b/test/markups/README.asciidoc
@@ -1,14 +1,27 @@
= Document Title
+// sectanchors will be ignored
+:sectanchors:
== First Section
* One
* Two
-== Second Section
+Refer to <> or <>.
+
+Navigate from {docname}{outfilesuffix} to xref:another-document.asciidoc[another document].
+
+== Another Section
NOTE: Here is some source code.
```ruby
puts "Hello, World!"
```
+
+* [ ] todo
+* [x] done
+
+== Another Section
+
+content
diff --git a/test/markups/README.asciidoc.html b/test/markups/README.asciidoc.html
index 4f06d0f9..8019074b 100644
--- a/test/markups/README.asciidoc.html
+++ b/test/markups/README.asciidoc.html
@@ -12,10 +12,16 @@ First Section
Refer to Another Section or Another Section.
+Navigate from README.asciidoc to another document.
+ID | +Type | +Priority | +Summary | +
---|---|---|---|
#3296 | +enhancement | +critical | +Support keywords and control structures with listener version 3 | +
#3761 | +enhancement | +critical | +Native VAR syntax to create variables inside tests and keywords |
+
#4294 | +enhancement | +critical | +Drop Python 3.6 and 3.7 support | +
#4710 | +enhancement | +critical | +Support library keywords with both embedded and normal arguments | +
#4847 | +enhancement | +critical | +Support JSON serialization with result model | +
#4659 | +bug | +high | +Performance regression when using Run Keyword and keyword name contains a variable |
+
#4921 | +bug | +high | +Log levels don't work correctly with robot:flatten
+ |
+
#3725 | +enhancement | +high | +Support dark theme with report and log | +
#4258 | +enhancement | +high | +Change timestamps from custom strings to datetime in result model and to ISO 8601 format in output.xml |
+
#4374 | +enhancement | +high | +Support removing tags set globally by using -tag syntax with [Tags] setting |
+
#4633 | +enhancement | +high | +Automatic argument conversion and validation for Literal
+ |
+
#4711 | +enhancement | +high | +Support type aliases in formats 'list[int]' and 'int | float' in argument conversion |
+
#4803 | +enhancement | +high | +Async support to dynamic and hybrid library APIs | +
#4808 | +bug | +medium | +Async keywords are not stopped when execution is stopped gracefully | +
#4859 | +bug | +medium | +Parsing errors in reStructuredText files have no source | +
#4880 | +bug | +medium | +Initially empty test fails even if pre-run modifier adds content to it | +
#4886 | +bug | +medium | +
+Set Variable If is slow if it has several conditions |
+
#4898 | +bug | +medium | +Resolving special variables can fail with confusing message | +
#4915 | +bug | +medium | +
+cached_property attributes are called when importing library |
+
#4924 | +bug | +medium | +WHILE on_limit missing from listener v2 attributes |
+
#4926 | +bug | +medium | +WHILE and TRY content are not removed with --removekeywords all
+ |
+
#4945 | +bug | +medium | +
+TypedDict with forward references do not work in argument conversion |
+
#4956 | +bug | +medium | +DotDict behaves inconsistent on equality checks. x == y != not x != y and not x != y == not x == y
+ |
+
#4964 | +bug | +medium | +Variables set using Set Suite Variable with children=True cannot be properly overwritten |
+
#4980 | +bug | +medium | +DateTime library uses deprecated datetime.utcnow()
+ |
+
#4999 | +bug | +medium | +XML Library: Double namespace during Element To String | +
#5005 | +bug | +medium | +
+Log Variables should not consume iterables |
+
#3017 | +enhancement | +medium | +Add return type to Libdoc specs and HTML output | +
#4103 | +enhancement | +medium | +Process: Change the default stdin behavior from subprocess.PIPE to None
+ |
+
#4302 | +enhancement | +medium | +Remove Reserved library |
+
#4343 | +enhancement | +medium | +Collections: Support case-insensitive list and dictionary comparisons | +
#4375 | +enhancement | +medium | +Change token type of AS (or WITH NAME ) used with library imports to Token.AS
+ |
+
#4385 | +enhancement | +medium | +Change the parsing model object produced by Test Tags (and Force Tags ) to TestTags
+ |
+
#4432 | +enhancement | +medium | +Loudly deprecate singular section headers | +
#4501 | +enhancement | +medium | +Loudly deprecate old Python 2/3 compatibility layer and other deprecated utils | +
#4524 | +enhancement | +medium | +Loudly deprecate variables used as embedded arguments not matching custom patterns | +
#4545 | +enhancement | +medium | +Support creating assigned variable name based on another variable like ${${var}} = Keyword
+ |
+
#4667 | +enhancement | +medium | +Remove deprecated constructs from Libdoc spec files | +
#4685 | +enhancement | +medium | +Deprecate SHORTEST mode being default with FOR IN ZIP loops |
+
#4708 | +enhancement | +medium | +Use assing , not variable , with FOR and TRY/EXCEPT model objects when referring to assigned variables |
+
#4720 | +enhancement | +medium | +Require --suite parent.suite to match the full suite name |
+
#4721 | +enhancement | +medium | +Change behavior of --test and --include so that they are cumulative |
+
#4747 | +enhancement | +medium | +Support [Setup] with user keywords |
+
#4784 | +enhancement | +medium | +Remote: Enhance datetime , date and timedelta conversion |
+
#4841 | +enhancement | +medium | +Add typing to all modules under robot.api
+ |
+
#4846 | +enhancement | +medium | +Result model: Loudly deprecate not needed attributes and remove already deprecated ones | +
#4872 | +enhancement | +medium | +Control continue-on-failure mode by using recursive and non-recursive tags together | +
#4876 | +enhancement | +medium | +Loudly deprecate [Return] setting |
+
#4877 | +enhancement | +medium | +XML: Support ignoring element order with Elements Should Be Equal
+ |
+
#4883 | +enhancement | +medium | +Result model: Add message to keywords and control structures and remove doc from controls |
+
#4884 | +enhancement | +medium | +Result model: Enhance storing keyword name | +
#4896 | +enhancement | +medium | +Support separator=<value> configuration option with scalar variables in Variables section |
+
#4903 | +enhancement | +medium | +Support argument conversion and named arguments with dynamic variable files | +
#4905 | +enhancement | +medium | +Support creating variable name based on another variable like ${${VAR}} in Variables section |
+
#4910 | +enhancement | +medium | +Make listener v3 the default listener API | +
#4912 | +enhancement | +medium | +Parsing model: Move type and tokens from _fields to _attributes
+ |
+
#4930 | +enhancement | +medium | +BuiltIn: New Reset Log Level keyword for resetting the log level to the original value |
+
#4939 | +enhancement | +medium | +Parsing model: Rename Return to ReturnSetting and ReturnStatement to Return
+ |
+
#4942 | +enhancement | +medium | +Add public argument conversion API for libraries and other tools | +
#4952 | +enhancement | +medium | +Collections: Make ignore_order and ignore_keys recursive |
+
#4960 | +enhancement | +medium | +Support integer conversion with strings representing whole number floats like '1.0' and '2e10'
+ |
+
#4976 | +enhancement | +medium | +Support string SELF (case-insenstive) when library registers itself as listener |
+
#4979 | +enhancement | +medium | +Add robot.result.TestSuite.to/from_xml methods |
+
#4982 | +enhancement | +medium | +DateTime: Support datetime.date as an input format with date related keywords |
+
#4983 | +enhancement | +medium | +Type conversion: Remove support for deprecated ByteString
+ |
+
#5000 | +enhancement | +medium | +Nicer API for setting keyword call arguments programmatically | +
#4934 | +--- | +medium | +Enhance performance of visiting parsing model | +
#4621 | +bug | +low | +OperatingSystem library docs have broken link / title | +
#4798 | +bug | +low | +
+--removekeywords passed doesn't remove test setup and teardown |
+
#4867 | +bug | +low | +Original order of dictionaries is not preserved when they are pretty printed in log messages | +
#4870 | +bug | +low | +User keyword teardown missing from running model JSON schema | +
#4904 | +bug | +low | +Importing static variable file with arguments does not fail | +
#4913 | +bug | +low | +Trace log level logs arguments twice for embedded arguments | +
#4927 | +bug | +low | +WARN level missing from the log level selector in log.html | +
#4967 | +bug | +low | +Variables are not resolved in keyword name in WUKS error message | +
#4861 | +enhancement | +low | +Remove deprecated accept_plain_values from timestr_to_secs utility function |
+
#4862 | +enhancement | +low | +Deprecate elapsed_time_to_string accepting time as milliseconds |
+
#4864 | +enhancement | +low | +Process: Make warning about processes hanging if output buffers get full more visible | +
#4885 | +enhancement | +low | +Add full_name to replace longname to suite and test objects |
+
#4900 | +enhancement | +low | +Make keywords and control structures in log look more like original data | +
#4922 | +enhancement | +low | +Change the log level of Set Log Level message from INFO to DEBUG |
+
#4933 | +enhancement | +low | +Type conversion: Ignore hyphens when matching enum members | +
#4935 | +enhancement | +low | +Use casefold , not lower , when comparing strings case-insensitively |
+
#4936 | +enhancement | +low | +Remove bytes support from robot.utils.normalize function |
+
#4954 | +enhancement | +low | +Collections and String: Add ignore_case as alias for case_insensitive
+ |
+
#4958 | +enhancement | +low | +Document robot_running and dry_run_active properties of the BuiltIn library in the User Guide |
+
#4975 | +enhancement | +low | +Support times and x suffixes with WHILE limit to make it more compatible with Wait Until Keyword Succeeds
+ |
+
#4988 | +enhancement | +low | +Change paths passed to listener v3 methods to pathlib.Path instances |
+
Altogether 88 issues. View on the issue tracker.
\ No newline at end of file diff --git a/test/markups/README.mediawiki b/test/markups/README.mediawiki index 36c3ef6b..c3cc004a 100644 --- a/test/markups/README.mediawiki +++ b/test/markups/README.mediawiki @@ -6,6 +6,9 @@ __TOC__ = Red Bridge (JRuby Embed) = +one-a-b+ JRuby has long had a private embedding API, which was closely tied to the runtime's internals and therefore changed frequently as JRuby evolved. Since version 1.4, however, we have also provided a more stable public API, known as Red Bridge or JRuby Embed. Existing Java programs written to the [[DirectJRubyEmbedding|legacy API]] should still work, but we strongly recommend Red Bridge for all new projects. == Features of Red Bridge == diff --git a/test/markups/README.mediawiki.html b/test/markups/README.mediawiki.html index 6f9ac5e3..e92accfd 100644 --- a/test/markups/README.mediawiki.html +++ b/test/markups/README.mediawiki.html @@ -15,15 +15,20 @@
one-<two +
a-b+
JRuby has long had a private embedding API, which was closely tied to the runtime's internals and therefore changed frequently as JRuby evolved. Since version 1.4, however, we have also provided a more stable public API, known as Red Bridge or JRuby Embed. Existing Java programs written to the legacy API should still work, but we strongly recommend Red Bridge for all new projects.
Red Bridge consists of two layers: Embed Core on the bottom, and implementations of JSR223 and BSF on top. Embed Core is JRuby-specific, and can take advantage of much of JRuby's power. JSR223 and BSF are more general interfaces that provide a common ground across scripting languages. @@ -43,14 +48,16 @@
We recommend using Embed Core; however, if you're maintaining code that uses the old API, you can find its documentation on the legacy embedding[1] page.
This is a port of the MATLAB/Octave programming language to Parrot. See the ROADMAP file for more information on the status of this project, and what else needs to be done.
-This is a port of the MATLAB/Octave programming language to Parrot. -See the ROADMAP file for more information on the status of this project, -and what else needs to be done.
- -Primary goals are:
--+=item* Create a working compiler that understands the majority of the MATLAB/Octave programming language.
-
Create a working compiler that understands the majority of the MATLAB/Octave programming language.
-This project is broken into three primary components:
--- -=item* The first is the parser, -located in the
- -src/parser/
directory. -The parser proper is composed of three source files, -grammar.pg which is a Perl6Grammar file, -and actions.pm which is the associated actions file written in NQP, -and grammar-oper.pm which is the operator precidence parser. -In addition, -several helper functions used by the parser are located insrc/internals
.=item* The second component is the library of builtin functions in the
- -src/builtins/
directory. -These functions are, -currently, -written primarily in PIR. -Function names prefixed with an underscore are "private" functions for use with the parser. -Other functions should have names which are the same as names for regular MATLAB or Octave functions, -since they will be available to the HLL. -These are also separated into different namespaces depending on visibility and utility.=item* A number of library functions are written in M, -or mostly M with some inline PIR code in
-toolbox/
.
The first is the parser, located in the src/parser/
directory. The parser proper is composed of three source files, grammar.pg which is a Perl6Grammar file, and actions.pm which is the associated actions file written in NQP, and grammar-oper.pm which is the operator precedence parser. In addition, several helper functions used by the parser are located in src/internals
.
The second component is the library of builtin functions in the src/builtins/
directory. These functions are, currently, written primarily in PIR. Function names prefixed with an underscore are "private" functions for use with the parser. Other functions should have names which are the same as names for regular MATLAB or Octave functions, since they will be available to the HLL. These are also separated into different namespaces depending on visibility and utility.
A number of library functions are written in M, or mostly M with some inline PIR code in toolbox/
.
Matrixy depends on these dependencies:
-To get a proper version of Parrot to build Matrixy, -you will need to check out and build Parrot from source:
+To get a proper version of Parrot to build Matrixy, you will need to check out and build Parrot from source:
-svn co http://svn.parrot.org/parrot/trunk parrot - cd parrot - perl Configure.pl - make && make test && make install-dev+
svn co http://svn.parrot.org/parrot/trunk parrot
+cd parrot
+perl Configure.pl
+make && make test && make install-dev
-The linear algebra package for Parrot is available separately and provides functionality required by Matrixy. This includes matrix data types and matrix manipulation libraries
-Once all dependencies are in place, you can build Matrixy using this sequence of commands:
-perl Configure.pl - nmake test+
perl Configure.pl
+nmake test
-* Parser - * Standard Builtins - * Test against Octave Test Suite.+
* Parser
+* Standard Builtins
+* Test against Octave Test Suite.
-Lots!
-If you need to contact the Matrixy team, go to the project home page at:
diff --git a/test/markups/README.rmd b/test/markups/README.rmd deleted file mode 100644 index f9f5f702..00000000 --- a/test/markups/README.rmd +++ /dev/null @@ -1,3 +0,0 @@ -# Title -* One -* Two diff --git a/test/markups/README.rmd.html b/test/markups/README.rmd.html deleted file mode 100644 index 39644656..00000000 --- a/test/markups/README.rmd.html +++ /dev/null @@ -1,6 +0,0 @@ -RAW HTML!
diff --git a/test/markups/README.rst.html b/test/markups/README.rst.html index a074e8d5..7a0f8327 100644 --- a/test/markups/README.rst.html +++ b/test/markups/README.rst.html @@ -2,20 +2,81 @@Example text.
-code
blahcode
, hoorayThe UTF-8 quote character in this table used to cause python to go boom. Now docutils just silently ignores it.
Thing | +Awesomeness | +
Icecream | +7 | +
Honey Badgers | +10.5 | +
Nickelback | +-2 | +
Iron Man | +10 | +
Iron Man 2 | +3 | +
Tabular Data | +5 | +
Made up ratings | +11 | +
+A block of code ++
+python.code('hooray')
+
+
+python.code('hello world')
+
+
+>>> some_function()
+'result'
+
+
+>>> some_function()
+'result'
+
+this should work even with the default :) | -
Press Ctrl+C to quit
+RAW HTML!
p {color:blue;} \ No newline at end of file diff --git a/test/markups/README.rst.txt.html b/test/markups/README.rst.txt.html index d2e61dc6..6d5d0675 100644 --- a/test/markups/README.rst.txt.html +++ b/test/markups/README.rst.txt.html @@ -1,5 +1,6 @@Example text.
+code
blahpycparser is a parser for the C language, written in pure Python. It is a +module designed to be easily integrated into applications that need to parse +C source code.
+ +Anything that needs C code to be parsed. The following are some uses for +pycparser, taken from real user reports:
+pycparser is unique in the sense that it's written in pure Python - a very +high level language that's easy to experiment with and tweak. To people familiar +with Lex and Yacc, pycparser's code will be simple to understand.
\ No newline at end of file