<commit_before># Copyright (c) 2010-2020 <NAME> and <NAME>
#
# This program is free software.
# You can distribute or modify this program under the terms of
# the GNU LGPL, Lesser General Public License version 2.1.
# For details of the GNU LGPL, see the file "COPYING".
#
require 'optparse'
require 'yaml'
require 'fileutils'
require 'erb'
require 'tmpdir'
require 'open3'
require 'shellwords'

require 'review/i18n'
require 'review/book'
require 'review/configure'
require 'review/converter'
require 'review/latexbuilder'
require 'review/yamlloader'
require 'review/version'
require 'review/makerhelper'
require 'review/template'

module ReVIEW
  class PDFMaker
    include FileUtils
    include ReVIEW::LaTeXUtils

    attr_accessor :config, :basedir

    def initialize
      @basedir = nil
      @logger = ReVIEW.logger
      @input_files = Hash.new { |h, key| h[key] = '' }
      @mastertex = '__REVIEW_BOOK__'
    end

    def system_with_info(*args)
      @logger.info args.join(' ')
      out, status = Open3.capture2e(*args)
      unless status.success?
        @logger.error "execution error\n\nError log:\n" + out
      end
    end

    def system_or_raise(*args)
      @logger.info args.join(' ')
      out, status = Open3.capture2e(*args)
      unless status.success?
        error "failed to run command: #{args.join(' ')}\n\nError log:\n" + out
      end
    end

    def error(msg)
      @logger.error msg
      exit 1
    end

    def warn(msg)
      @logger.warn msg
    end

    def pdf_filepath
      File.join(@basedir, @config['bookname'] + '.pdf')
    end

    def remove_old_file
      FileUtils.rm_f(pdf_filepath)
    end

    def build_path
      if @config['debug']
        path = "#{@config['bookname']}-pdf"
        if File.exist?(path)
          FileUtils.rm_rf(path, secure: true)
        end
        Dir.mkdir(path)
        path
      else
        Dir.mktmpdir("#{@config['bookname']}-pdf-")
      end
    end

    def check_compile_status(ignore_errors)
      return unless @compile_errors

      if ignore_errors
        @logger.info 'compile error, but try to generate PDF file'
      else
        error 'compile error, No PDF file output.'
      end
    end

    def self.execute(*args)
      self.new.execute(*args)
    end

    def parse_opts(args)
      cmd_config = {}
      opts = OptionParser.new

      opts.banner = 'Usage: review-pdfmaker configfile'
      opts.version = ReVIEW::VERSION
      opts.on('--help', 'Prints this message and quit.') do
        puts opts.help
        exit 0
      end
      opts.on('--[no-]debug', 'Keep temporary files.') { |debug| cmd_config['debug'] = debug }
      opts.on('--ignore-errors', 'Ignore review-compile errors.') { cmd_config['ignore-errors'] = true }

      opts.parse!(args)
      if args.size != 1
        puts opts.help
        exit 0
      end

      [cmd_config, args[0]]
    end

    def execute(*args)
      @config = ReVIEW::Configure.values
      @config.maker = 'pdfmaker'
      cmd_config, yamlfile = parse_opts(args)
      error "#{yamlfile} not found." unless File.exist?(yamlfile)

      begin
        loader = ReVIEW::YAMLLoader.new
        @config.deep_merge!(loader.load_file(yamlfile))
      rescue => e
        error "yaml error #{e.message}"
      end

      # YAML configs will be overridden by command line options.
      @config.deep_merge!(cmd_config)
      I18n.setup(@config['language'])
      @basedir = File.absolute_path(File.dirname(yamlfile))

      begin
        @config.check_version(ReVIEW::VERSION)
      rescue ReVIEW::ConfigError => e
        warn e.message
      end

      # version 2 compatibility
      unless @config['texdocumentclass']
        if @config.check_version(2, exception: false)
          @config['texdocumentclass'] = ['jsbook', 'uplatex,oneside']
        else
          @config['texdocumentclass'] = @config['_texdocumentclass']
        end
      end

      # version 4.0 compatibility
      if @config['image_scale2width']
        warn 'image_scale2width parameter is moved to under pdfmaker section'
        @config['pdfmaker']['image_scale2width'] = @config['image_scale2width']
      end

      begin
        generate_pdf
      rescue ApplicationError => e
        raise if @config['debug']
        error(e.message)
      end
    end

    def make_input_files(book)
      input_files = Hash.new { |h, key| h[key] = '' }
      book.parts.each do |part|
        if part.name.present?
          @config['use_part'] = true
          if part.file?
            output_chaps(part.name)
            input_files['CHAPS'] << %Q(\\input{#{part.name}.tex}\n)
          else
            input_files['CHAPS'] << %Q(\\part{#{part.name}}\n)
          end
        end

        part.chapters.each do |chap|
          filename = File.basename(chap.path, '.*')
          output_chaps(filename)
          input_files['PREDEF'] << "\\input{#{filename}.tex}\n" if chap.on_predef?
          input_files['CHAPS'] << "\\input{#{filename}.tex}\n" if chap.on_chaps?
          input_files['APPENDIX'] << "\\input{#{filename}.tex}\n" if chap.on_appendix?
          input_files['POSTDEF'] << "\\input{#{filename}.tex}\n" if chap.on_postdef?
        end
      end

      input_files
    end
<commit_msg>PDFMaker: add -y option to choose build target<commit_after># Copyright (c) 2010-2020 <NAME> and <NAME>
#
# This program is free software.
# You can distribute or modify this program under the terms of
# the GNU LGPL, Lesser General Public License version 2.1.
# For details of the GNU LGPL, see the file "COPYING".
#
require 'optparse'
require 'yaml'
require 'fileutils'
require 'erb'
require 'tmpdir'
require 'open3'
require 'shellwords'

require 'review/i18n'
require 'review/book'
require 'review/configure'
require 'review/converter'
require 'review/latexbuilder'
require 'review/yamlloader'
require 'review/version'
require 'review/makerhelper'
require 'review/template'

module ReVIEW
  class PDFMaker
    include FileUtils
    include ReVIEW::LaTeXUtils

    attr_accessor :config, :basedir

    def initialize
      @basedir = nil
      @logger = ReVIEW.logger
      @input_files = Hash.new { |h, key| h[key] = '' }
      @mastertex = '__REVIEW_BOOK__'
    end

    def system_with_info(*args)
      @logger.info args.join(' ')
      out, status = Open3.capture2e(*args)
      unless status.success?
        @logger.error "execution error\n\nError log:\n" + out
      end
    end

    def system_or_raise(*args)
      @logger.info args.join(' ')
      out, status = Open3.capture2e(*args)
      unless status.success?
        error "failed to run command: #{args.join(' ')}\n\nError log:\n" + out
      end
    end

    def error(msg)
      @logger.error msg
      exit 1
    end

    def warn(msg)
      @logger.warn msg
    end

    def pdf_filepath
      File.join(@basedir, @config['bookname'] + '.pdf')
    end

    def remove_old_file
      FileUtils.rm_f(pdf_filepath)
    end

    def build_path
      if @config['debug']
        path = "#{@config['bookname']}-pdf"
        if File.exist?(path)
          FileUtils.rm_rf(path, secure: true)
        end
        Dir.mkdir(path)
        path
      else
        Dir.mktmpdir("#{@config['bookname']}-pdf-")
      end
    end

    def check_compile_status(ignore_errors)
      return unless @compile_errors

      if ignore_errors
        @logger.info 'compile error, but try to generate PDF file'
      else
        error 'compile error, No PDF file output.'
      end
    end

    def self.execute(*args)
      self.new.execute(*args)
    end

    def parse_opts(args)
      cmd_config = {}
      opts = OptionParser.new
      @buildonly = nil

      opts.banner = 'Usage: review-pdfmaker configfile'
      opts.version = ReVIEW::VERSION
      opts.on('--help', 'Prints this message and quit.') do
        puts opts.help
        exit 0
      end
      opts.on('--[no-]debug', 'Keep temporary files.') { |debug| cmd_config['debug'] = debug }
      opts.on('--ignore-errors', 'Ignore review-compile errors.') { cmd_config['ignore-errors'] = true }
      opts.on('-y', '--only file1,file2,...', 'Build only specified files.') { |v| @buildonly = v.split(/\s*,\s*/).map { |m| m.strip.sub(/\.re\Z/, '') } }

      opts.parse!(args)
      if args.size != 1
        puts opts.help
        exit 0
      end

      [cmd_config, args[0]]
    end

    def execute(*args)
      @config = ReVIEW::Configure.values
      @config.maker = 'pdfmaker'
      cmd_config, yamlfile = parse_opts(args)
      error "#{yamlfile} not found." unless File.exist?(yamlfile)

      begin
        loader = ReVIEW::YAMLLoader.new
        @config.deep_merge!(loader.load_file(yamlfile))
      rescue => e
        error "yaml error #{e.message}"
      end

      # YAML configs will be overridden by command line options.
      @config.deep_merge!(cmd_config)
      I18n.setup(@config['language'])
      @basedir = File.absolute_path(File.dirname(yamlfile))

      begin
        @config.check_version(ReVIEW::VERSION)
      rescue ReVIEW::ConfigError => e
        warn e.message
      end

      # version 2 compatibility
      unless @config['texdocumentclass']
        if @config.check_version(2, exception: false)
          @config['texdocumentclass'] = ['jsbook', 'uplatex,oneside']
        else
          @config['texdocumentclass'] = @config['_texdocumentclass']
        end
      end

      # version 4.0 compatibility
      if @config['image_scale2width']
        warn 'image_scale2width parameter is moved to under pdfmaker section'
        @config['pdfmaker']['image_scale2width'] = @config['image_scale2width']
      end

      begin
        generate_pdf
      rescue ApplicationError => e
        raise if @config['debug']
        error(e.message)
      end
    end

    def make_input_files(book)
      input_files = Hash.new { |h, key| h[key] = '' }
      book.parts.each do |part|
        if part.name.present?
          @config['use_part'] = true
          if part.file?
            if @buildonly && !@buildonly.include?(part.name)
              input_files['CHAPS'] << %Q(\\part{}\n)
            else
              output_chaps(part.name)
              input_files['CHAPS'] << %Q(\\input{#{part.name}.tex}\n)
            end
          else
            input_files['CHAPS'] << %Q(\\part{#{part.name}}\n)
          end
        end

        part.chapters.each do |chap|
          filename = File.basename(chap.path, '.*')
          entry = "\\input{#{filename}.tex}\n"
          if @buildonly && !@buildonly.include?(filename)
            entry = "\\chapter{}\n"
          else
            output_chaps(filename)
          end

          input_files['PREDEF'] << entry if chap.on_predef?
          input_files['CHAPS'] << entry if chap.on_chaps?
          input_files['APPENDIX'] << entry if chap.on_appendix?
          input_files['POSTDEF'] << entry if chap.on_postdef?
        end
      end

      input_files
    end

{'fraction_non_alphanumeric': 0.12418480756865986, 'fraction_numerical': 0.00606227610912097, 'mean_word_length': 2.343980343980344, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7112550', 'n_tokens_mistral': 3465, 'n_tokens_neox': 3361, 'n_words': 827}