class Patman
{Patman} (Patch Manipulator) is a library for text file patching. It can also be used to extract information from files.
Constants
- VERSION
Attributes
Public Class Methods
Edit file and also create it if it does not exist.
If block is given, a file will be opened and block with Patman
commands will be executed for it. Otherwise a Patman
object is returned for further use.
# File lib/patman.rb, line 31 def Patman.edit( file, &blk ) p = Patman.new( file ) if File.exist?( file ) p.send( :read, file ) end if block_given? p.instance_exec( &blk ) p.send( :write ) else p end end
Create {Patman} object.
# File lib/patman.rb, line 45 def initialize( file ) @file = file @lines = [] @line = 0 @mark = nil @marks = {} @blockline = nil @edited = false end
Create editing session with file.
# File lib/patman.rb, line 19 def Patman.read( file ) p = Patman.new( file ) p.read p end
# File lib/version.rb, line 3 def Patman.version Patman::VERSION end
Public Instance Methods
Reference {Patman} content by range.
# File lib/patman.rb, line 141 def []( range ) @lines[ range ] end
Append after current position.
# File lib/patman.rb, line 210 def append( text = nil ) @edited = true if text.kind_of? Array text.each do |txt| append( txt ) end else step @lines.insert( @line, text ) end self end
Jump to line after block.
# File lib/patman.rb, line 123 def blockline if @blockline @line = @blockline end self end
Clear {Patman} content and reset current line.
# File lib/patman.rb, line 243 def clear @edited = true @lines = [] @line = 0 self end
Copy {Patman} content to file.
# File lib/patman.rb, line 89 def copy( file ) write( file ) self end
Delete current line.
# File lib/patman.rb, line 224 def delete( count = 1 ) @edited = true count.times do |i| @lines.delete_at( @line ) end self end
Execute given block for all lines, i.e. all positions. Block parameter is {Patman}.
# File lib/patman.rb, line 324 def do_all( &blk ) do_for( 1, length-1, &blk ) end
Execute given block starting from start by count, and update position.
# File lib/patman.rb, line 336 def do_for( start, count, &blk ) line = @line @line = start-1 count.times do yield self @line += 1 end @blockline = @line @line = line self end
Execute given block between start and stop positions, and update position.
# File lib/patman.rb, line 330 def do_range( start, stop, &blk ) do_for( start, (stop-start+1), &blk ) end
Mark content modified (explicit).
# File lib/patman.rb, line 279 def edit @edited = true end
Return true if content is modified.
# File lib/patman.rb, line 284 def edited? @edited end
Execute block, retain current position, and return block value.
# File lib/patman.rb, line 289 def excursion( &blk ) line = @line ret = instance_eval( &blk ) @line = line ret end
Return {Patman} file name.
# File lib/patman.rb, line 274 def filename @file end
Find Regexp or literal string forwards or backwards. Return true on success.
# File lib/patman.rb, line 252 def find( re_or_str, forward = true ) begin @line = search_with_exception( re_or_str, forward ) true rescue false end end
Jump to first line.
# File lib/patman.rb, line 111 def firstline @line = 0 self end
Get current line or lines by count.
# File lib/patman.rb, line 146 def get( count = 1 ) if count == 1 @lines[ @line ] else @lines[ @line .. (@line+count-1) ] end end
Get lines starting from start by count.
# File lib/patman.rb, line 354 def get_for( start, count ) @lines[ (start-1) ... (start-1+count) ] end
Get lines between start and stop positions inclusive.
# File lib/patman.rb, line 349 def get_range( start, stop ) @lines[ (start-1) .. (stop-1) ] end
Insert line or lines (Array) to current position.
# File lib/patman.rb, line 194 def insert( text = nil ) @edited = true if text.kind_of? Array line = @line step( -1 ) text.each do |txt| append( txt ) end @line = line else @lines.insert( @line, text ) end self end
Insert file to current position.
# File lib/patman.rb, line 233 def insertfile( file ) @edited = true step( -1 ) read_clean( file ).each do |line| append line end self end
Jump to last line.
# File lib/patman.rb, line 117 def lastline @line = @lines.length-1 self end
Return line count of {Patman} content.
# File lib/patman.rb, line 269 def length @lines.length end
Return or set line.
# File lib/patman.rb, line 95 def line( arg = nil ) if arg @line = (arg-1) self else @line+1 end end
Get or set all {Patman} content.
# File lib/patman.rb, line 131 def lines( arg = nil ) if arg @edited = true @lines = arg else @lines end end
Mark (store) current position to default or to named mark.
# File lib/patman.rb, line 297 def mark( tag = nil ) if tag @marks[ tag ] = @line+1 self else @mark = @line+1 self end end
View line content around current position (by count).
# File lib/patman.rb, line 359 def peek( count = 0 ) view_range( @line-count, @line+count+1 ) nil end
View line content with line numbers around current position (by count).
# File lib/patman.rb, line 366 def peek_ln( count = 0 ) view_range( @line-count, @line+count+1, true ) nil end
Read file in.
# File lib/patman.rb, line 56 def read( file = @file ) if File.exist?( file ) @lines = read_clean( file ) else raise PatmanFileError end end
Get current line or any line.
# File lib/patman.rb, line 155 def ref( line = nil ) if line @lines[ line-1 ] else @lines[ @line ] end end
Search Regexp or literal string forwards or backwards. Fail with expection (PatmanSearchError
) if not found.
# File lib/patman.rb, line 263 def search( re_or_str, forward = true ) @line = search_with_exception( re_or_str, forward ) self end
Set current line.
# File lib/patman.rb, line 164 def set( text ) @edited = true @lines[ @line ] = text self end
Step forward or backward current position.
# File lib/patman.rb, line 105 def step( dir = 1 ) @line = @line + dir self end
Substitution in current line.
# File lib/patman.rb, line 171 def sub( from, to ) @edited = true @lines[ @line ] = @lines[ @line ].sub( from, to ) self end
Unmark (restore) current position from default or from named mark.
# File lib/patman.rb, line 309 def unmark( tag = nil ) if tag && @marks[ tag ] @line = @marks[ tag ]-1 self elsif @mark @line = @mark-1 @mark = nil self else self end end
Update current line content (i.e. get&set) with the return value of the given block. Hence last stmt should include the new line content.
@example
r.update do |c| c.sub!( /foo/, 'bar' ) c end
# File lib/patman.rb, line 187 def update( &blk ) @edited = true set( yield( get ) ) self end
View line content.
-
no args: view all
-
one arg: view from current onwards by count
-
two args: view given range
# File lib/patman.rb, line 376 def view( arg1 = nil, arg2 = nil ) if !arg1 && !arg2 view_range( 0, length ) elsif arg1 && !arg2 view_range( @line, @line+arg1 ) elsif arg1 && arg2 view_range( arg1-1, arg1-1+arg2 ) end nil end
View line content with line numbers.
-
no args: view all
-
one arg: view from current onwards by count
-
two args: view given range
# File lib/patman.rb, line 392 def view_ln( arg1 = nil, arg2 = nil ) if !arg1 && !arg2 view_range( 0, length, true ) elsif arg1 && !arg2 view_range( @line, @line+arg1, true ) elsif arg1 && arg2 view_range( arg1-1, arg1-1+arg2, true ) end nil end
Write {Patman} content to disk.
# File lib/patman.rb, line 65 def write( file = @file ) return unless @edited file_dir = File.dirname( file ) unless File.exist?( file_dir ) require 'fileutils' FileUtils.mkdir_p( file_dir ) end fh = File.open( file, 'w' ) @lines.each do |line| if line fh.puts line else fh.puts "" end end fh.close @edited = false self end