Merge pull request #6484 from opf/fix/pandoc-version

Detect pandoc functionality based on usage and output formats

[ci skip]
pull/6487/head
Oliver Günther 6 years ago committed by GitHub
commit b369437307
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 110
      lib/open_project/text_formatting/formats/markdown/pandoc_wrapper.rb
  2. 22
      lib/open_project/text_formatting/formats/markdown/textile_converter.rb
  3. 99
      spec/lib/open_project/text_formatting/markdown/pandoc_wrapper_spec.rb

@ -0,0 +1,110 @@
#-- encoding: UTF-8
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2017 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See docs/COPYRIGHT.rdoc for more details.
#++
require 'open3'
module OpenProject::TextFormatting::Formats
module Markdown
class PandocWrapper
def initialize; end
def execute!(stdin)
run_pandoc! pandoc_arguments, stdin_data: stdin
end
def pandoc_arguments
[
wrap_mode,
'--atx-headers',
'-f',
'textile',
'-t',
output_format
]
end
##
# Detect available output markdown format
# pandoc recommends format 'gfm' but that isnt available in current LTS
# markdown_github, which is deprecated, is however available.
def output_format
if gfm_supported?
'gfm'
else
'markdown_github'
end
end
##
# Detect available wrap mode
# --wrap=preserve will keep the wrapping the same, however is only available in versions 1.16+
# In older versions we try to use the deprecated --no-wrap instead
# --atx-headers will lead to headers like `### Some header` and '## Another header'
def wrap_mode
usage = read_usage_string
# Detect wrap usage
if usage.include? '--wrap='
'--wrap=preserve'
elsif usage.include? '--no-wrap'
'--no-wrap'
else
raise 'Your pandoc version has neither --no-wrap nor --wrap=preserve. Please install a recent version of pandoc.'
end
end
##
# Detect whether an output format for gfm exists
# so we don't have to use the legacy github_markdown format.
def gfm_supported?
read_output_formats.match? /^gfm$/
end
private
##
# Run pandoc through open3 and raise if an exception occurred
def run_pandoc!(args, **options)
output, stderr_str, status = Open3.capture3('pandoc', *args, **options)
raise stderr_str unless status.success?
output
end
def read_usage_string
run_pandoc! %w[--help]
end
def read_output_formats
run_pandoc! %w[--list-output-formats]
end
end
end
end

@ -52,7 +52,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
require 'open3'
require_relative 'pandoc_wrapper'
module OpenProject::TextFormatting::Formats
module Markdown
@ -186,22 +186,18 @@ module OpenProject::TextFormatting::Formats
cleanup_before_pandoc(textile)
# TODO pandoc recommends format 'gfm' but that isnt available in current LTS
# markdown_github, which is deprecated, is however available.
# --wrap=preserve will keep the wrapping the same
# --atx-headers will lead to headers like `### Some header` and '## Another header'
command = %w(pandoc --wrap=preserve --atx-headers -f textile -t markdown_github)
markdown, stderr_str, status = begin
Open3.capture3(*command, stdin_data: textile)
rescue StandardError
raise "Pandoc failed with unspecific error"
end
raise "Pandoc failed: #{stderr_str}" unless status.success?
markdown = execute_pandoc_with_stdin! textile
cleanup_after_pandoc(markdown)
end
def execute_pandoc_with_stdin!(textile)
wrapper = PandocWrapper.new
wrapper.execute! textile
rescue StandardError => e
raise "Execution of pandoc failed: #{e}"
end
def models_to_convert
{
::Announcement => [:text],

@ -0,0 +1,99 @@
#-- encoding: UTF-8
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2017 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See docs/COPYRIGHT.rdoc for more details.
#++
require 'spec_helper'
describe OpenProject::TextFormatting::Formats::Markdown::PandocWrapper do
let(:subject) { described_class.new }
let(:output_formats) { "gfm\n foo\n" }
before do
allow(subject).to receive(:read_usage_string).and_return(usage_string)
allow(subject).to receive(:read_output_formats).and_return(output_formats)
end
describe 'gfm mode' do
let(:usage_string) { 'does not matter' }
context 'when gfm exists' do
it 'uses gfm format' do
expect(subject.output_format).to eq 'gfm'
end
end
context 'when gfm does not exist' do
let(:output_formats) { "bar\n foo\n" }
it 'uses the legacy format' do
expect(subject.output_format).to eq 'markdown_github'
end
end
end
describe 'wrap mode' do
context 'when wrap=preserve exists' do
let(:usage_string) do
<<~EOS
--list-output-formats
--list-highlight-languages
--list-highlight-styles
--wrap=auto|none|preserve
-v --version
-h --help
EOS
end
it do
expect(subject.wrap_mode).to eq('--wrap=preserve')
end
end
context 'when only no-wrap exists' do
let(:usage_string) do
<<~EOS
--list-output-formats
--list-highlight-languages
--list-highlight-styles
--no-wrap
-v --version
-h --help
EOS
end
it do
expect(subject.wrap_mode).to eq('--no-wrap')
end
end
context 'when neither exists' do
let(:usage_string) { 'wat?' }
it do
expect { subject.wrap_mode }.to raise_error 'Your pandoc version has neither --no-wrap nor --wrap=preserve. Please install a recent version of pandoc.'
end
end
end
end
Loading…
Cancel
Save