txt2ebook 0.1.116__tar.gz → 0.1.118__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.
Files changed (52) hide show
  1. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/PKG-INFO +1 -1
  2. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/pyproject.toml +1 -1
  3. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/__init__.py +1 -1
  4. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/cli.py +2 -114
  5. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/parser.py +1 -1
  6. txt2ebook-0.1.118/src/txt2ebook/subcommands/__init__.py +33 -0
  7. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/subcommands/epub.py +24 -0
  8. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/subcommands/gmi.py +24 -0
  9. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/subcommands/massage.py +9 -0
  10. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/subcommands/md.py +24 -0
  11. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/subcommands/pdf.py +33 -0
  12. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/subcommands/tex.py +33 -0
  13. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/subcommands/typ.py +34 -1
  14. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/tokenizer.py +5 -5
  15. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/LICENSE.md +0 -0
  16. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/README.md +0 -0
  17. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/__main__.py +0 -0
  18. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/exceptions.py +0 -0
  19. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/formats/__init__.py +0 -0
  20. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/formats/base.py +0 -0
  21. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/formats/epub.py +0 -0
  22. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/formats/gmi.py +0 -0
  23. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/formats/md.py +0 -0
  24. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/formats/pdf.py +0 -0
  25. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/formats/templates/__init__.py +0 -0
  26. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/formats/templates/epub/__init__.py +0 -0
  27. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/formats/templates/epub/clean.css +0 -0
  28. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/formats/templates/epub/condense.css +0 -0
  29. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/formats/templates/epub/noindent.css +0 -0
  30. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/formats/tex.py +0 -0
  31. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/formats/txt.py +0 -0
  32. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/formats/typ.py +0 -0
  33. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/helpers/__init__.py +0 -0
  34. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/languages/__init__.py +0 -0
  35. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/languages/en.py +0 -0
  36. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/languages/zh_cn.py +0 -0
  37. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/languages/zh_tw.py +0 -0
  38. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/locales/en/LC_MESSAGES/txt2ebook.mo +0 -0
  39. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/locales/en/LC_MESSAGES/txt2ebook.po +0 -0
  40. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/locales/txt2ebook.pot +0 -0
  41. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/locales/zh-cn/LC_MESSAGES/txt2ebook.mo +0 -0
  42. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/locales/zh-cn/LC_MESSAGES/txt2ebook.po +0 -0
  43. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/locales/zh-tw/LC_MESSAGES/txt2ebook.mo +0 -0
  44. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/locales/zh-tw/LC_MESSAGES/txt2ebook.po +0 -0
  45. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/models/__init__.py +0 -0
  46. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/models/book.py +0 -0
  47. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/models/chapter.py +0 -0
  48. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/models/volume.py +0 -0
  49. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/subcommands/env.py +0 -0
  50. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/subcommands/parse.py +0 -0
  51. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/txt2ebook.py +0 -0
  52. {txt2ebook-0.1.116 → txt2ebook-0.1.118}/src/txt2ebook/zh_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: txt2ebook
3
- Version: 0.1.116
3
+ Version: 0.1.118
4
4
  Summary: CLI tool to convert txt file to ebook format
5
5
  Home-page: https://github.com/kianmeng/txt2ebook
6
6
  License: AGPL-3.0-or-later
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "txt2ebook"
3
- version = "0.1.116"
3
+ version = "0.1.118"
4
4
  description = "CLI tool to convert txt file to ebook format"
5
5
  authors = ["Kian-Meng Ang <kianmeng@cpan.org>"]
6
6
  license = "AGPL-3.0-or-later"
@@ -24,7 +24,7 @@ import langdetect
24
24
 
25
25
  logger = logging.getLogger(__name__)
26
26
 
27
- __version__ = "0.1.116"
27
+ __version__ = "0.1.118"
28
28
 
29
29
 
30
30
  def setup_logger(config: argparse.Namespace) -> None:
@@ -25,15 +25,7 @@ import logging
25
25
  import sys
26
26
  from typing import Optional, Sequence
27
27
 
28
- import txt2ebook.subcommands.env
29
- import txt2ebook.subcommands.epub
30
- import txt2ebook.subcommands.gmi
31
- import txt2ebook.subcommands.massage
32
- import txt2ebook.subcommands.md
33
- import txt2ebook.subcommands.parse
34
- import txt2ebook.subcommands.pdf
35
- import txt2ebook.subcommands.tex
36
- import txt2ebook.subcommands.typ
28
+ import txt2ebook.subcommands
37
29
  from txt2ebook import __version__, setup_logger
38
30
 
39
31
  logger = logging.getLogger(__name__)
@@ -100,15 +92,6 @@ def build_parser(
100
92
  metavar="AUTHOR",
101
93
  )
102
94
 
103
- parser.add_argument(
104
- "-c",
105
- "--cover",
106
- dest="cover",
107
- default=None,
108
- help="cover of the ebook",
109
- metavar="IMAGE_FILENAME",
110
- )
111
-
112
95
  parser.add_argument(
113
96
  "-tr",
114
97
  "--translator",
@@ -128,50 +111,6 @@ def build_parser(
128
111
  help="convert ASCII character from halfwidth to fullwidth",
129
112
  )
130
113
 
131
-
132
- parser.add_argument(
133
- "-ra",
134
- "--regex-author",
135
- dest="re_author",
136
- default=[],
137
- action="append",
138
- help="regex to parse author of the book (default: by LANGUAGE)",
139
- metavar="REGEX",
140
- )
141
-
142
- parser.add_argument(
143
- "-rc",
144
- "--regex-chapter",
145
- dest="re_chapter",
146
- default=[],
147
- action="append",
148
- help="regex to parse chapter header (default: by LANGUAGE)",
149
- metavar="REGEX",
150
- )
151
-
152
- parser.add_argument(
153
- "-rvc",
154
- "--regex-volume-chapter",
155
- dest="re_volume_chapter",
156
- default=[],
157
- action="append",
158
- help=(
159
- "regex to parse volume and chapter header "
160
- "(default: by LANGUAGE)"
161
- ),
162
- metavar="REGEX",
163
- )
164
-
165
- parser.add_argument(
166
- "-rv",
167
- "--regex-volume",
168
- dest="re_volume",
169
- default=[],
170
- action="append",
171
- help="regex to parse volume header (default: by LANGUAGE)",
172
- metavar="REGEX",
173
- )
174
-
175
114
  parser.add_argument(
176
115
  "-hn",
177
116
  "--header-number",
@@ -191,49 +130,6 @@ def build_parser(
191
130
  metavar="SEPARATOR",
192
131
  )
193
132
 
194
- parser.add_argument(
195
- "-rt",
196
- "--regex-title",
197
- dest="re_title",
198
- default=[],
199
- action="append",
200
- help="regex to parse title of the book (default: by LANGUAGE)",
201
- metavar="REGEX",
202
- )
203
-
204
- parser.add_argument(
205
- "-ff",
206
- "--filename-format",
207
- dest="filename_format",
208
- type=int,
209
- default=None,
210
- help=(
211
- "the output filename format "
212
- "(default: TXT_FILENAME [EBOOK_FILENAME])\n"
213
- "1 - title_authors.EBOOK_EXTENSION\n"
214
- "2 - authors_title.EBOOK_EXTENSION"
215
- ),
216
- metavar="FILENAME_FORMAT",
217
- )
218
-
219
- parser.add_argument(
220
- "-op",
221
- "--open",
222
- default=False,
223
- action="store_true",
224
- dest="open",
225
- help="open the generated file using default program",
226
- )
227
-
228
- parser.add_argument(
229
- "-ss",
230
- "--sort-volume-and-chapter",
231
- default=False,
232
- action="store_true",
233
- dest="sort_volume_and_chapter",
234
- help="short volume and chapter",
235
- )
236
-
237
133
  parser.add_argument(
238
134
  "-rw",
239
135
  "--raise-on-warning",
@@ -286,15 +182,7 @@ def build_parser(
286
182
  )
287
183
 
288
184
  subparsers = parser.add_subparsers(help="sub-command help")
289
- txt2ebook.subcommands.parse.build_subparser(subparsers)
290
- txt2ebook.subcommands.massage.build_subparser(subparsers)
291
- txt2ebook.subcommands.epub.build_subparser(subparsers)
292
- txt2ebook.subcommands.tex.build_subparser(subparsers)
293
- txt2ebook.subcommands.pdf.build_subparser(subparsers)
294
- txt2ebook.subcommands.typ.build_subparser(subparsers)
295
- txt2ebook.subcommands.md.build_subparser(subparsers)
296
- txt2ebook.subcommands.gmi.build_subparser(subparsers)
297
- txt2ebook.subcommands.env.build_subparser(subparsers)
185
+ txt2ebook.subcommands.build_subparser(subparsers)
298
186
 
299
187
  return parser
300
188
 
@@ -231,7 +231,7 @@ class Parser:
231
231
  logger.info("Found or set tags: %s", repr(tags))
232
232
  logger.info("Found or set index: %s", repr(index))
233
233
 
234
- if self.config.sort_volume_and_chapter:
234
+ if hasattr(self.config, "sort_volume_and_chapter") and self.config.sort_volume_and_chapter:
235
235
  self.sort_volume_and_chapter(toc)
236
236
 
237
237
  return (book_title, authors, translators, tags, index, toc)
@@ -0,0 +1,33 @@
1
+ # Copyright (C) 2021,2022,2023,2024 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
+ """Common utils for subcommand."""
17
+
18
+ import importlib
19
+ import pkgutil
20
+
21
+
22
+ def build_subparser(subparsers):
23
+ """Build subparser for each subcommands."""
24
+ iter_namespace = pkgutil.iter_modules(__path__, __name__ + ".")
25
+
26
+ subcommands = {
27
+ name: importlib.import_module(name)
28
+ for finder, name, ispkg
29
+ in iter_namespace
30
+ }
31
+
32
+ for subcommand in subcommands.values():
33
+ subcommand.build_subparser(subparsers)
@@ -79,6 +79,30 @@ def build_subparser(subparsers) -> None:
79
79
  help="generate each volume as separate page",
80
80
  )
81
81
 
82
+ epub_parser.add_argument(
83
+ "-op",
84
+ "--open",
85
+ default=False,
86
+ action="store_true",
87
+ dest="open",
88
+ help="open the generated file using default program",
89
+ )
90
+
91
+ epub_parser.add_argument(
92
+ "-ff",
93
+ "--filename-format",
94
+ dest="filename_format",
95
+ type=int,
96
+ default=None,
97
+ help=(
98
+ "the output filename format "
99
+ "(default: TXT_FILENAME [EBOOK_FILENAME])\n"
100
+ "1 - title_authors.EBOOK_EXTENSION\n"
101
+ "2 - authors_title.EBOOK_EXTENSION"
102
+ ),
103
+ metavar="FILENAME_FORMAT",
104
+ )
105
+
82
106
 
83
107
  def run(args: argparse.Namespace) -> None:
84
108
  """Run epub subcommand.
@@ -71,6 +71,30 @@ def build_subparser(subparsers) -> None:
71
71
  help="add table of content",
72
72
  )
73
73
 
74
+ gmi_parser.add_argument(
75
+ "-op",
76
+ "--open",
77
+ default=False,
78
+ action="store_true",
79
+ dest="open",
80
+ help="open the generated file using default program",
81
+ )
82
+
83
+ gmi_parser.add_argument(
84
+ "-ff",
85
+ "--filename-format",
86
+ dest="filename_format",
87
+ type=int,
88
+ default=None,
89
+ help=(
90
+ "the output filename format "
91
+ "(default: TXT_FILENAME [EBOOK_FILENAME])\n"
92
+ "1 - title_authors.EBOOK_EXTENSION\n"
93
+ "2 - authors_title.EBOOK_EXTENSION"
94
+ ),
95
+ metavar="FILENAME_FORMAT",
96
+ )
97
+
74
98
 
75
99
  def run(args: argparse.Namespace) -> None:
76
100
  """Run md subcommand.
@@ -117,6 +117,15 @@ def build_subparser(subparsers) -> None:
117
117
  metavar="WIDTH",
118
118
  )
119
119
 
120
+ massage_parser.add_argument(
121
+ "-ss",
122
+ "--sort-volume-and-chapter",
123
+ default=False,
124
+ action="store_true",
125
+ dest="sort_volume_and_chapter",
126
+ help="short volume and chapter",
127
+ )
128
+
120
129
  massage_parser.set_defaults(func=run)
121
130
 
122
131
 
@@ -71,6 +71,30 @@ def build_subparser(subparsers) -> None:
71
71
  help="add table of content",
72
72
  )
73
73
 
74
+ md_parser.add_argument(
75
+ "-op",
76
+ "--open",
77
+ default=False,
78
+ action="store_true",
79
+ dest="open",
80
+ help="open the generated file using default program",
81
+ )
82
+
83
+ md_parser.add_argument(
84
+ "-ff",
85
+ "--filename-format",
86
+ dest="filename_format",
87
+ type=int,
88
+ default=None,
89
+ help=(
90
+ "the output filename format "
91
+ "(default: TXT_FILENAME [EBOOK_FILENAME])\n"
92
+ "1 - title_authors.EBOOK_EXTENSION\n"
93
+ "2 - authors_title.EBOOK_EXTENSION"
94
+ ),
95
+ metavar="FILENAME_FORMAT",
96
+ )
97
+
74
98
 
75
99
  def run(args: argparse.Namespace) -> None:
76
100
  """Run md subcommand.
@@ -52,6 +52,15 @@ def build_subparser(subparsers) -> None:
52
52
  metavar="EBOOK_FILENAME",
53
53
  )
54
54
 
55
+ pdf_parser.add_argument(
56
+ "-c",
57
+ "--cover",
58
+ dest="cover",
59
+ default=None,
60
+ help="cover of the ebook",
61
+ metavar="IMAGE_FILENAME",
62
+ )
63
+
55
64
  pdf_parser.add_argument(
56
65
  "-pz",
57
66
  "--page-size",
@@ -62,6 +71,30 @@ def build_subparser(subparsers) -> None:
62
71
  metavar="PAGE_SIZE",
63
72
  )
64
73
 
74
+ pdf_parser.add_argument(
75
+ "-op",
76
+ "--open",
77
+ default=False,
78
+ action="store_true",
79
+ dest="open",
80
+ help="open the generated file using default program",
81
+ )
82
+
83
+ pdf_parser.add_argument(
84
+ "-ff",
85
+ "--filename-format",
86
+ dest="filename_format",
87
+ type=int,
88
+ default=None,
89
+ help=(
90
+ "the output filename format "
91
+ "(default: TXT_FILENAME [EBOOK_FILENAME])\n"
92
+ "1 - title_authors.EBOOK_EXTENSION\n"
93
+ "2 - authors_title.EBOOK_EXTENSION"
94
+ ),
95
+ metavar="FILENAME_FORMAT",
96
+ )
97
+
65
98
 
66
99
  def run(args: argparse.Namespace) -> None:
67
100
  """Run pdf subcommand.
@@ -68,6 +68,39 @@ def build_subparser(subparsers) -> None:
68
68
 
69
69
  tex_parser.set_defaults(func=run)
70
70
 
71
+ tex_parser.add_argument(
72
+ "-c",
73
+ "--cover",
74
+ dest="cover",
75
+ default=None,
76
+ help="cover of the ebook",
77
+ metavar="IMAGE_FILENAME",
78
+ )
79
+
80
+ tex_parser.add_argument(
81
+ "-op",
82
+ "--open",
83
+ default=False,
84
+ action="store_true",
85
+ dest="open",
86
+ help="open the generated file using default program",
87
+ )
88
+
89
+ tex_parser.add_argument(
90
+ "-ff",
91
+ "--filename-format",
92
+ dest="filename_format",
93
+ type=int,
94
+ default=None,
95
+ help=(
96
+ "the output filename format "
97
+ "(default: TXT_FILENAME [EBOOK_FILENAME])\n"
98
+ "1 - title_authors.EBOOK_EXTENSION\n"
99
+ "2 - authors_title.EBOOK_EXTENSION"
100
+ ),
101
+ metavar="FILENAME_FORMAT",
102
+ )
103
+
71
104
 
72
105
  def run(args: argparse.Namespace) -> None:
73
106
  """Run tex subcommand.
@@ -13,7 +13,7 @@
13
13
  # You should have received a copy of the GNU Affero General Public License
14
14
  # along with this program. If not, see <https://www.gnu.org/licenses/>.
15
15
 
16
- """md subcommand."""
16
+ """typ subcommand."""
17
17
 
18
18
  import argparse
19
19
  import logging
@@ -52,6 +52,15 @@ def build_subparser(subparsers) -> None:
52
52
  metavar="EBOOK_FILENAME",
53
53
  )
54
54
 
55
+ typ_parser.add_argument(
56
+ "-c",
57
+ "--cover",
58
+ dest="cover",
59
+ default=None,
60
+ help="cover of the ebook",
61
+ metavar="IMAGE_FILENAME",
62
+ )
63
+
55
64
  typ_parser.add_argument(
56
65
  "-pz",
57
66
  "--page-size",
@@ -79,6 +88,30 @@ def build_subparser(subparsers) -> None:
79
88
  help="keyword to index (default: '%(default)s')",
80
89
  )
81
90
 
91
+ typ_parser.add_argument(
92
+ "-op",
93
+ "--open",
94
+ default=False,
95
+ action="store_true",
96
+ dest="open",
97
+ help="open the generated file using default program",
98
+ )
99
+
100
+ typ_parser.add_argument(
101
+ "-ff",
102
+ "--filename-format",
103
+ dest="filename_format",
104
+ type=int,
105
+ default=None,
106
+ help=(
107
+ "the output filename format "
108
+ "(default: TXT_FILENAME [EBOOK_FILENAME])\n"
109
+ "1 - title_authors.EBOOK_EXTENSION\n"
110
+ "2 - authors_title.EBOOK_EXTENSION"
111
+ ),
112
+ metavar="FILENAME_FORMAT",
113
+ )
114
+
82
115
 
83
116
  def run(args: argparse.Namespace) -> None:
84
117
  """Run typ subcommand.
@@ -114,11 +114,11 @@ class Tokenizer:
114
114
  """Tokenize the metadata of the book."""
115
115
  for line in self._extract_metadata():
116
116
  re_title = f"^{self.langconf.DEFAULT_RE_TITLE}"
117
- if self.config.re_title:
117
+ if hasattr(self.config, "re_title") and self.config.re_title:
118
118
  re_title = self.config.re_title[0]
119
119
 
120
120
  re_author = f"{self.langconf.DEFAULT_RE_AUTHOR}"
121
- if self.config.re_author:
121
+ if hasattr(self.config, "re_author") and self.config.re_author:
122
122
  re_author = self.config.re_author[0]
123
123
 
124
124
  token_type_regex_map = [
@@ -205,7 +205,7 @@ class Tokenizer:
205
205
  rf"^{self.langconf.DEFAULT_RE_VOLUME}\s*"
206
206
  rf"{self.langconf.DEFAULT_RE_CHAPTER}"
207
207
  )
208
- if self.config.re_volume_chapter:
208
+ if hasattr(self.config, "re_volume_chapter") and self.config.re_volume_chapter:
209
209
  re_volume_chapter = self.config.re_volume_chapter[0]
210
210
 
211
211
  match = re.search(re_volume_chapter, line)
@@ -228,7 +228,7 @@ class Tokenizer:
228
228
  token = None
229
229
 
230
230
  re_volume = rf"^{self.langconf.DEFAULT_RE_VOLUME}$"
231
- if self.config.re_volume:
231
+ if hasattr(self.config, "re_volume") and self.config.re_volume:
232
232
  re_volume = "(" + "|".join(self.config.re_volume) + ")"
233
233
 
234
234
  match = re.search(re_volume, line)
@@ -244,7 +244,7 @@ class Tokenizer:
244
244
  token = None
245
245
 
246
246
  re_chapter = rf"^{self.langconf.DEFAULT_RE_CHAPTER}$"
247
- if self.config.re_chapter:
247
+ if hasattr(self.config, "re_chapter") and self.config.re_chapter:
248
248
  re_chapter = "(" + "|".join(self.config.re_chapter) + ")"
249
249
 
250
250
  match = re.search(re_chapter, line)
File without changes
File without changes