diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..bd5de2b --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,203 @@ +AllCops: + Include: + - lib/**/*.rb + TargetRubyVersion: 2.3 + + +Metrics/LineLength: + Max: 110 # Preferred length is 100 + +Metrics/ParameterLists: + CountKeywordArgs: false + Max: 8 + +Metrics/BlockLength: + Enabled: false + +Metrics/MethodLength: + Enabled: false + +Metrics/ClassLength: + Enabled: false + +Metrics/ModuleLength: + Enabled: false + +Metrics/AbcSize: + Enabled: false + +Metrics/CyclomaticComplexity: + Enabled: false + +Metrics/PerceivedComplexity: + Enabled: false + +Metrics/BlockNesting: + Max: 5 + + +Style/Encoding: + Enabled: false + +Style/StringLiterals: + Enabled: false # we don't care + +Style/RegexpLiteral: + AllowInnerSlashes: true + +Style/NumericLiterals: + MinDigits: 6 + +Style/NumericLiteralPrefix: + EnforcedOctalStyle: zero_only + +Style/SymbolArray: + EnforcedStyle: brackets + +Style/WordArray: + MinSize: 5 + +Style/TrailingCommaInArrayLiteral: + EnforcedStyleForMultiline: comma + +Style/TrailingCommaInHashLiteral: + EnforcedStyleForMultiline: comma + +Style/ClassCheck: + EnforcedStyle: kind_of? + +Style/EmptyMethod: + EnforcedStyle: expanded + +Style/Lambda: + EnforcedStyle: lambda + +Style/NumericPredicate: + EnforcedStyle: comparison + +Style/TernaryParentheses: + EnforcedStyle: require_parentheses + +Style/FormatString: + EnforcedStyle: sprintf + +Style/Semicolon: + AllowAsExpressionSeparator: true + +Style/YodaCondition: + EnforcedStyle: equality_operators_only + +Style/EmptyElse: + EnforcedStyle: empty + + +Style/GuardClause: + Enabled: false # false alarms + +Style/MethodMissingSuper: + Enabled: false # why the need to fallback to super? + +Style/Next: + Enabled: false # not really useful + +Style/ParallelAssignment: + Enabled: false # not really needed + +Style/TrivialAccessors: + Enabled: false + +Style/NestedTernaryOperator: + Enabled: false # compact nested ternary operators are okay + +Style/RescueModifier: + Enabled: false # valid but using it makes life sometimes easier + +Style/MutableConstant: + Enabled: false # valid but sometimes unavoidable + +Style/CommentedKeyword: + Enabled: false # false alarms and we do want yield comments on that line + +Style/StderrPuts: + Enabled: false # false alarms because not all $stderr.puts messages are Ruby style warnings + +Style/PerlBackrefs: + Enabled: false # sometimes there are no good alternatives + +Style/IfUnlessModifier: + Enabled: false # useful but sometimes the meaning is better conveyed using an if/unless statement + +Style/InfiniteLoop: + Enabled: false # why should Kernel#loop be better than while true? + +Style/SpecialGlobalVars: + Enabled: false # I think that $! and $? are recognizable in terms of their function + +Style/MultipleComparison: + Enabled: false # why should an array be created? especially if only two items are compared + +Style/AccessModifierDeclarations: + Enabled: false + +Style/WhileUntilModifier: + Enabled: false # I prefer to use either one or the other, depending on context + +Style/FormatStringToken: + Enabled: false # I don't care about this + +Style/ClassAndModuleChildren: + Enabled: false + + +Layout/AlignHash: + EnforcedLastArgumentHashStyle: ignore_implicit + +Layout/SpaceInsideBlockBraces: + SpaceBeforeBlockParameters: false + +Layout/SpaceInsideHashLiteralBraces: + EnforcedStyle: no_space + +Layout/EmptyLineBetweenDefs: + AllowAdjacentOneLineDefs: true + +Layout/EmptyLinesAroundModuleBody: + Enabled: false + +Layout/EmptyLinesAroundClassBody: + EnforcedStyle: empty_lines + +Layout/MultilineOperationIndentation: + EnforcedStyle: indented + +Layout/MultilineMethodCallIndentation: + EnforcedStyle: indented + +Layout/DotPosition: + EnforcedStyle: trailing + +Layout/EmptyLineAfterMagicComment: + Enabled: false # we have the magic comment and then the license + +Layout/IndentAssignment: + Enabled: false # false alarms + + +Naming/HeredocDelimiterNaming: + Enabled: false # we like our delimiters short and obvious + +Naming/UncommunicativeMethodParamName: + Enabled: false # for points the names x,y are perfectly reasonable + +Lint/LiteralAsCondition: + Enabled: false # we use while true + +Lint/NonLocalExitFromIterator: + Enabled: false + +Performance/FixedSize: + Enabled: false + + +Security/Open: + Enabled: false diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..1bce8bb --- /dev/null +++ b/COPYING @@ -0,0 +1,21 @@ +kramdown-syntax-coderay +Copyright (C) 2019 Thomas Leitner + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..799c3bf --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +# kramdown syntax highlighter based on Coderay + +This is a syntax highlighter for [kramdown](https://kramdown.gettalong.org) +that uses [coderay](http://coderay.rubychan.de/) to highlight code blocks and +spans when converting to HTML. + +Note: Until kramdown version 2.0.0 this math engine was part of the kramdown +distribution. + + +## Installation + +~~~ruby +gem install kramdown-syntax-coderay +~~~ + + +## Usage + +~~~ruby +require 'kramdown' +require 'kramdown-syntax-coderay' + +Kramdown::Document.new(text, syntax_highlighter: :coderay).to_html +~~~ + + +## Development + +Clone the git repository and you are good to go. You probably want to install +`rake` so that you can use the provided rake tasks. + + +## License + +MIT - see the **COPYING** file. diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..bb13c90 --- /dev/null +++ b/Rakefile @@ -0,0 +1,73 @@ +# -*- ruby -*- + +require 'rubygems/package_task' +require 'fileutils' +require 'rake/clean' +require 'rake/testtask' +require_relative 'lib/kramdown/converter/syntax_highlighter/coderay' + +task :default => :test +Rake::TestTask.new do |test| + test.warning = false + test.libs << 'test' + test.test_files = FileList['test/test_*.rb'] +end + +SUMMARY = 'kramdown-syntax-coderay uses coderay to highlight code blocks/spans' + +PKG_FILES = FileList.new(['COPYING', 'VERSION', 'CONTRIBUTERS', 'lib/**/*.rb', 'test/**/*']) + +CLOBBER << "VERSION" +file 'VERSION' do + puts "Generating VERSION file" + File.open('VERSION', 'w+') {|file| file.write(Kramdown::Converter::SyntaxHighlighter::Coderay::VERSION + "\n")} +end + +CLOBBER << 'CONTRIBUTERS' +file 'CONTRIBUTERS' do + puts "Generating CONTRIBUTERS file" + `echo " Count Name" > CONTRIBUTERS` + `echo "======= ====" >> CONTRIBUTERS` + `git log | grep ^Author: | sed 's/^Author: //' | sort | uniq -c | sort -nr >> CONTRIBUTERS` +end + +spec = Gem::Specification.new do |s| + s.name = 'kramdown-syntax-coderay' + s.version = Kramdown::Converter::SyntaxHighlighter::Coderay::VERSION + s.summary = SUMMARY + s.license = 'MIT' + + s.files = PKG_FILES.to_a + + s.require_path = 'lib' + s.required_ruby_version = '>= 2.3' + s.add_dependency 'kramdown', '~> 2.0' + s.add_dependency 'coderay', '~> 1.0.0' + + s.has_rdoc = true + + s.author = 'Thomas Leitner' + s.email = 't_leitner@gmx.at' + s.homepage = "https://github.com/kramdown/syntax-coderay" +end + +Gem::PackageTask.new(spec) do |pkg| + pkg.need_zip = true + pkg.need_tar = true +end + +task :gemspec => ['CONTRIBUTERS', 'VERSION'] do + print "Generating Gemspec\n" + contents = spec.to_ruby + File.write("kramdown-syntax-coderay.gemspec", contents, mode: 'w+') +end +CLOBBER << 'kramdown-syntax-coderay.gemspec' + +desc 'Release version ' + Kramdown::Converter::SyntaxHighlighter::Coderay::VERSION +task :release => [:clobber, :package, :publish_files] + +desc "Upload the release to Rubygems" +task :publish_files => [:package] do + sh "gem push pkg/kramdown-syntax-coderay-#{Kramdown::Converter::SyntaxHighlighter::Coderay::VERSION}.gem" + puts 'done' +end diff --git a/lib/kramdown-syntax-coderay.rb b/lib/kramdown-syntax-coderay.rb new file mode 100644 index 0000000..647fda9 --- /dev/null +++ b/lib/kramdown-syntax-coderay.rb @@ -0,0 +1,10 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2019 Thomas Leitner +# +# This file is part of kramdown-syntax-coderay which is licensed under the MIT. +#++ +# + +require 'kramdown/converter/syntax_highlighter/coderay' diff --git a/lib/kramdown/converter/syntax_highlighter/coderay.rb b/lib/kramdown/converter/syntax_highlighter/coderay.rb new file mode 100644 index 0000000..447775f --- /dev/null +++ b/lib/kramdown/converter/syntax_highlighter/coderay.rb @@ -0,0 +1,169 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2019 Thomas Leitner +# +# This file is part of kramdown-syntax-coderay which is licensed under the MIT. +#++ +# + +require 'kramdown/options' +require 'kramdown/converter' +require 'coderay' + +module Kramdown #:nodoc: + + module Options #:nodoc: + + define(:enable_coderay, Boolean, true, < +# +# This file is part of kramdown-syntax-coderay which is licensed under the MIT. +#++ +# + +require 'minitest/autorun' +require 'kramdown' +require 'kramdown-syntax-coderay' +require 'yaml' +require 'tmpdir' + +Encoding.default_external = 'utf-8' + +class TestFiles < Minitest::Test + + Dir[File.dirname(__FILE__) + '/testcases/**/*.text'].each do |text_file| + basename = text_file.sub(/\.text$/, '') + + html_file = basename + '.html' + define_method('test_' + text_file.tr('.', '_') + "_to_html") do + opts_file = basename + '.options' + opts_file = File.join(File.dirname(html_file), 'options') if !File.exist?(opts_file) + options = File.exist?(opts_file) ? YAML::load(File.read(opts_file)) : {auto_ids: false, footnote_nr: 1} + doc = Kramdown::Document.new(File.read(text_file), options) + assert_equal(File.read(html_file), doc.to_html) + end + end + +end diff --git a/test/testcases/highlighting-opts.html b/test/testcases/highlighting-opts.html new file mode 100644 index 0000000..5a2ea48 --- /dev/null +++ b/test/testcases/highlighting-opts.html @@ -0,0 +1,6 @@ +
x = Class.new + +
+
<a>href</a> + +
diff --git a/test/testcases/highlighting-opts.options b/test/testcases/highlighting-opts.options new file mode 100644 index 0000000..0e04a45 --- /dev/null +++ b/test/testcases/highlighting-opts.options @@ -0,0 +1,8 @@ +:syntax_highlighter: :coderay +:syntax_highlighter_opts: + block: + css: class + default_lang: ruby + wrap: span + line_numbers: null + diff --git a/test/testcases/highlighting-opts.text b/test/testcases/highlighting-opts.text new file mode 100644 index 0000000..5ac4746 --- /dev/null +++ b/test/testcases/highlighting-opts.text @@ -0,0 +1,4 @@ + x = Class.new +^ + href +{: .language-html} diff --git a/test/testcases/highlighting-span.html b/test/testcases/highlighting-span.html new file mode 100644 index 0000000..c6860f6 --- /dev/null +++ b/test/testcases/highlighting-span.html @@ -0,0 +1 @@ +

