Created
March 4, 2015 20:00
-
-
Save avdgaag/f40be301ef37a52b8c7b to your computer and use it in GitHub Desktop.
Revisions
-
avdgaag created this gist
Mar 4, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,135 @@ #!/usr/bin/env ruby require 'open3' require 'tmpdir' module Literate class Line INDENT = ''.freeze def self.indent(str) return str if str == "" str.gsub(/^/, INDENT) end def initialize(str) @str = str end def to_s @str end def cd? !path.nil? end def path @str[/^#{INDENT}%-? cd (.+)$/, 1] end def silent? @str =~ /^#{INDENT}%- / end def ignore? @str =~ /^#{INDENT}%% / end def command? @str =~ /^#{INDENT}% / end def plain? !silent? && !ignore? && !command? end def formatted_command "#{INDENT}% #{command}\n" end def command @command ||= begin @str[/^#{INDENT}%[-%]? (.+)$/, 1].gsub /\{\{(.+)\}\}/ do |match| Command.capture($1.strip).chomp end end end end def self.in_masked_tmpdir original_directory = Dir.pwd new_dir = File.join(Dir.pwd, 'tmp') Dir.chdir(new_dir) yield(new_dir).gsub(new_dir, "~/examples") ensure Dir.chdir original_directory end class LineReader include Enumerable def initialize(source) @source = source end def each @source.each_line do |line| yield Line.new(line) end end end class Command attr_reader :line def initialize(line) @line = line end def result if line.silent? run '' elsif line.ignore? || line.cd? line.formatted_command elsif line.command? line.formatted_command + Line.indent(run) else line.to_s end end def self.capture(cmd) input, output, wait_thr = Open3.popen2e(cmd) output.read ensure input.close output.close end private def run self.class.capture(line.command) end end def self.literalize(str) in_masked_tmpdir do |dir| original_directory = dir LineReader.new(str).each_with_object('') do |line, output| if line.cd? dir = File.join(dir, line.path) raise "Invalid path: #{dir}" unless dir.start_with?(original_directory) Dir.chdir(dir) end output << Command.new(line).result end end end end puts Literate.literalize(STDIN.read)