#!/usr/bin/env ruby # frozen_string_literal: true require 'optimist' require_relative '../lib/rsyntaxtree' require_relative '../lib/rsyntaxtree/utils' opts = Optimist.options do version "RSyntaxTree #{RSyntaxTree::VERSION} (c) 2023 Yoichiro Hasebe" banner <<~BANNER RSyntaxTree, (linguistic) syntax tree generator written in Ruby. Usage: 1) rsyntaxtree [options] "[VP [VP [V set] [NP bracket notation]] [ADV here]]" 2) rsyntaxtree [options] "/path/to/text/file" where [options] are: BANNER opt :outdir, "Output directory", default: "./" opt :format, "Output format: png, pdf, or svg", default: "png" opt :leafstyle, "visual style of tree leaves: auto, triangle, bar, or nothing", default: "auto" opt :fontstyle, "Font style (available when ttf font is specified): sans, serif, cjk, mono", default: "sans" opt :font, "Path to a ttf font used to generate tree (optional)", type: String opt :fontsize, "Size: 8-26", default: 16 opt :linewidth, "Size: 1-5", default: 1 opt :vheight, "Connector Height: 0.5-5.0", default: 2.0 opt :color, "Color text and bars: modern, traditional, or off", default: "modern" opt :symmetrize, "Generate radically symmetrical, balanced tree: on or off", default: "off" opt :transparent, "Make background transparent: on or off", default: "off" opt :polyline, "draw polyline connectors: on or off", default: "off" opt :hide_default_connectors, "make default connectors transparent: on or off", default: "off" opt :help, "This is a custom help message", short: :h end Optimist.die :outdir, "must be an exsting directory path" unless FileTest.directory?(opts[:outdir]) Optimist.die :format, "must be png, pdf, or svg" unless /\A(png|jpg|gif|pdf|svg)\z/ =~ opts[:format] Optimist.die :leafstyle, "must be auto, triangle, bar, or nothing" unless /\A(auto|triangle|bar|nothing)\z/ =~ opts[:leafstyle] Optimist.die :fontstyle, "must be sans, serif, cjk, or mono" unless /\A(sans|serif|cjk|mono)\z/ =~ opts[:fontstyle] Optimist.die :font, "must be path to an existing ttf font" if opts[:font] && !File.exist?(opts[:font]) Optimist.die :fontsize, "must be in the range of 8-26" unless opts[:fontsize] >= 8 && opts[:fontsize] <= 26 Optimist.die :linewidth, "must be in the range of 1-5" unless opts[:linewidth] >= 1 && opts[:linewidth] <= 5 Optimist.die :color, "must be either modern, traditional, or off" unless /\A(modern|traditional|on|off|true|false)\z/ =~ opts[:color] Optimist.die :symmetrize, "must be either on or off" unless /\A(on|off|true|false)\z/ =~ opts[:symmetrize] Optimist.die :vheight, "must be in the range of 0.5-5.0" if opts[:vheight] < 0.5 || opts[:vheight] > 5.0 Optimist.die :transparent, "must be either on or off" unless /\A(on|off|true|false)\z/ =~ opts[:transparent] Optimist.die :polyline, "must be either on or off" unless /\A(on|off|true|false)\z/ =~ opts[:polyline] Optimist.die :hide_default_connectors, "must be either on or off" unless /\A(on|off|true|false)\z/ =~ opts[:hide_default_connectors] string_opts = {} opts.each do |key, value| string_opts[key.to_sym] = value unless key == :font && !value end data = if ARGV[0] && File.exist?(File.expand_path(ARGV[0])) File.read ARGV[0] else ARGV[0] end begin RSyntaxTree::RSGenerator.check_data(data) rescue RSTError => e puts e exit end begin string_opts[:data] = data rsg = RSyntaxTree::RSGenerator.new(string_opts) ext = string_opts[:format] filepath = File.expand_path(string_opts[:outdir]) + "/syntree." + ext case ext when "pdf" outfile = File.new(filepath, "wb") outfile.write rsg.draw_pdf outfile.close when "png" outfile = File.new(filepath, "wb") outfile.write rsg.draw_png outfile.close when "svg" outfile = File.new(filepath, "wb") outfile.write rsg.draw_svg outfile.close end rescue RSTError => e puts e exit rescue StandardError => e p e puts "Error: something unexpected occurred" exit end