Check for a @pid variable, and then hit `kill -0` with the pid to check if the pid is still in the process table. If this function gives us an ENOENT or ESRCH, we can also safely return false (no process to worry about). Defensively, if EPERM is raised, in a odd/rare dying process situation (e.g., mentos is checking on the pid of a dead process and the pid has already been re-used) we'll want to raise that as a more informative Mentos exception.
Returns true if the child is alive.
# File lib/pygments/popen.rb, line 77 def alive? return true if @pid && Process.kill(0, @pid) false rescue Errno::ENOENT, Errno::ESRCH false rescue Errno::EPERM raise MentosError, "EPERM checking if child process is alive." end
Public: Return css for highlighted code
# File lib/pygments/popen.rb, line 149 def css(klass='', opts={}) if klass.is_a?(Hash) opts = klass klass = '' end mentos(:css, ['html', klass], opts) end
Public: Return an array of all available filters
# File lib/pygments/popen.rb, line 139 def filters mentos(:get_all_filters) end
Public: Get an array of available Pygments formatters
Returns an array of formatters.
# File lib/pygments/popen.rb, line 89 def formatters mentos(:get_all_formatters).inject(Hash.new) do | hash, (name, desc, aliases) | # Remove the long-winded and repetitive 'Formatter' suffix name.sub!(/Formatter$/, '') hash[name] = { :name => name, :description => desc, :aliases => aliases } hash end end
Public: Highlight code.
Takes a first-position argument of the code to be highlighted, and a second-position hash of various arguments specifiying highlighting properties.
# File lib/pygments/popen.rb, line 179 def highlight(code, opts={}) # If the caller didn't give us any code, we have nothing to do, # so return right away. return code if code.nil? || code.empty? # Callers pass along options in the hash opts[:options] ||= {} # Default to utf-8 for the output encoding, if not given. opts[:options][:outencoding] ||= 'utf-8' # Get back the string from mentos and force encoding if we can str = mentos(:highlight, nil, opts, code) str.force_encoding(opts[:options][:outencoding]) if str.respond_to?(:force_encoding) str end
Public: Return the name of a lexer.
# File lib/pygments/popen.rb, line 158 def lexer_name_for(*args) # Pop off the last arg if it's a hash, which becomes our opts if args.last.is_a?(Hash) opts = args.pop else opts = {} end if args.last.is_a?(String) code = args.pop else code = nil end mentos(:lexer_name_for, args, opts, code) end
Public: Get all lexers from a serialized array. This avoids needing to spawn mentos when it's not really needed (e.g,. one-off jobs, loading the Rails env, etc).
Should be preferred to lexers!
Returns an array of lexers
# File lib/pygments/popen.rb, line 109 def lexers begin lexer_file = File.expand_path('../../../lexers', __FILE__) raw = File.open(lexer_file, "r").read Marshal.load(raw) rescue Errno::ENOENT raise MentosError, "Error loading lexer file. Was it created and vendored?" end end
Public: Get back all available lexers from mentos itself
Returns an array of lexers
# File lib/pygments/popen.rb, line 122 def lexers! mentos(:get_all_lexers).inject(Hash.new) do |hash, lxr| name = lxr[0] hash[name] = { :name => name, :aliases => lxr[1], :filenames => lxr[2], :mimetypes => lxr[3] } hash["Augeas"] = {:name=>"Augeas", :aliases=>["augeas"], :filenames=>["*.aug"], :mimetypes=>[]} hash["dasm16"] = {:name=>"dasm16", :aliases=>["DASM16"], :filenames=>["*.dasm16", "*.dasm"], :mimetypes=>['text/x-dasm16']} hash["Puppet"] = {:name=>"Puppet", :aliases=>["puppet"], :filenames=>["*.pp"], :mimetypes=>[]} hash end end
Get things started by opening a pipe to mentos (the freshmaker), a Python process that talks to the Pygments library. We'll talk back and forth across this pipe.
# File lib/pygments/popen.rb, line 21 def start(pygments_path = File.expand_path('../../../vendor/pygments-main/', __FILE__)) is_windows = RUBY_PLATFORM =~ /mswin|mingw/ begin @log = Logger.new(ENV['MENTOS_LOG'] ||= is_windows ? 'NUL:' : '/dev/null') @log.level = Logger::INFO @log.datetime_format = "%Y-%m-%d %H:%M " rescue @log = Logger.new(is_windows ? 'NUL:' : '/dev/null') end ENV['PYGMENTS_PATH'] = pygments_path # Make sure we kill off the child when we're done at_exit { stop "Exiting" } # A pipe to the mentos python process. #popen4 gives us # the pid and three IO objects to write and read. script = File.expand_path('../mentos.py', __FILE__) script = 'python ' + script if is_windows @pid, @in, @out, @err = popen4(script) @log.info "[#{Time.now.iso8601}] Starting pid #{@pid.to_s} with fd #{@out.to_i.to_s}." end
Stop the child process by issuing a kill -9.
We then call waitpid() with the pid, which waits for that particular child and reaps it.
kill() can set errno to ESRCH if, for some reason, the file is gone; regardless the final outcome of this method will be to set our @pid variable to nil.
Technically, kill() can also fail with EPERM or EINVAL (wherein the signal isn't sent); but we have permissions, and we're not doing anything invalid here.
# File lib/pygments/popen.rb, line 56 def stop(reason) if @pid begin Process.kill('KILL', @pid) Process.waitpid(@pid) rescue Errno::ESRCH, Errno::ECHILD end end @log.info "[#{Time.now.iso8601}] Killing pid: #{@pid.to_s}. Reason: #{reason}" @pid = nil end
Generated with the Darkfish Rdoc Generator 2.