QA@IT

Ruby: 長いテキストを折り返しつつmanようにインデントをつけて出力するには?

2376 PV

こんな長いテキストを出力するプログラムで、

$ ruby print_without_indent.rb
Lorem ipsum dolor sit amet, ut ubique iuvaret vocibus eos, ius ex volumus evertitur contentiones, oratio imperdiet mnesarchum eu eam. Duo et ceteros eleifend, mel affert noster te. Epicuri deserunt cu sit. No torquatos tincidunt eam, sumo nulla accommodare ne mea, vix et ornatus apeirian. Has aperiam offendit signiferumque no.

各行の先頭にインデントを出力したい(ブラウザでは再現しにくいので一行目のみ再現)。

$ ruby print_with_indent.rb
    Lorem ipsum dolor sit amet, ut ubique iuvaret vocibus eos, ius ex volumus evertitur contentiones, oratio imperdiet mnesarchum eu eam. Duo et ceteros eleifend, mel affert noster te. Epicuri deserunt cu sit. No torquatos tincidunt eam, sumo nulla accommodare ne mea, vix et ornatus apeirian. Has aperiam offendit signiferumque no.

イメージで言うと、manのフォーマットのような感じです。

回答

cursesを使うと端末サイズを取得できるので、その桁数で折り返すのであれば以下のようなコードになるかと思います。
単語の途中で改行されないようにしていますが、英文のみ対応です。

#-*- coding: utf-8 -*-
require "curses"

# 端末のサイズを取得する
screen = Curses::init_screen
screen_width = screen.maxx
Curses::close_screen
puts screen_width

# 対象文字列とインデント幅
text = "Lorem ipsum dolor sit amet, ut ubique iuvaret vocibus eos, ius ex volumus evertitur contentiones, oratio imperdiet mnesarchum eu eam. Duo et ceteros eleifend, mel affert noster te. Epicuri deserunt cu sit. No torquatos tincidunt eam, sumo nulla accommodare ne mea, vix et ornatus apeirian. Has aperiam offendit signiferumque no."
indent = 4

text_width = screen_width - indent - 1
text.scan(/.{,#{text_width}} /).each do |word|
  puts " " * indent + word
end

出力例(端末横サイズが72の場合)

    Lorem ipsum dolor sit amet, ut ubique iuvaret vocibus eos, ius ex
    volumus evertitur contentiones, oratio imperdiet mnesarchum eu eam.
    Duo et ceteros eleifend, mel affert noster te. Epicuri deserunt cu
    sit. No torquatos tincidunt eam, sumo nulla accommodare ne mea, vix
    et ornatus apeirian. Has aperiam offendit signiferumque

出力例(端末横サイズを50まで縮めてみた)

    Lorem ipsum dolor sit amet, ut ubique iuvaret
    vocibus eos, ius ex volumus evertitur
    contentiones, oratio imperdiet mnesarchum eu
    eam. Duo et ceteros eleifend, mel affert
    noster te. Epicuri deserunt cu sit. No
    torquatos tincidunt eam, sumo nulla
    accommodare ne mea, vix et ornatus apeirian.
    Has aperiam offendit signiferumque
編集 履歴 (1)

指定した文字数で無差別に折り返すなら、単純にこんな感じでどうでしょう?

input = "super long long text."
indent = 4
width = 70
output = ' ' * indent + input.gsub(/.{#{width}}/, "\\0\n" + ' ' * indent)
編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。