[SVN] r2829 (Ruby)

Gavin Kistner gavin at refinery.com
Tue Mar 7 16:09:35 UTC 2006


On Mar 7, 2006, at 4:43 AM, Allan Odgaard wrote:
> • stdout and stderr for the forked process (which loads the script)  
> are now set to a pair of pipes, so that filtering (escaping) of  
> output will happen even when that output isn’t going through the  
> (previously modified) STDOUT object
> • output sent to stderr now show up as red

I'm working on this myself for a Ruby runner for Lua commands. I've  
pasted what I have so far at the end.

I am seeing all sorts of stalling problems with the new tmruby.rb.  
For example, this simple script:
puts 'hello'
warn 'Whoa! I expected to see "hello world", but saw "hello"'
puts 'world'

Sometimes works, sometimes shows only the warning and stalls (spinner  
in upper right) indefinitely, and sometimes shows only the stdout and  
stalls.



One thing that neither mine nor yours does it allow the interleaving  
of stdout and stderr, with identification of which is which. For  
example, with the above, I'd love to find a way to have the output be:
hello
Whoa! I expected to see "hello world", but saw "hello"         (in  
red, or otherwise marked in HTML)
world

Any thoughts on how to do this?


-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
My Lua runner so far. Only current problem, I think, is some filename  
escaping issues (solvable) and the fact that I can't catch the actual  
exitstatus using open3. (But Ara Howard has given me a solution with  
another Ruby library, open4, that I may use.

# Run a Lua file and produce TextMate HTML output
# by Gavin Kistner
#
# Revision History
# 2006-03-01	Version 1.0b1
#
# Known Bugs
# - Long path names are truncated by the lua runtime, and improperly  
linked
#   Recompile Lua with LUA_IDSIZE set to a larger value in luaconf.h  
to fix
#   TODO: use heuristics to guess at common path and make a good link.

require 'cgi'       # for it's HTML-escaping utilities
require 'pathname'  # for manipulating file paths
require 'open3'     # for capturing stdout & stderr

$KCODE = 'u'

file_path = Pathname.new( ARGV[0].gsub( %r{([^\w/.])}, '\\\\\1' ) )
file_name = file_path.basename.to_s
file_dir  = file_path.parent.to_s
my_dir    = Pathname.new( __FILE__ ).parent.to_s

output, errors = '', ''
t1 = Time.new
Open3::popen3( "lua #{file_path}" ){ |i,o,e|
	i.close
	o.each { |line| output << line }
	e.each { |line| errors << line }
}
t2 = Time.new

output = CGI.escapeHTML( output )
errors = CGI.escapeHTML( errors )
unless errors.empty?
	# Link error lines to files
	errors.gsub!( %r{(\S*/.+/)([^/]+):(\d+)} ){ |orig|
		path, file, line = $1, $2, $3
		if orig =~ /^\.{3,}/ then
			# Lua truncated the path, we can't link it...for now
			orig
		else
			htmlpath = CGI.escape( "file://" + File.expand_path( path+file,  
file_dir ).gsub( /\\(.)/, '\\1' ) ).gsub('+','%20')
			#htmlpath = "file://" + File.expand_path( path+file,  
file_dir ).gsub( /\\(.)/, '\\1' )
			#p orig, htmlpath
			"#{path}<a href='txmt://open?url=#{htmlpath}&line=#{line}'  
title='Go to line ##{line} in #{CGI.escapeHTML(CGI.unescape 
(htmlpath))}'>#{file}:#{line}</a>"
		end
	}
end

html = <<ENDHTML
<html><head>
	<title>Output from #{file_name}</title>
	<style>#{IO.read(File.join(my_dir,'tmlua.css'))}</style>
	<script type="text/javascript">
		function ToggleWrap( inButton ){
			var theOutput = document.getElementById( 'output' )
			var theErrors = document.getElementById( 'errors' )
			if ( inButton.wrappedFlag ){
				Unwrap( theOutput ); Unwrap( theErrors )
				inButton.value = 'Wrap Output'
				inButton.wrappedFlag = false
			}else{
				Wrap( theOutput ); Wrap( theErrors )
				inButton.value = 'Unwrap Output'
				inButton.wrappedFlag = true
			}
		}
		function Wrap( inEl ){
			if (!inEl) return;
			inEl.className = 'wrapped';
			inEl.innerHTML = inEl.innerHTML.replace( /\\r\\n|\\r|\\n/g, '<br>' )
		}
		function Unwrap( inEl ){
			if (!inEl) return;
			inEl.className = 'unwrapped';
			inEl.innerHTML = inEl.innerHTML.replace( /<br>/g, '\\n' )
		}
	</script>
</head><body>
	<input type="button" id="wrap" onclick="ToggleWrap(this)"  
value="Wrap Output">
	<pre id="output" class="unwrapped">#{output}</pre>
	#{unless errors.empty?
		%Q{<pre id="errors" class="unwrapped">#{errors}</pre>}
	end}
	<p>Finished in #{"%.3f" % (t2 - t1)} seconds</p>
</body></html>
ENDHTML

# Show the raw source of the page at the bottom for debugging
#html.gsub!( '</body>', "<pre id='source'>#{CGI.escapeHTML(html)}</ 
pre></body>" )

puts html


More information about the textmate-dev mailing list