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

marks[RW]

Public Class Methods

edit( file, &blk ) click to toggle source

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
new( file ) click to toggle source

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
read( file ) click to toggle source

Create editing session with file.

# File lib/patman.rb, line 19
def Patman.read( file )
    p = Patman.new( file )
    p.read
    p
end
version() click to toggle source
# File lib/version.rb, line 3
def Patman.version
    Patman::VERSION
end

Public Instance Methods

[]( range ) click to toggle source

Reference {Patman} content by range.

# File lib/patman.rb, line 141
def []( range )
    @lines[ range ]
end
append( text = nil ) click to toggle source

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
blockline() click to toggle source

Jump to line after block.

# File lib/patman.rb, line 123
def blockline
    if @blockline
        @line = @blockline
    end
    self
end
clear() click to toggle source

Clear {Patman} content and reset current line.

# File lib/patman.rb, line 243
def clear
    @edited = true
    @lines = []
    @line = 0
    self
end
copy( file ) click to toggle source

Copy {Patman} content to file.

# File lib/patman.rb, line 89
def copy( file )
    write( file )
    self
end
delete( count = 1 ) click to toggle source

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
do_all( &blk ) click to toggle source

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
do_for( start, count ) { |self| ... } click to toggle source

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
do_range( start, stop, &blk ) click to toggle source

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
edit() click to toggle source

Mark content modified (explicit).

# File lib/patman.rb, line 279
def edit
    @edited = true
end
edited?() click to toggle source

Return true if content is modified.

# File lib/patman.rb, line 284
def edited?
    @edited
end
excursion( &blk ) click to toggle source

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
filename() click to toggle source

Return {Patman} file name.

# File lib/patman.rb, line 274
def filename
    @file
end
find( re_or_str, forward = true ) click to toggle source

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
firstline() click to toggle source

Jump to first line.

# File lib/patman.rb, line 111
def firstline
    @line = 0
    self
end
get( count = 1 ) click to toggle source

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_for( start, count ) click to toggle source

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_range( start, stop ) click to toggle source

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( text = nil ) click to toggle source

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
insertfile( file ) click to toggle source

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
lastline() click to toggle source

Jump to last line.

# File lib/patman.rb, line 117
def lastline
    @line = @lines.length-1
    self
end
length() click to toggle source

Return line count of {Patman} content.

# File lib/patman.rb, line 269
def length
    @lines.length
end
line( arg = nil ) click to toggle source

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
lines( arg = nil ) click to toggle source

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( tag = nil ) click to toggle source

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
peek( count = 0 ) click to toggle source

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
peek_ln( count = 0 ) click to toggle source

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 = @file ) click to toggle source

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
ref( line = nil ) click to toggle source

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
set( text ) click to toggle source

Set current line.

# File lib/patman.rb, line 164
def set( text )
    @edited = true
    @lines[ @line ] = text
    self
end
step( dir = 1 ) click to toggle source

Step forward or backward current position.

# File lib/patman.rb, line 105
def step( dir = 1 )
    @line = @line + dir
    self
end
sub( from, to ) click to toggle source

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( tag = nil ) click to toggle source

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( ) { |get| ... } click to toggle source

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( arg1 = nil, arg2 = nil ) click to toggle source

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_ln( arg1 = nil, arg2 = nil ) click to toggle source

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( file = @file ) click to toggle source

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