txt2ebook 0.1.155__tar.gz → 0.1.156__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.
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/PKG-INFO +18 -18
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/pyproject.toml +12 -5
- txt2ebook-0.1.156/setup.cfg +4 -0
- txt2ebook-0.1.156/src/txt2ebook.egg-info/PKG-INFO +153 -0
- txt2ebook-0.1.156/src/txt2ebook.egg-info/SOURCES.txt +61 -0
- txt2ebook-0.1.156/src/txt2ebook.egg-info/dependency_links.txt +1 -0
- txt2ebook-0.1.156/src/txt2ebook.egg-info/entry_points.txt +3 -0
- txt2ebook-0.1.156/src/txt2ebook.egg-info/requires.txt +13 -0
- txt2ebook-0.1.156/src/txt2ebook.egg-info/top_level.txt +1 -0
- txt2ebook-0.1.156/tests/test_header_number_flag.py +46 -0
- txt2ebook-0.1.156/tests/test_input_file_arg.py +28 -0
- txt2ebook-0.1.156/tests/test_language_option.py +33 -0
- txt2ebook-0.1.156/tests/test_output_file_arg.py +34 -0
- txt2ebook-0.1.156/tests/test_overwrite_flag.py +23 -0
- txt2ebook-0.1.156/tests/test_parser.py +94 -0
- txt2ebook-0.1.156/tests/test_purge_flag.py +49 -0
- txt2ebook-0.1.156/tests/test_quiet_flag.py +24 -0
- txt2ebook-0.1.156/tests/test_sort_volume_and_chapter_flag.py +44 -0
- txt2ebook-0.1.156/tests/test_split_volume_and_chapter_flag.py +51 -0
- txt2ebook-0.1.156/tests/test_test_parsing_flag.py +28 -0
- txt2ebook-0.1.156/tests/test_tokenizer.py +127 -0
- txt2ebook-0.1.156/tests/test_txt2ebook.py +21 -0
- txt2ebook-0.1.156/tests/test_verbose_flag.py +92 -0
- txt2ebook-0.1.156/tests/test_volume_page_flag.py +23 -0
- txt2ebook-0.1.155/src/txt2ebook/formats/templates/epub/clean.css +0 -41
- txt2ebook-0.1.155/src/txt2ebook/formats/templates/epub/condense.css +0 -42
- txt2ebook-0.1.155/src/txt2ebook/formats/templates/epub/noindent.css +0 -42
- txt2ebook-0.1.155/src/txt2ebook/locales/en/LC_MESSAGES/txt2ebook.mo +0 -0
- txt2ebook-0.1.155/src/txt2ebook/locales/en/LC_MESSAGES/txt2ebook.po +0 -31
- txt2ebook-0.1.155/src/txt2ebook/locales/txt2ebook.pot +0 -31
- txt2ebook-0.1.155/src/txt2ebook/locales/zh-cn/LC_MESSAGES/txt2ebook.mo +0 -0
- txt2ebook-0.1.155/src/txt2ebook/locales/zh-cn/LC_MESSAGES/txt2ebook.po +0 -31
- txt2ebook-0.1.155/src/txt2ebook/locales/zh-tw/LC_MESSAGES/txt2ebook.mo +0 -0
- txt2ebook-0.1.155/src/txt2ebook/locales/zh-tw/LC_MESSAGES/txt2ebook.po +0 -31
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/LICENSE.md +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/README.md +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/__init__.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/__main__.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/cli.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/exceptions.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/formats/__init__.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/formats/base.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/formats/epub.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/formats/gmi.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/formats/md.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/formats/pdf.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/formats/templates/__init__.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/formats/templates/epub/__init__.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/formats/tex.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/formats/txt.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/formats/typ.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/helpers/__init__.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/languages/__init__.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/languages/en.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/languages/zh_cn.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/languages/zh_tw.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/models/__init__.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/models/book.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/models/chapter.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/models/volume.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/parser.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/subcommands/__init__.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/subcommands/env.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/subcommands/epub.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/subcommands/gmi.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/subcommands/massage.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/subcommands/md.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/subcommands/parse.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/subcommands/pdf.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/subcommands/tex.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/subcommands/typ.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/tokenizer.py +0 -0
- {txt2ebook-0.1.155 → txt2ebook-0.1.156}/src/txt2ebook/zh_utils.py +0 -0
@@ -1,14 +1,14 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: txt2ebook
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.156
|
4
4
|
Summary: CLI tool to convert txt file to ebook format
|
5
|
-
Keywords: cjk,ebook,epub,gmi,latex,md,pdf,txt,typst
|
6
5
|
Author-email: Kian-Meng Ang <kianmeng@cpan.org>
|
7
|
-
|
8
|
-
|
6
|
+
License-Expression: AGPL-3.0-or-later
|
7
|
+
Project-URL: Homepage, https://github.com/kianmeng/txt2ebook
|
8
|
+
Project-URL: Repository, https://github.com/kianmeng/txt2ebook
|
9
|
+
Keywords: cjk,ebook,epub,gmi,latex,md,pdf,txt,typst
|
9
10
|
Classifier: Development Status :: 4 - Beta
|
10
11
|
Classifier: Environment :: Console
|
11
|
-
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
|
12
12
|
Classifier: Natural Language :: Chinese (Simplified)
|
13
13
|
Classifier: Natural Language :: Chinese (Traditional)
|
14
14
|
Classifier: Programming Language :: Python
|
@@ -23,22 +23,23 @@ Classifier: Topic :: Text Processing :: Filters
|
|
23
23
|
Classifier: Topic :: Text Processing :: General
|
24
24
|
Classifier: Topic :: Text Processing :: Markup :: HTML
|
25
25
|
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
26
|
+
Requires-Python: ~=3.9
|
27
|
+
Description-Content-Type: text/markdown
|
26
28
|
License-File: LICENSE.md
|
27
29
|
Requires-Dist: CJKwrap~=2.2
|
28
|
-
Requires-Dist: EbookLib
|
29
|
-
Requires-Dist: bs4
|
30
|
-
Requires-Dist: importlib-resources
|
31
|
-
Requires-Dist: jieba
|
32
|
-
Requires-Dist: langdetect
|
33
|
-
Requires-Dist: lxml
|
34
|
-
Requires-Dist: pylatex
|
30
|
+
Requires-Dist: EbookLib<0.18,>=0.17.1
|
31
|
+
Requires-Dist: bs4<0.0.2,>=0.0.1
|
32
|
+
Requires-Dist: importlib-resources<7,>=6.1.1
|
33
|
+
Requires-Dist: jieba<0.43,>=0.42.1
|
34
|
+
Requires-Dist: langdetect<2,>=1.0.9
|
35
|
+
Requires-Dist: lxml<6,>=5.2.2
|
36
|
+
Requires-Dist: pylatex<2,>=1.4.2
|
35
37
|
Requires-Dist: pypandoc~=1.11
|
36
|
-
Requires-Dist: regex
|
37
|
-
Requires-Dist: reportlab
|
38
|
-
Requires-Dist: typing-extensions
|
38
|
+
Requires-Dist: regex<2022,>=2021.11.10
|
39
|
+
Requires-Dist: reportlab<5,>=4.0.0
|
40
|
+
Requires-Dist: typing-extensions<5,>=4.5.0
|
39
41
|
Requires-Dist: typst>=0.13.0
|
40
|
-
|
41
|
-
Project-URL: Repository, https://github.com/kianmeng/txt2ebook
|
42
|
+
Dynamic: license-file
|
42
43
|
|
43
44
|
# txt2ebook
|
44
45
|
|
@@ -150,4 +151,3 @@ The fish logo used in the documentation generated by Sphinx is a public domain
|
|
150
151
|
drawing of Troschel's parrotfish (Chlorurus troschelii Var. A.) from
|
151
152
|
<https://commons.wikimedia.org/entity/M18506436>.
|
152
153
|
18506436>.
|
153
|
-
|
@@ -1,11 +1,12 @@
|
|
1
1
|
[project]
|
2
2
|
name = "txt2ebook"
|
3
|
-
version = "0.1.
|
3
|
+
version = "0.1.156"
|
4
4
|
description = "CLI tool to convert txt file to ebook format"
|
5
5
|
authors = [{ name = "Kian-Meng Ang", email = "kianmeng@cpan.org" }]
|
6
6
|
requires-python = "~=3.9"
|
7
7
|
readme = "README.md"
|
8
|
-
license =
|
8
|
+
license = "AGPL-3.0-or-later"
|
9
|
+
license-files = ["LICENSE.md"]
|
9
10
|
keywords = [
|
10
11
|
"cjk",
|
11
12
|
"ebook",
|
@@ -20,7 +21,6 @@ keywords = [
|
|
20
21
|
classifiers = [
|
21
22
|
"Development Status :: 4 - Beta",
|
22
23
|
"Environment :: Console",
|
23
|
-
"License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)",
|
24
24
|
"Natural Language :: Chinese (Simplified)",
|
25
25
|
"Natural Language :: Chinese (Traditional)",
|
26
26
|
"Programming Language :: Python",
|
@@ -83,5 +83,12 @@ dev = [
|
|
83
83
|
]
|
84
84
|
|
85
85
|
[build-system]
|
86
|
-
requires = ["
|
87
|
-
build-backend = "
|
86
|
+
requires = ["setuptools>=61.0"]
|
87
|
+
build-backend = "setuptools.build_meta"
|
88
|
+
|
89
|
+
# verify through: uv run ruff check --show-settings
|
90
|
+
[tool.ruff]
|
91
|
+
line-length = 79
|
92
|
+
|
93
|
+
[tool.setuptools.packages.find]
|
94
|
+
where = ["src"]
|
@@ -0,0 +1,153 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: txt2ebook
|
3
|
+
Version: 0.1.156
|
4
|
+
Summary: CLI tool to convert txt file to ebook format
|
5
|
+
Author-email: Kian-Meng Ang <kianmeng@cpan.org>
|
6
|
+
License-Expression: AGPL-3.0-or-later
|
7
|
+
Project-URL: Homepage, https://github.com/kianmeng/txt2ebook
|
8
|
+
Project-URL: Repository, https://github.com/kianmeng/txt2ebook
|
9
|
+
Keywords: cjk,ebook,epub,gmi,latex,md,pdf,txt,typst
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
11
|
+
Classifier: Environment :: Console
|
12
|
+
Classifier: Natural Language :: Chinese (Simplified)
|
13
|
+
Classifier: Natural Language :: Chinese (Traditional)
|
14
|
+
Classifier: Programming Language :: Python
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
21
|
+
Classifier: Topic :: Text Processing
|
22
|
+
Classifier: Topic :: Text Processing :: Filters
|
23
|
+
Classifier: Topic :: Text Processing :: General
|
24
|
+
Classifier: Topic :: Text Processing :: Markup :: HTML
|
25
|
+
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
26
|
+
Requires-Python: ~=3.9
|
27
|
+
Description-Content-Type: text/markdown
|
28
|
+
License-File: LICENSE.md
|
29
|
+
Requires-Dist: CJKwrap~=2.2
|
30
|
+
Requires-Dist: EbookLib<0.18,>=0.17.1
|
31
|
+
Requires-Dist: bs4<0.0.2,>=0.0.1
|
32
|
+
Requires-Dist: importlib-resources<7,>=6.1.1
|
33
|
+
Requires-Dist: jieba<0.43,>=0.42.1
|
34
|
+
Requires-Dist: langdetect<2,>=1.0.9
|
35
|
+
Requires-Dist: lxml<6,>=5.2.2
|
36
|
+
Requires-Dist: pylatex<2,>=1.4.2
|
37
|
+
Requires-Dist: pypandoc~=1.11
|
38
|
+
Requires-Dist: regex<2022,>=2021.11.10
|
39
|
+
Requires-Dist: reportlab<5,>=4.0.0
|
40
|
+
Requires-Dist: typing-extensions<5,>=4.5.0
|
41
|
+
Requires-Dist: typst>=0.13.0
|
42
|
+
Dynamic: license-file
|
43
|
+
|
44
|
+
# txt2ebook
|
45
|
+
|
46
|
+
A console tool to convert txt file to different ebook formats.
|
47
|
+
|
48
|
+
## Installation
|
49
|
+
|
50
|
+
Stable version From PyPI:
|
51
|
+
|
52
|
+
```console
|
53
|
+
uv tool install txt2ebook
|
54
|
+
```
|
55
|
+
|
56
|
+
Upgrade to latest stable version:
|
57
|
+
|
58
|
+
```console
|
59
|
+
uv tool upgrade txt2ebook
|
60
|
+
```
|
61
|
+
|
62
|
+
## Usage
|
63
|
+
|
64
|
+
Showing help message of command-line options:
|
65
|
+
|
66
|
+
```console
|
67
|
+
txt2ebook --help
|
68
|
+
```
|
69
|
+
|
70
|
+
<!--help !-->
|
71
|
+
|
72
|
+
```console
|
73
|
+
usage: txt2ebook [-of OUTPUT_FOLDER] [-p] [-l LANGUAGE] [-rw] [-q] [-v] [-d]
|
74
|
+
[-h] [-V]
|
75
|
+
{env,epub,gmi,massage,md,parse,pdf,tex,typ} ...
|
76
|
+
|
77
|
+
txt2ebook/tte is a cli tool to convert txt file to ebook format.
|
78
|
+
|
79
|
+
website: https://github.com/kianmeng/txt2ebook
|
80
|
+
changelog: https://github.com/kianmeng/txt2ebook/blob/master/CHANGELOG.md
|
81
|
+
issues: https://github.com/kianmeng/txt2ebook/issues
|
82
|
+
|
83
|
+
positional arguments:
|
84
|
+
{env,epub,gmi,massage,md,parse,pdf,tex,typ}
|
85
|
+
sub-command help
|
86
|
+
env
|
87
|
+
print environment information for bug reporting
|
88
|
+
epub
|
89
|
+
generate ebook in EPUB format
|
90
|
+
gmi
|
91
|
+
generate ebook in Gemtext format
|
92
|
+
massage
|
93
|
+
massage the source txt file
|
94
|
+
md
|
95
|
+
generate ebook in Markdown format
|
96
|
+
parse
|
97
|
+
parse and validate the txt file
|
98
|
+
pdf
|
99
|
+
generate ebook in Markdown format
|
100
|
+
tex
|
101
|
+
generate ebook in TeX/PDF format
|
102
|
+
typ
|
103
|
+
generate ebook in Typst format
|
104
|
+
|
105
|
+
options:
|
106
|
+
-of, --output-folder OUTPUT_FOLDER
|
107
|
+
set default output folder (default: 'output')
|
108
|
+
-p, --purge
|
109
|
+
remove converted ebooks specified by --output-folder option (default: 'False')
|
110
|
+
-l, --language LANGUAGE
|
111
|
+
language of the ebook (default: 'None')
|
112
|
+
-rw, --raise-on-warning
|
113
|
+
raise exception and stop parsing upon warning
|
114
|
+
-q, --quiet
|
115
|
+
suppress all logging
|
116
|
+
-v, --verbose
|
117
|
+
show verbosity of debugging log, use -vv, -vvv for more details
|
118
|
+
-d, --debug
|
119
|
+
show debugging log and stacktrace
|
120
|
+
-h, --help
|
121
|
+
show this help message and exit
|
122
|
+
-V, --version
|
123
|
+
show program's version number and exit
|
124
|
+
```
|
125
|
+
|
126
|
+
<!--help !-->
|
127
|
+
|
128
|
+
Convert a txt file into epub:
|
129
|
+
|
130
|
+
```console
|
131
|
+
txt2ebook ebook.txt
|
132
|
+
```
|
133
|
+
|
134
|
+
## Copyright and License
|
135
|
+
|
136
|
+
Copyright (c) 2021,2022,2023,2024,2025 Kian-Meng Ang
|
137
|
+
|
138
|
+
This program is free software: you can redistribute it and/or modify it under
|
139
|
+
the terms of the GNU Affero General Public License as published by the Free
|
140
|
+
Software Foundation, either version 3 of the License, or (at your option) any
|
141
|
+
later version.
|
142
|
+
|
143
|
+
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
144
|
+
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
145
|
+
PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
146
|
+
|
147
|
+
You should have received a copy of the GNU Affero General Public License along
|
148
|
+
with this program. If not, see <https://www.gnu.org/licenses/>.
|
149
|
+
|
150
|
+
The fish logo used in the documentation generated by Sphinx is a public domain
|
151
|
+
drawing of Troschel's parrotfish (Chlorurus troschelii Var. A.) from
|
152
|
+
<https://commons.wikimedia.org/entity/M18506436>.
|
153
|
+
18506436>.
|
@@ -0,0 +1,61 @@
|
|
1
|
+
LICENSE.md
|
2
|
+
README.md
|
3
|
+
pyproject.toml
|
4
|
+
src/txt2ebook/__init__.py
|
5
|
+
src/txt2ebook/__main__.py
|
6
|
+
src/txt2ebook/cli.py
|
7
|
+
src/txt2ebook/exceptions.py
|
8
|
+
src/txt2ebook/parser.py
|
9
|
+
src/txt2ebook/tokenizer.py
|
10
|
+
src/txt2ebook/zh_utils.py
|
11
|
+
src/txt2ebook.egg-info/PKG-INFO
|
12
|
+
src/txt2ebook.egg-info/SOURCES.txt
|
13
|
+
src/txt2ebook.egg-info/dependency_links.txt
|
14
|
+
src/txt2ebook.egg-info/entry_points.txt
|
15
|
+
src/txt2ebook.egg-info/requires.txt
|
16
|
+
src/txt2ebook.egg-info/top_level.txt
|
17
|
+
src/txt2ebook/formats/__init__.py
|
18
|
+
src/txt2ebook/formats/base.py
|
19
|
+
src/txt2ebook/formats/epub.py
|
20
|
+
src/txt2ebook/formats/gmi.py
|
21
|
+
src/txt2ebook/formats/md.py
|
22
|
+
src/txt2ebook/formats/pdf.py
|
23
|
+
src/txt2ebook/formats/tex.py
|
24
|
+
src/txt2ebook/formats/txt.py
|
25
|
+
src/txt2ebook/formats/typ.py
|
26
|
+
src/txt2ebook/formats/templates/__init__.py
|
27
|
+
src/txt2ebook/formats/templates/epub/__init__.py
|
28
|
+
src/txt2ebook/helpers/__init__.py
|
29
|
+
src/txt2ebook/languages/__init__.py
|
30
|
+
src/txt2ebook/languages/en.py
|
31
|
+
src/txt2ebook/languages/zh_cn.py
|
32
|
+
src/txt2ebook/languages/zh_tw.py
|
33
|
+
src/txt2ebook/models/__init__.py
|
34
|
+
src/txt2ebook/models/book.py
|
35
|
+
src/txt2ebook/models/chapter.py
|
36
|
+
src/txt2ebook/models/volume.py
|
37
|
+
src/txt2ebook/subcommands/__init__.py
|
38
|
+
src/txt2ebook/subcommands/env.py
|
39
|
+
src/txt2ebook/subcommands/epub.py
|
40
|
+
src/txt2ebook/subcommands/gmi.py
|
41
|
+
src/txt2ebook/subcommands/massage.py
|
42
|
+
src/txt2ebook/subcommands/md.py
|
43
|
+
src/txt2ebook/subcommands/parse.py
|
44
|
+
src/txt2ebook/subcommands/pdf.py
|
45
|
+
src/txt2ebook/subcommands/tex.py
|
46
|
+
src/txt2ebook/subcommands/typ.py
|
47
|
+
tests/test_header_number_flag.py
|
48
|
+
tests/test_input_file_arg.py
|
49
|
+
tests/test_language_option.py
|
50
|
+
tests/test_output_file_arg.py
|
51
|
+
tests/test_overwrite_flag.py
|
52
|
+
tests/test_parser.py
|
53
|
+
tests/test_purge_flag.py
|
54
|
+
tests/test_quiet_flag.py
|
55
|
+
tests/test_sort_volume_and_chapter_flag.py
|
56
|
+
tests/test_split_volume_and_chapter_flag.py
|
57
|
+
tests/test_test_parsing_flag.py
|
58
|
+
tests/test_tokenizer.py
|
59
|
+
tests/test_txt2ebook.py
|
60
|
+
tests/test_verbose_flag.py
|
61
|
+
tests/test_volume_page_flag.py
|
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
CJKwrap~=2.2
|
2
|
+
EbookLib<0.18,>=0.17.1
|
3
|
+
bs4<0.0.2,>=0.0.1
|
4
|
+
importlib-resources<7,>=6.1.1
|
5
|
+
jieba<0.43,>=0.42.1
|
6
|
+
langdetect<2,>=1.0.9
|
7
|
+
lxml<6,>=5.2.2
|
8
|
+
pylatex<2,>=1.4.2
|
9
|
+
pypandoc~=1.11
|
10
|
+
regex<2022,>=2021.11.10
|
11
|
+
reportlab<5,>=4.0.0
|
12
|
+
typing-extensions<5,>=4.5.0
|
13
|
+
typst>=0.13.0
|
@@ -0,0 +1 @@
|
|
1
|
+
txt2ebook
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# # Copyright (c) 2021,2022,2023,2024,2025 Kian-Meng Ang
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU Affero General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU Affero General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Affero General Public License
|
14
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
from textwrap import dedent
|
17
|
+
|
18
|
+
import pytest
|
19
|
+
|
20
|
+
|
21
|
+
@pytest.mark.parametrize("option", ["-hn", "--header-number"])
|
22
|
+
def test_header_to_numbers_conversion(cli_runner, infile, option):
|
23
|
+
txtfile = infile("sample_long_headers.txt")
|
24
|
+
|
25
|
+
output = cli_runner("-d", option, txtfile)
|
26
|
+
expected_output1 = dedent(
|
27
|
+
"""\
|
28
|
+
DEBUG: Convert header to numbers: 第一卷 -> 第1卷
|
29
|
+
DEBUG: Convert header to numbers: 第一章 月既不解饮 -> 第1章 月既不解饮
|
30
|
+
DEBUG: Convert header to numbers: 第二章 影徒随我身 -> 第2章 影徒随我身
|
31
|
+
"""
|
32
|
+
)
|
33
|
+
assert expected_output1 in output.stdout
|
34
|
+
|
35
|
+
output = cli_runner("-d", "--header-number", txtfile)
|
36
|
+
expected_output2 = dedent(
|
37
|
+
"""\
|
38
|
+
DEBUG: Convert header to numbers: 第二卷 -> 第2卷
|
39
|
+
DEBUG: Convert header to numbers: 第三章 暂伴月将影 -> 第3章 暂伴月将影
|
40
|
+
DEBUG: Convert header to numbers: 第二百章 暂伴月将影 -> 第200章 暂伴月将
|
41
|
+
DEBUG: Convert header to numbers: 第九百九十九章 暂伴 -> 第999章 暂伴月将
|
42
|
+
DEBUG: Convert header to numbers: 第九千百九十九章 暂 -> 第9919章 暂伴月
|
43
|
+
"""
|
44
|
+
)
|
45
|
+
|
46
|
+
assert expected_output2 in output.stdout
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# # Copyright (c) 2021,2022,2023,2024,2025 Kian-Meng Ang
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU Affero General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU Affero General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Affero General Public License
|
14
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
|
17
|
+
def test_nonexistent_filename(cli_runner):
|
18
|
+
output = cli_runner("parse", "nonexistent.txt")
|
19
|
+
assert (
|
20
|
+
"[Errno 2] No such file or directory: 'nonexistent.txt'"
|
21
|
+
in output.stderr
|
22
|
+
)
|
23
|
+
|
24
|
+
|
25
|
+
def test_empty_file_content(cli_runner, infile):
|
26
|
+
txt = infile("empty_file.txt")
|
27
|
+
output = cli_runner("parse", str(txt))
|
28
|
+
assert f"error: Empty file content in {str(txt)}" in output.stdout
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# # Copyright (c) 2021,2022,2023,2024,2025 Kian-Meng Ang
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU Affero General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU Affero General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Affero General Public License
|
14
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
import pytest
|
17
|
+
|
18
|
+
|
19
|
+
def test_auto_detect_language(cli_runner, infile):
|
20
|
+
txtfile = infile("sample.txt")
|
21
|
+
output = cli_runner(txtfile)
|
22
|
+
assert "Detect language: zh-cn" in output.stdout
|
23
|
+
|
24
|
+
|
25
|
+
@pytest.mark.parametrize("option", ["-l", "--language"])
|
26
|
+
def test_warning_log_for_mismatch_configured_and_detect_language(
|
27
|
+
cli_runner, infile, option
|
28
|
+
):
|
29
|
+
txtfile = infile("missing_chapters.txt")
|
30
|
+
output = cli_runner(txtfile, option, "en")
|
31
|
+
assert "Config language: en" in output.stdout
|
32
|
+
assert "Detect language: ko" in output.stdout
|
33
|
+
assert "Config (en) and detect (ko) language mismatch" in output.stdout
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# # Copyright (c) 2021,2022,2023,2024,2025 Kian-Meng Ang
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU Affero General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU Affero General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Affero General Public License
|
14
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
|
17
|
+
def test_output_basename_default_to_input_basename(
|
18
|
+
tte, infile, outfile
|
19
|
+
):
|
20
|
+
txt = infile("sample.txt")
|
21
|
+
epub = outfile("output/sample.epub")
|
22
|
+
output = tte("epub", str(txt))
|
23
|
+
|
24
|
+
assert epub.exists()
|
25
|
+
assert f"Generate EPUB file: {str(epub)}" in output.stdout
|
26
|
+
|
27
|
+
|
28
|
+
def test_set_output_filename(tte, infile, outfile):
|
29
|
+
txt = infile("sample.txt")
|
30
|
+
epub = outfile("foobar.epub")
|
31
|
+
output = tte("epub", str(txt), str(epub))
|
32
|
+
|
33
|
+
assert epub.exists()
|
34
|
+
assert f"Generate EPUB file: {str(epub)}" in output.stdout
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# # Copyright (c) 2021,2022,2023,2024,2025 Kian-Meng Ang
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU Affero General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU Affero General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Affero General Public License
|
14
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
import pytest
|
17
|
+
|
18
|
+
|
19
|
+
@pytest.mark.parametrize("option", ["-ow", "--overwrite"])
|
20
|
+
def test_overwrite_source_txt_file(cli_runner, infile, option):
|
21
|
+
txtfile = infile("sample.txt")
|
22
|
+
output = cli_runner(txtfile, option)
|
23
|
+
assert "Backup txt file" not in output.stdout
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# # Copyright (c) 2021,2022,2023,2024,2025 Kian-Meng Ang
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU Affero General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU Affero General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Affero General Public License
|
14
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
15
|
+
import argparse
|
16
|
+
|
17
|
+
import pytest
|
18
|
+
|
19
|
+
from txt2ebook.parser import Parser
|
20
|
+
|
21
|
+
|
22
|
+
@pytest.fixture(name="config")
|
23
|
+
def fixture_config():
|
24
|
+
return argparse.Namespace(
|
25
|
+
**{
|
26
|
+
"author": False,
|
27
|
+
"translator": False,
|
28
|
+
"cover": None,
|
29
|
+
"fullwidth": False,
|
30
|
+
"header_number": False,
|
31
|
+
"language": "zh-cn",
|
32
|
+
"no_wrapping": False,
|
33
|
+
"paragraph_separator": "\n\n",
|
34
|
+
"raise_on_warning": False,
|
35
|
+
"re_author": (),
|
36
|
+
"re_chapter": (),
|
37
|
+
"re_delete": False,
|
38
|
+
"re_delete_line": False,
|
39
|
+
"re_replace": False,
|
40
|
+
"re_title": (),
|
41
|
+
"re_volume": (),
|
42
|
+
"re_volume_chapter": (),
|
43
|
+
"sort_volume_and_chapter": False,
|
44
|
+
"title": False,
|
45
|
+
"verbose": 1,
|
46
|
+
"width": False,
|
47
|
+
}
|
48
|
+
)
|
49
|
+
|
50
|
+
|
51
|
+
def test_parsing_two_newlines_as_paragraph_separator(config):
|
52
|
+
content = """\
|
53
|
+
---
|
54
|
+
书名:月下独酌·其一
|
55
|
+
作者:李白
|
56
|
+
---
|
57
|
+
|
58
|
+
第一章
|
59
|
+
|
60
|
+
天地玄黄。(paragraph 1)
|
61
|
+
|
62
|
+
寒来暑往,秋收冬藏。(paragraph 2)
|
63
|
+
云腾致雨,露结为霜,金生丽水。(paragraph 2)
|
64
|
+
|
65
|
+
第二章
|
66
|
+
|
67
|
+
剑号巨阙,珠称夜光,果珍李柰,菜重芥姜。(paragraph 1)
|
68
|
+
"""
|
69
|
+
parser = Parser(content, config)
|
70
|
+
[chapter1, chapter2] = parser.parse().toc
|
71
|
+
assert len(chapter1.paragraphs) == 2
|
72
|
+
assert len(chapter2.paragraphs) == 1
|
73
|
+
|
74
|
+
|
75
|
+
def test_parsing_one_newline_as_paragraph_separator(config):
|
76
|
+
content = """\
|
77
|
+
---
|
78
|
+
书名:月下独酌·其一
|
79
|
+
作者:李白
|
80
|
+
---
|
81
|
+
|
82
|
+
第一章
|
83
|
+
天地玄黄。(paragraph 1)
|
84
|
+
寒来暑往,秋收冬藏。 (paragraph 2)
|
85
|
+
云腾致雨,露结为霜,金生丽水。 (paragraph 3)
|
86
|
+
第二章
|
87
|
+
剑号巨阙,珠称夜光,果珍李柰,菜重芥姜。(paragraph 1)
|
88
|
+
"""
|
89
|
+
config.paragraph_separator = "\n"
|
90
|
+
parser = Parser(content, config)
|
91
|
+
book = parser.parse()
|
92
|
+
[chapter1, chapter2] = book.toc
|
93
|
+
assert len(chapter1.paragraphs) == 3
|
94
|
+
assert len(chapter2.paragraphs) == 1
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# # Copyright (c) 2021,2022,2023,2024,2025 Kian-Meng Ang
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU Affero General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU Affero General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Affero General Public License
|
14
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
import pytest
|
17
|
+
|
18
|
+
|
19
|
+
@pytest.mark.parametrize("option", ["-p", "--purge"])
|
20
|
+
def test_debug_log(cli_runner, infile, option):
|
21
|
+
txt = infile("sample.txt")
|
22
|
+
output = cli_runner(txt, "-d", option)
|
23
|
+
assert "purge=True" in output.stdout
|
24
|
+
|
25
|
+
|
26
|
+
def test_purge_output_folder_if_exists(cli_runner, infile, tmpdir):
|
27
|
+
csv = infile("sample.txt")
|
28
|
+
opf = f"{tmpdir}/output"
|
29
|
+
_ = cli_runner(csv, "-d", "-of", opf)
|
30
|
+
output = cli_runner(csv, "-d", "-of", opf, "-p", "-y")
|
31
|
+
assert f"Purge output folder: {opf}" in output.stdout
|
32
|
+
|
33
|
+
|
34
|
+
def test_prompt_when_purging_output_folder(cli_runner, infile, tmpdir):
|
35
|
+
csv = infile("sample.txt")
|
36
|
+
opf = f"{tmpdir}/output"
|
37
|
+
_ = cli_runner(csv, "-d", "-of", opf)
|
38
|
+
|
39
|
+
output = cli_runner(csv, "-d", "-of", opf, "-p", stdin=b"y")
|
40
|
+
assert (
|
41
|
+
f"Are you sure to purge output folder: {opf}? [y/N] " in output.stdout
|
42
|
+
)
|
43
|
+
|
44
|
+
|
45
|
+
def test_no_purge_output_folder_if_not_exists(cli_runner, infile):
|
46
|
+
csv = infile("sample.txt")
|
47
|
+
output_folder = csv.resolve().parent.joinpath("output")
|
48
|
+
output = cli_runner(csv, "-d", "-p")
|
49
|
+
assert f"Purge output folder: {output_folder}" not in output.stdout
|