2018/07/28
ソースと結果を直しました。
@set0gut1 さんの寄り目を利用した「目diff」および「立体インデント」の考案からインスパイアされた記事です。
Python3 で立体インデント化したソースコードを出力できるようにしました。
ソース
いろいろツッコミどころのあるコードですが、大目に見てやってください…
ソースコードはここにもあげています。
make3Dindent.py
#!/usr/bin/env python3
import sys
import os
start = '{' # ネストの起点
end = '}' # ネストの終点
width = 20 # 改行幅
def make3Dindent(stream, reverse=False):
depth = 0 # いまの浮かび具合(右側のテキストに適用)
depthList = [0] # 行ごとの浮かび具合の管理
leftLines = []
rightLines = []
for line in stream:
charcount = 0
left = ''
right = ''
for c in line:
charcount += 1
if(c == start):
# 浮かび具合を上げる
depth += 1
left += c
right += ' ' + c
elif(c == end):
# 浮かび具合を下げる
depth -= 1
left += c + ' '
right += c
elif c == "\n": # 改行処理
pad = (width - charcount) * ' '
leftLines.append(left + pad)
rightLines.append(right + pad)
depthList.append(depth)
left = ''
right = ''
charcount = 0
continue
else:
left += c
right += c
if charcount >= width:
leftLines.append(left)
rightLines.append(right)
depthList.append(depth)
left = ''
right = ''
charcount = 0
if c != "\n" and charcount > 0:
pad = (width - charcount) * ' '
leftLines.append(left + pad)
rightLines.append(right + pad)
depthList.append(depth)
depthList.pop()
maxDepth = max(depthList)
maxLength = max([len(line) for line in leftLines])
retRight = []
retLeft = []
baseWidth = maxDepth + maxLength
for (l, r, d) in zip(leftLines, rightLines, depthList):
retLeft.append((' ' * (maxDepth - d)) + l + (' ' * (baseWidth - (len(l) + (maxDepth - d)))))
retRight.append((' ' * d) + r + (' ' * (baseWidth - (len(r) + d))))
# 焦点補助のドット
pad = ' ' * int(baseWidth / 2)
dotLine = pad + '●' + pad
retLeft.append(dotLine)
retRight.append(dotLine)
if reverse:
# 沈む
return (retRight, retLeft)
else:
# 浮かぶ
return (retLeft, retRight)
# 出力用
def printLeftRight(left, right):
for (l, r) in zip(left, right):
print (l + ' ' + r)
if __name__ == '__main__':
if len(sys.argv) == 1:
(left, right) = make3Dindent(sys.stdin)
printLeftRight(left, right)
else:
input_file = sys.argv[1]
if not os.path.isfile(input_file):
print(input_file + ': not found')
sys.exit(1)
f = open(input_file)
(left, right) = make3Dindent(f)
f.close()
printLeftRight(left, right)
実行
$ ./make3Dindent.py input.js
# 標準入力からも可能
$ ./make3Dindent.py < input.js
結果
for(var i=1;i<=100;i for(var i=1;i<=100;i
++){if(i%3===0){if(i ++) {if(i%3===0) {if(i
%5===0){console.log( %5===0) {console.log(
"FizzBuzz")} else{con "FizzBuzz")}else {con
sole.log("Fizz")} } el sole.log("Fizz")}}el
se if(i%5===0){conso se if(i%5===0) {conso
le.log("Buzz")} else{ le.log("Buzz")}else {
console.log(i)} } console.log(i)}}
● ●
問題
改行位置をwidth
で指定しているので、単語の途中でも改行されてしまう。
所感
動作確認で目がいたい…
printLeftRight
ってなんだよ