开发者

How can I separate pages with Vim?

I have the requirement of separating an ASCII document into pages of max length 58 lines per page.开发者_StackOverflow At the bottom of each page there is a 3 line footer. I'm not aware of any pagination abilities within Vim that would accomplish this.

Is there a good way to do this with Vim? Perhaps highlighting every 58th line or something of the sort.

N.B. I'm seeing answers involving using a separate tool to do this; which I have thought of. What I'm interested in is a Vim solution.

Thanks.


The proper tool you're looking for is very likely a2ps.

a2ps --lines-per-page 58 --footer=footer_text document.txt


It's possible in vim as a script. Put the following in a file and :source it while the file to change is open. The s:footer list are the lines to insert after each run of 58 lines.

let s:footer = ["","Footer",""]
let s:line = 0

while s:line <= line("$") - 58
  let s:line = s:line + 58
  call append(s:line, s:footer)
  let s:line = s:line + len(s:footer)
endwhile


Why is it important to use vim? You could use split and cat more efficiently.

Assuming your original file is called file and you have a file, footer, created that includes your footer text.

$ split -l 58 file file_parts
$ for i in file_parts*; do cat $i footer > $i.footered; done
$ cat file_parts*.footered > file.footered

file.footered would have your original file with the contents of footer inserted at every 58th line.

This is assuming you want it all back in the original file. If you don't, then the resulting file_parts*.footered files would be the already separated pages so you could skip the last step.


The two most effective ways for doing that in Vim are a script (like @Geoff has already suggested) and a substitution command, like

:%s@\%(.*\n\)\{58}@\0---\rfooter\r---\r@

A macro (as suggested in a comment to the question) is the slowest, a script is the fastest. A substitution command is slower than script, but much faster than a macro.

So probably substitution is the best Vim-only solution unless its performance is unacceptable. Only in that case, I think, it is worth writing a script.


You're probably trying to use the wrong tool for this. You could do it much easier programmatically, for example with this simple Perl oneliner:

perl -pe'print "your\nfooter\nhere\n" unless $. % 58' inputfilename > outputfilename


A recursive macro might work. Experiment with the following (position the cursor on the first character of the first line and switch to normal mode):

qqq
qq
57j
:read footer.txt
3j
@q
q

Note that the register to which you record the macro must be cleared (qqq) and that you must not use tab-completion when reading the footer-file (:read footer.txt).

You can then use the macro (normal mode):

@q
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