printsection 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 printtitle contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: printsection
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: 출력 구간을 나누는 위아래 빈 줄 + 가운데 정렬 구분선 (한글 폭 자동 보정)
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: center,console,divider,korean,print,section
|
|
8
|
+
Classifier: Natural Language :: Korean
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
# printsection
|
|
15
|
+
|
|
16
|
+
`print("\n", "실습 결과".center(50, "-"), end="\n\n")` 를 한 줄로.
|
|
17
|
+
출력 결과를 구간별로 나눠 보기 좋게 구분해 줍니다.
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install printsection
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
from printsection import section
|
|
25
|
+
|
|
26
|
+
section("실습 1")
|
|
27
|
+
print("...")
|
|
28
|
+
section("실습 2")
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
----------------------실습 1----------------------
|
|
34
|
+
|
|
35
|
+
...
|
|
36
|
+
|
|
37
|
+
----------------------실습 2----------------------
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
위아래 빈 줄과 가운데 정렬이 기본입니다. 한글처럼 화면에서 2칸을 차지하는 글자도 폭을 계산해서 실제 화면 기준으로 가운데에 맞춥니다.
|
|
42
|
+
|
|
43
|
+
## 옵션
|
|
44
|
+
|
|
45
|
+
호출할 때 원하는 값만 바꾸면 됩니다.
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
section("실습 결과", width=60, fillchar="=")
|
|
49
|
+
section("왼쪽 정렬", align="left") # "center" / "left" / "right"
|
|
50
|
+
section("빈 줄 조절", top=2, bottom=0)
|
|
51
|
+
section("str.center처럼", wide=False) # 글자 수 기준으로 계산
|
|
52
|
+
section() # 글자 없이 구분선만
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
| 옵션 | 기본값 | 설명 |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| `width` | `50` | 전체 너비 |
|
|
58
|
+
| `fillchar` | `"-"` | 채움 문자 (한 글자) |
|
|
59
|
+
| `align` | `"center"` | `"center"`, `"left"`, `"right"` |
|
|
60
|
+
| `top` | `1` | 위쪽 빈 줄 수 |
|
|
61
|
+
| `bottom` | `1` | 아래쪽 빈 줄 수 |
|
|
62
|
+
| `wide` | `True` | 한글 등 전각 문자를 2칸으로 계산 |
|
|
63
|
+
| `file` | `sys.stdout` | 출력 대상 |
|
|
64
|
+
|
|
65
|
+
## 기본값 한 번에 바꾸기
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from printsection import section, set_defaults, reset_defaults
|
|
69
|
+
|
|
70
|
+
set_defaults(width=70, fillchar="*")
|
|
71
|
+
section("1번 문제")
|
|
72
|
+
section("2번 문제")
|
|
73
|
+
reset_defaults()
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## 문자열만 받기
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from printsection import format_section
|
|
80
|
+
|
|
81
|
+
s = format_section("실습 결과") # 출력하지 않고 문자열 반환
|
|
82
|
+
```
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# printsection
|
|
2
|
+
|
|
3
|
+
`print("\n", "실습 결과".center(50, "-"), end="\n\n")` 를 한 줄로.
|
|
4
|
+
출력 결과를 구간별로 나눠 보기 좋게 구분해 줍니다.
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
pip install printsection
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
from printsection import section
|
|
12
|
+
|
|
13
|
+
section("실습 1")
|
|
14
|
+
print("...")
|
|
15
|
+
section("실습 2")
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
----------------------실습 1----------------------
|
|
21
|
+
|
|
22
|
+
...
|
|
23
|
+
|
|
24
|
+
----------------------실습 2----------------------
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
위아래 빈 줄과 가운데 정렬이 기본입니다. 한글처럼 화면에서 2칸을 차지하는 글자도 폭을 계산해서 실제 화면 기준으로 가운데에 맞춥니다.
|
|
29
|
+
|
|
30
|
+
## 옵션
|
|
31
|
+
|
|
32
|
+
호출할 때 원하는 값만 바꾸면 됩니다.
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
section("실습 결과", width=60, fillchar="=")
|
|
36
|
+
section("왼쪽 정렬", align="left") # "center" / "left" / "right"
|
|
37
|
+
section("빈 줄 조절", top=2, bottom=0)
|
|
38
|
+
section("str.center처럼", wide=False) # 글자 수 기준으로 계산
|
|
39
|
+
section() # 글자 없이 구분선만
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
| 옵션 | 기본값 | 설명 |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| `width` | `50` | 전체 너비 |
|
|
45
|
+
| `fillchar` | `"-"` | 채움 문자 (한 글자) |
|
|
46
|
+
| `align` | `"center"` | `"center"`, `"left"`, `"right"` |
|
|
47
|
+
| `top` | `1` | 위쪽 빈 줄 수 |
|
|
48
|
+
| `bottom` | `1` | 아래쪽 빈 줄 수 |
|
|
49
|
+
| `wide` | `True` | 한글 등 전각 문자를 2칸으로 계산 |
|
|
50
|
+
| `file` | `sys.stdout` | 출력 대상 |
|
|
51
|
+
|
|
52
|
+
## 기본값 한 번에 바꾸기
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from printsection import section, set_defaults, reset_defaults
|
|
56
|
+
|
|
57
|
+
set_defaults(width=70, fillchar="*")
|
|
58
|
+
section("1번 문제")
|
|
59
|
+
section("2번 문제")
|
|
60
|
+
reset_defaults()
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## 문자열만 받기
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from printsection import format_section
|
|
67
|
+
|
|
68
|
+
s = format_section("실습 결과") # 출력하지 않고 문자열 반환
|
|
69
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "printsection"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "출력 구간을 나누는 위아래 빈 줄 + 가운데 정렬 구분선 (한글 폭 자동 보정)"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
keywords = ["print", "section", "divider", "center", "korean", "console"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Natural Language :: Korean",
|
|
17
|
+
]
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""위아래 빈 줄과 가운데 정렬이 기본으로 들어간 구간 구분 출력 함수.
|
|
2
|
+
|
|
3
|
+
>>> from printsection import section
|
|
4
|
+
>>> section("실습 결과")
|
|
5
|
+
|
|
6
|
+
--------------------실습 결과---------------------
|
|
7
|
+
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import sys
|
|
11
|
+
import unicodedata
|
|
12
|
+
|
|
13
|
+
__all__ = ["section", "format_section", "set_defaults", "reset_defaults"]
|
|
14
|
+
__version__ = "0.1.0"
|
|
15
|
+
|
|
16
|
+
_FACTORY_DEFAULTS = {
|
|
17
|
+
"width": 50,
|
|
18
|
+
"fillchar": "-",
|
|
19
|
+
"align": "center",
|
|
20
|
+
"top": 1,
|
|
21
|
+
"bottom": 1,
|
|
22
|
+
"wide": True,
|
|
23
|
+
}
|
|
24
|
+
_defaults = dict(_FACTORY_DEFAULTS)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _display_width(s):
|
|
28
|
+
"""터미널에서 차지하는 칸 수. 한글/한자 등 전각 문자는 2칸으로 센다."""
|
|
29
|
+
return sum(2 if unicodedata.east_asian_width(ch) in ("W", "F") else 1 for ch in s)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def format_section(text="", **options):
|
|
33
|
+
"""출력하지 않고 구분 문자열만 만들어 반환한다 (위아래 빈 줄 포함)."""
|
|
34
|
+
unknown = set(options) - set(_FACTORY_DEFAULTS)
|
|
35
|
+
if unknown:
|
|
36
|
+
raise TypeError(f"알 수 없는 옵션: {', '.join(sorted(unknown))}")
|
|
37
|
+
opt = {**_defaults, **options}
|
|
38
|
+
|
|
39
|
+
text = str(text)
|
|
40
|
+
fillchar = opt["fillchar"]
|
|
41
|
+
if len(fillchar) != 1:
|
|
42
|
+
raise ValueError("fillchar는 한 글자여야 합니다.")
|
|
43
|
+
|
|
44
|
+
measure = _display_width if opt["wide"] else len
|
|
45
|
+
fill_w = measure(fillchar)
|
|
46
|
+
pad = max(opt["width"] - measure(text), 0) // fill_w
|
|
47
|
+
|
|
48
|
+
align = opt["align"]
|
|
49
|
+
if align == "center":
|
|
50
|
+
left = pad // 2
|
|
51
|
+
elif align == "left":
|
|
52
|
+
left = 0
|
|
53
|
+
elif align == "right":
|
|
54
|
+
left = pad
|
|
55
|
+
else:
|
|
56
|
+
raise ValueError("align은 'center', 'left', 'right' 중 하나여야 합니다.")
|
|
57
|
+
line = fillchar * left + text + fillchar * (pad - left)
|
|
58
|
+
|
|
59
|
+
return "\n" * opt["top"] + line + "\n" * opt["bottom"]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def section(text="", *, file=None, flush=False, **options):
|
|
63
|
+
"""구간 이름을 위아래 빈 줄과 함께 가운데 정렬해서 출력한다.
|
|
64
|
+
|
|
65
|
+
옵션 (생략하면 set_defaults로 정한 값, 처음엔 아래 기본값):
|
|
66
|
+
width=50 전체 너비
|
|
67
|
+
fillchar="-" 채움 문자 (한 글자)
|
|
68
|
+
align="center" "center" / "left" / "right"
|
|
69
|
+
top=1 위쪽 빈 줄 수
|
|
70
|
+
bottom=1 아래쪽 빈 줄 수
|
|
71
|
+
wide=True 한글 등 전각 문자를 2칸으로 계산해 실제 화면에서 정확히 정렬
|
|
72
|
+
"""
|
|
73
|
+
print(format_section(text, **options), file=file or sys.stdout, flush=flush)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def set_defaults(**options):
|
|
77
|
+
"""이후 모든 section() 호출의 기본값을 바꾼다. 예: set_defaults(width=60, fillchar="=")"""
|
|
78
|
+
unknown = set(options) - set(_FACTORY_DEFAULTS)
|
|
79
|
+
if unknown:
|
|
80
|
+
raise TypeError(f"알 수 없는 옵션: {', '.join(sorted(unknown))}")
|
|
81
|
+
_defaults.update(options)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def reset_defaults():
|
|
85
|
+
"""set_defaults로 바꾼 기본값을 처음 상태로 되돌린다."""
|
|
86
|
+
_defaults.clear()
|
|
87
|
+
_defaults.update(_FACTORY_DEFAULTS)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from printsection import format_section, reset_defaults, set_defaults
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@pytest.fixture(autouse=True)
|
|
7
|
+
def _reset():
|
|
8
|
+
reset_defaults()
|
|
9
|
+
yield
|
|
10
|
+
reset_defaults()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_default_matches_screen_width():
|
|
14
|
+
s = format_section("실습 결과")
|
|
15
|
+
line = s.strip("\n")
|
|
16
|
+
assert s.startswith("\n") and s.endswith("\n")
|
|
17
|
+
# 한글 4자(8칸) + 공백 1칸 = 9칸, 나머지 41칸을 '-'로 채움
|
|
18
|
+
assert line == "-" * 20 + "실습 결과" + "-" * 21
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_ascii_same_as_str_center_length():
|
|
22
|
+
line = format_section("abc", top=0, bottom=0)
|
|
23
|
+
assert len(line) == 50 and line.strip("-") == "abc"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_options():
|
|
27
|
+
assert format_section("ab", width=6, fillchar="=", top=0, bottom=0) == "==ab=="
|
|
28
|
+
assert format_section("ab", width=6, align="left", top=0, bottom=0) == "ab----"
|
|
29
|
+
assert format_section("ab", width=6, align="right", top=0, bottom=0) == "----ab"
|
|
30
|
+
assert format_section("가", width=4, wide=False, top=0, bottom=0) == "-가--"
|
|
31
|
+
assert format_section("x", width=1, top=2, bottom=3) == "\n\nx\n\n\n"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_set_defaults():
|
|
35
|
+
set_defaults(width=4, fillchar="*", top=0, bottom=0)
|
|
36
|
+
assert format_section("ab") == "*ab*"
|
|
37
|
+
reset_defaults()
|
|
38
|
+
assert len(format_section("ab", top=0, bottom=0)) == 50
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_bad_options():
|
|
42
|
+
with pytest.raises(TypeError):
|
|
43
|
+
format_section("a", colour="red")
|
|
44
|
+
with pytest.raises(ValueError):
|
|
45
|
+
format_section("a", fillchar="--")
|
|
46
|
+
with pytest.raises(ValueError):
|
|
47
|
+
format_section("a", align="middle")
|