You can say x = Class.new, for example.

diff --git a/test/testcases/highlighting-span.options b/test/testcases/highlighting-span.options new file mode 100644 index 0000000..ca85a88 --- /dev/null +++ b/test/testcases/highlighting-span.options @@ -0,0 +1 @@ +:syntax_highlighter: :coderay diff --git a/test/testcases/highlighting-span.text b/test/testcases/highlighting-span.text new file mode 100644 index 0000000..7373290 --- /dev/null +++ b/test/testcases/highlighting-span.text @@ -0,0 +1 @@ +You can say `x = Class.new`{:.language-ruby}, for example. diff --git a/test/testcases/highlighting.html b/test/testcases/highlighting.html new file mode 100644 index 0000000..5a2ea48 --- /dev/null +++ b/test/testcases/highlighting.html @@ -0,0 +1,6 @@ +
x = Class.new + +
+
<a>href</a> + +
diff --git a/test/testcases/highlighting.options b/test/testcases/highlighting.options new file mode 100644 index 0000000..c8b8162 --- /dev/null +++ b/test/testcases/highlighting.options @@ -0,0 +1,6 @@ +:syntax_highlighter: :coderay +:coderay_default_lang: ruby +:coderay_wrap: span +:coderay_line_numbers: ~ +:coderay_css: class + diff --git a/test/testcases/highlighting.text b/test/testcases/highlighting.text new file mode 100644 index 0000000..5ac4746 --- /dev/null +++ b/test/testcases/highlighting.text @@ -0,0 +1,4 @@ + x = Class.new +^ + href +{: .language-html}