Skip to content

Instantly share code, notes, and snippets.

@ncaq
Last active August 1, 2023 12:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ncaq/71f2b262462b904795c10b75a259114f to your computer and use it in GitHub Desktop.
Save ncaq/71f2b262462b904795c10b75a259114f to your computer and use it in GitHub Desktop.
文字列から文字列幅のために行われた改行を削除します。ただし、本当に意味的に改行したい場合が推定されれば改行をなるべく残します。
import sys
from collections.abc import Iterator
def format_line_endings(line: str) -> str:
"""
一行の文字列を受け取り、文字列の種類によって行末の書式を決定します。
文字列が空行であるか、行自体に意味がありそうなことを示唆している場合は、行末に改行を追加します。
それ以外の場合は、文字列をそのまま返します。
"""
# 意味的な空行を処理します。
if line.strip() == "":
return line + "\n"
# 前段階で空白文字列は引っかかるので安全に添字アクセスが出来ます。
# TODO: Markdownのリスト記号などの限られた記号とかのみ先頭もチェックします。
if not line[-1].isalnum():
return line + "\n"
else:
# それ以外の行(主に英数字で始まり、英数字で終わる行)はそのまま返します。
return line
def join_by_direct_or_space(lines: list[str] | Iterator[str]) -> str:
"""
文字列のリストを、
前回の要素が改行で終わる場合などのスペースを入れるべきではない場面は、
末尾のスペース無しで繋げます。
そうでない場合、
スペースを挟んで繋げます。
"""
target = []
last_line = None
for line in lines:
if last_line is None or last_line.endswith("\n") or line.strip() == "":
target += line
else:
target += " " + line
last_line = line
return "".join(target)
def remove_wrapping_newline(source: str) -> str:
"""
与えられた文字列から、行の折り返しのために挿入された改行を削除します。
ただし、行の内容から、その行が意味的にも改行された可能性が高い場合は、改行を保持します。
"""
return join_by_direct_or_space(map(format_line_endings, source.split("\n")))
def remove_wrapping_newline_interact() -> None:
"""
標準入力から文字列を読み取り、その文字列から行の折り返しのための改行を削除します。
その結果を標準出力に出力します。
"""
sys.stdout.write(remove_wrapping_newline(sys.stdin.read()))
if __name__ == "__main__":
remove_wrapping_newline_interact()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment