chgksuite 0.24.3__tar.gz → 0.25.0b2__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.
- {chgksuite-0.24.3/chgksuite.egg-info → chgksuite-0.25.0b2}/PKG-INFO +1 -1
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/composer/pptx.py +91 -33
- chgksuite-0.25.0b2/chgksuite/version.py +1 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2/chgksuite.egg-info}/PKG-INFO +1 -1
- chgksuite-0.24.3/chgksuite/version.py +0 -1
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/LICENSE +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/MANIFEST.in +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/README.md +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/__init__.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/__main__.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/cli.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/common.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/composer/__init__.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/composer/chgksuite_parser.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/composer/composer_common.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/composer/db.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/composer/docx.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/composer/latex.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/composer/lj.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/composer/openquiz.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/composer/reddit.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/composer/stats.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/composer/telegram.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/composer/telegram_bot.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/composer/telegram_parser.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/parser.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/parser_db.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/cheader.tex +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/fix-unnumbered-sections.sty +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/labels_by.toml +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/labels_by_tar.toml +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/labels_en.toml +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/labels_kz_cyr.toml +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/labels_ru.toml +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/labels_sr.toml +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/labels_ua.toml +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/labels_uz.toml +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/labels_uz_cyr.toml +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/pptx_config.toml +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/regexes_by.json +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/regexes_en.json +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/regexes_kz_cyr.json +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/regexes_ru.json +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/regexes_sr.json +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/regexes_ua.json +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/regexes_uz_cyr.json +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/template.docx +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/template.pptx +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/template_shorin.pptx +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/resources/trello.json +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/trello.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/typotools.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite/vulture_whitelist.py +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite.egg-info/SOURCES.txt +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite.egg-info/dependency_links.txt +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite.egg-info/entry_points.txt +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite.egg-info/requires.txt +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/chgksuite.egg-info/top_level.txt +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/history.md +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/setup.cfg +0 -0
- {chgksuite-0.24.3 → chgksuite-0.25.0b2}/setup.py +0 -0
|
@@ -5,10 +5,11 @@ import re
|
|
|
5
5
|
import toml
|
|
6
6
|
from pptx import Presentation
|
|
7
7
|
from pptx.dml.color import RGBColor
|
|
8
|
+
from pptx.enum.text import MSO_AUTO_SIZE, MSO_VERTICAL_ANCHOR
|
|
8
9
|
from pptx.util import Inches as PptxInches
|
|
9
10
|
from pptx.util import Pt as PptxPt
|
|
10
11
|
|
|
11
|
-
from chgksuite.common import log_wrap, replace_escaped
|
|
12
|
+
from chgksuite.common import log_wrap, replace_escaped, tryint
|
|
12
13
|
from chgksuite.composer.composer_common import BaseExporter, backtick_replace, parseimg
|
|
13
14
|
|
|
14
15
|
|
|
@@ -130,6 +131,14 @@ class PptxExporter(BaseExporter):
|
|
|
130
131
|
s = s.strip()
|
|
131
132
|
return s
|
|
132
133
|
|
|
134
|
+
def apply_vertical_alignment_if_needed(self, text_frame):
|
|
135
|
+
align = self.c["textbox"].get("vertical_align")
|
|
136
|
+
if align:
|
|
137
|
+
text_frame.auto_size = MSO_AUTO_SIZE.NONE
|
|
138
|
+
text_frame.margin_top = 0
|
|
139
|
+
text_frame.margin_bottom = 0
|
|
140
|
+
text_frame.vertical_anchor = getattr(MSO_VERTICAL_ANCHOR, align.upper())
|
|
141
|
+
|
|
133
142
|
def _process_block(self, block):
|
|
134
143
|
section = [x for x in block if x[0] == "section"]
|
|
135
144
|
editor = [x for x in block if x[0] == "editor"]
|
|
@@ -139,6 +148,7 @@ class PptxExporter(BaseExporter):
|
|
|
139
148
|
slide = self.prs.slides.add_slide(self.BLANK_SLIDE)
|
|
140
149
|
textbox = self.get_textbox(slide)
|
|
141
150
|
tf = textbox.text_frame
|
|
151
|
+
self.apply_vertical_alignment_if_needed(tf)
|
|
142
152
|
tf.word_wrap = True
|
|
143
153
|
text_for_size = (
|
|
144
154
|
(self.recursive_join([x[1] for x in section]) or "")
|
|
@@ -150,10 +160,16 @@ class PptxExporter(BaseExporter):
|
|
|
150
160
|
p = self.init_paragraph(tf, text=text_for_size)
|
|
151
161
|
add_line_break = False
|
|
152
162
|
if section:
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
163
|
+
if self.c.get("tour_as_question_number"):
|
|
164
|
+
txt = self.pptx_process_text(section[0][1])
|
|
165
|
+
if self.c.get("tour_as_question_number") == "caps":
|
|
166
|
+
txt = txt.upper()
|
|
167
|
+
self.set_question_number(slide, number=txt)
|
|
168
|
+
else:
|
|
169
|
+
r = p.add_run()
|
|
170
|
+
r.text = self._replace_no_break(self.pptx_process_text(section[0][1]))
|
|
171
|
+
r.font.size = PptxPt(self.c["text_size_grid"]["section"])
|
|
172
|
+
add_line_break = True
|
|
157
173
|
if editor:
|
|
158
174
|
r = p.add_run()
|
|
159
175
|
r.text = self._replace_no_break(
|
|
@@ -207,9 +223,13 @@ class PptxExporter(BaseExporter):
|
|
|
207
223
|
qtf = qntextbox.text_frame
|
|
208
224
|
qtf_p = self.init_paragraph(qtf)
|
|
209
225
|
qtf_r = qtf_p.add_run()
|
|
226
|
+
if self.c.get("question_number_format") == "caps" and tryint(number):
|
|
227
|
+
number = f"ВОПРОС {number}"
|
|
210
228
|
qtf_r.text = number
|
|
211
229
|
if self.c["number_textbox"].get("color"):
|
|
212
230
|
qtf_r.font.color.rgb = RGBColor(*self.c["number_textbox"]["color"])
|
|
231
|
+
if self.c["number_textbox"].get("font_size"):
|
|
232
|
+
qtf_r.font.size = PptxPt(self.c["number_textbox"]["font_size"])
|
|
213
233
|
|
|
214
234
|
def _get_handout_from_4s(self, text):
|
|
215
235
|
if isinstance(text, list):
|
|
@@ -336,10 +356,14 @@ class PptxExporter(BaseExporter):
|
|
|
336
356
|
image, slide, allowbigimage=allowbigimage
|
|
337
357
|
)
|
|
338
358
|
tf = textbox.text_frame
|
|
359
|
+
self.apply_vertical_alignment_if_needed(tf)
|
|
339
360
|
tf.word_wrap = True
|
|
340
361
|
self.set_question_number(slide, self.number)
|
|
341
362
|
question_text = self.pptx_process_text(q["question"], image=image)
|
|
342
|
-
|
|
363
|
+
if self.c.get("force_text_size_question"):
|
|
364
|
+
p = self.init_paragraph(tf, size=self.c["force_text_size_question"])
|
|
365
|
+
else:
|
|
366
|
+
p = self.init_paragraph(tf, text=question_text, coeff=coeff)
|
|
343
367
|
self.pptx_format(question_text, p, tf, slide)
|
|
344
368
|
|
|
345
369
|
def recursive_join(self, s):
|
|
@@ -352,13 +376,12 @@ class PptxExporter(BaseExporter):
|
|
|
352
376
|
slide = self.prs.slides.add_slide(self.BLANK_SLIDE)
|
|
353
377
|
textbox = self.get_textbox(slide)
|
|
354
378
|
tf = textbox.text_frame
|
|
379
|
+
self.apply_vertical_alignment_if_needed(tf)
|
|
355
380
|
tf.word_wrap = True
|
|
356
381
|
if number is not None:
|
|
357
382
|
self.set_question_number(slide, number)
|
|
358
383
|
p = self.init_paragraph(tf, text=handout)
|
|
359
|
-
self.pptx_format(
|
|
360
|
-
self.pptx_process_text(handout), p, tf, slide
|
|
361
|
-
)
|
|
384
|
+
self.pptx_format(self.pptx_process_text(handout), p, tf, slide)
|
|
362
385
|
|
|
363
386
|
def process_question_text(self, q):
|
|
364
387
|
image = self._get_image_from_4s(q["question"])
|
|
@@ -375,31 +398,19 @@ class PptxExporter(BaseExporter):
|
|
|
375
398
|
if image and image["big"] and text_is_duplicated:
|
|
376
399
|
self.add_slide_with_image(image, number=self.number)
|
|
377
400
|
|
|
378
|
-
def
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
self.qcount = int(q["setcounter"])
|
|
383
|
-
self.number = str(self.qcount if "number" not in q else q["number"])
|
|
384
|
-
|
|
385
|
-
if isinstance(q["question"], list):
|
|
386
|
-
for i in range(len(q["question"][1])):
|
|
387
|
-
qn = copy.deepcopy(q)
|
|
388
|
-
qn["question"][1] = q["question"][1][: i + 1]
|
|
389
|
-
self.process_question_text(qn)
|
|
401
|
+
def add_answer_slide(self, q):
|
|
402
|
+
slide = self.prs.slides.add_slide(self.BLANK_SLIDE)
|
|
403
|
+
if self.c.get("override_answer_caption"):
|
|
404
|
+
self.set_question_number(slide, self.c["override_answer_caption"])
|
|
390
405
|
else:
|
|
391
|
-
self.process_question_text(q)
|
|
392
|
-
|
|
393
|
-
if self.c["add_plug"]:
|
|
394
|
-
slide = self.prs.slides.add_slide(self.BLANK_SLIDE)
|
|
395
406
|
self.set_question_number(slide, self.number)
|
|
396
|
-
slide = self.prs.slides.add_slide(self.BLANK_SLIDE)
|
|
397
|
-
self.set_question_number(slide, self.number)
|
|
398
407
|
fields = ["answer"]
|
|
399
408
|
if q.get("zachet") and self.c.get("add_zachet"):
|
|
400
409
|
fields.append("zachet")
|
|
401
410
|
if self.c["add_comment"] and "comment" in q:
|
|
402
411
|
fields.append("comment")
|
|
412
|
+
if self.c["add_source"] and "source" in q:
|
|
413
|
+
fields.append("source")
|
|
403
414
|
textbox = None
|
|
404
415
|
coeff = 1
|
|
405
416
|
for field in fields:
|
|
@@ -410,6 +421,7 @@ class PptxExporter(BaseExporter):
|
|
|
410
421
|
if not textbox:
|
|
411
422
|
textbox = self.get_textbox(slide)
|
|
412
423
|
tf = textbox.text_frame
|
|
424
|
+
self.apply_vertical_alignment_if_needed(tf)
|
|
413
425
|
tf.word_wrap = True
|
|
414
426
|
|
|
415
427
|
text_for_size = self.recursive_join(
|
|
@@ -423,7 +435,18 @@ class PptxExporter(BaseExporter):
|
|
|
423
435
|
text_for_size += "\n" + self.recursive_join(
|
|
424
436
|
self.pptx_process_text(q["comment"])
|
|
425
437
|
)
|
|
426
|
-
|
|
438
|
+
if q.get("source") and self.c.get("add_source"):
|
|
439
|
+
text_for_size += "\n" + self.recursive_join(
|
|
440
|
+
self.pptx_process_text(q["source"])
|
|
441
|
+
)
|
|
442
|
+
if q.get("author") and self.c.get("add_author"):
|
|
443
|
+
text_for_size += "\n" + self.recursive_join(
|
|
444
|
+
self.pptx_process_text(q["author"])
|
|
445
|
+
)
|
|
446
|
+
if self.c.get("force_text_size_answer"):
|
|
447
|
+
p = self.init_paragraph(tf, size=self.c["force_text_size_answer"])
|
|
448
|
+
else:
|
|
449
|
+
p = self.init_paragraph(tf, text=text_for_size, coeff=coeff)
|
|
427
450
|
r = p.add_run()
|
|
428
451
|
r.text = f"{self.get_label(q, 'answer')}: "
|
|
429
452
|
r.font.bold = True
|
|
@@ -442,6 +465,38 @@ class PptxExporter(BaseExporter):
|
|
|
442
465
|
r.text = f"\n{self.get_label(q, 'comment')}: "
|
|
443
466
|
r.font.bold = True
|
|
444
467
|
self.pptx_format(comment_text, p, tf, slide)
|
|
468
|
+
if self.c["add_source"] and "source" in q:
|
|
469
|
+
source_text = self.pptx_process_text(q["source"])
|
|
470
|
+
r = p.add_run()
|
|
471
|
+
r.text = f"\n{self.get_label(q, 'source')}: "
|
|
472
|
+
r.font.bold = True
|
|
473
|
+
self.pptx_format(source_text, p, tf, slide)
|
|
474
|
+
if self.c["add_author"] and "author" in q:
|
|
475
|
+
author_text = self.pptx_process_text(q["author"])
|
|
476
|
+
r = p.add_run()
|
|
477
|
+
r.text = f"\n{self.get_label(q, 'author')}: "
|
|
478
|
+
r.font.bold = True
|
|
479
|
+
self.pptx_format(author_text, p, tf, slide)
|
|
480
|
+
|
|
481
|
+
def process_question(self, q):
|
|
482
|
+
if "number" not in q:
|
|
483
|
+
self.qcount += 1
|
|
484
|
+
if "setcounter" in q:
|
|
485
|
+
self.qcount = int(q["setcounter"])
|
|
486
|
+
self.number = str(self.qcount if "number" not in q else q["number"])
|
|
487
|
+
|
|
488
|
+
if isinstance(q["question"], list):
|
|
489
|
+
for i in range(len(q["question"][1])):
|
|
490
|
+
qn = copy.deepcopy(q)
|
|
491
|
+
qn["question"][1] = q["question"][1][: i + 1]
|
|
492
|
+
self.process_question_text(qn)
|
|
493
|
+
else:
|
|
494
|
+
self.process_question_text(q)
|
|
495
|
+
|
|
496
|
+
if self.c["add_plug"]:
|
|
497
|
+
slide = self.prs.slides.add_slide(self.BLANK_SLIDE)
|
|
498
|
+
self.set_question_number(slide, self.number)
|
|
499
|
+
self.add_answer_slide(q)
|
|
445
500
|
|
|
446
501
|
def determine_size(self, text, coeff=1):
|
|
447
502
|
text = self.recursive_join(text)
|
|
@@ -451,13 +506,16 @@ class PptxExporter(BaseExporter):
|
|
|
451
506
|
return element["size"]
|
|
452
507
|
return self.c["text_size_grid"]["smallest"]
|
|
453
508
|
|
|
454
|
-
def init_paragraph(self, text_frame, text=None, coeff=1):
|
|
509
|
+
def init_paragraph(self, text_frame, text=None, coeff=1, size=None):
|
|
455
510
|
p = text_frame.paragraphs[0]
|
|
456
511
|
p.font.name = self.c["font"]["name"]
|
|
457
|
-
size
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
512
|
+
if size:
|
|
513
|
+
_size = size
|
|
514
|
+
else:
|
|
515
|
+
_size = self.c["text_size_grid"]["default"]
|
|
516
|
+
if text:
|
|
517
|
+
_size = self.determine_size(text, coeff=coeff)
|
|
518
|
+
p.font.size = PptxPt(_size)
|
|
461
519
|
return p
|
|
462
520
|
|
|
463
521
|
def export(self, outfilename):
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.25.0b2"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.24.3"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|