pretext 2.41.2__tar.gz → 2.41.3.dev20260609094354__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 (67) hide show
  1. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/PKG-INFO +1 -1
  2. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/__init__.py +1 -1
  3. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/cli.py +56 -4
  4. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/core/common.py +18 -8
  5. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/core/webwork.py +1 -1
  6. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/project/__init__.py +15 -11
  7. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/resources/core.zip +0 -0
  8. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/resources/pelican.zip +0 -0
  9. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/resources/resource_hash_table.json +9 -0
  10. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/resources/rs_cache.zip +0 -0
  11. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/resources/templates.zip +0 -0
  12. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pyproject.toml +1 -1
  13. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/LICENSE +0 -0
  14. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/README.md +0 -0
  15. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/__main__.py +0 -0
  16. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/codechat.py +0 -0
  17. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/constants.py +0 -0
  18. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/core/__init__.py +0 -0
  19. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/core/braille_format.py +0 -0
  20. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/core/pretext.py +0 -0
  21. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/core/stack.py +0 -0
  22. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/logger.py +0 -0
  23. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Alignment.jinja2s +0 -0
  24. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Arrays.jinja2s +0 -0
  25. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Bibliography.jinja2s +0 -0
  26. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Boxes.jinja2s +0 -0
  27. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Breaking.jinja2s +0 -0
  28. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Crossref.jinja2s +0 -0
  29. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Floats.jinja2s +0 -0
  30. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/FontSelection.jinja2s +0 -0
  31. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Footnotes.jinja2s +0 -0
  32. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Index.jinja2s +0 -0
  33. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Lists.jinja2s +0 -0
  34. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Pictures.jinja2s +0 -0
  35. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Quotations.jinja2s +0 -0
  36. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Sectioning.jinja2s +0 -0
  37. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Sentences.jinja2s +0 -0
  38. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Space.jinja2s +0 -0
  39. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Tabbing.jinja2s +0 -0
  40. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Themes/__init__.py +0 -0
  41. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Themes/default/__init__.py +0 -0
  42. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Themes/default/default-layout.jinja2 +0 -0
  43. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Themes/default/document-layout.jinja2 +0 -0
  44. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Thms.jinja2s +0 -0
  45. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/Verbatim.jinja2s +0 -0
  46. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/__init__.py +0 -0
  47. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/babel.jinja2s +0 -0
  48. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/graphicx.jinja2s +0 -0
  49. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/hyperref.jinja2s +0 -0
  50. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/lipsum.jinja2s +0 -0
  51. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/longtable.jinja2s +0 -0
  52. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/math.jinja2s +0 -0
  53. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/misc.jinja2s +0 -0
  54. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/natbib.jinja2s +0 -0
  55. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/p.jinja2s +0 -0
  56. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/subfig.jinja2s +0 -0
  57. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/textcomp.jinja2s +0 -0
  58. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/tikzcd.jinja2 +0 -0
  59. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/tikzpicture.jinja2 +0 -0
  60. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/url.jinja2s +0 -0
  61. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/plastex/wrapfig.jinja2s +0 -0
  62. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/project/generate.py +0 -0
  63. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/project/xml.py +0 -0
  64. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/resources/__init__.py +0 -0
  65. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/server.py +0 -0
  66. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/types.py +0 -0
  67. {pretext-2.41.2 → pretext-2.41.3.dev20260609094354}/pretext/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pretext
3
- Version: 2.41.2
3
+ Version: 2.41.3.dev20260609094354
4
4
  Summary: A package to author, build, and deploy PreTeXt projects.
5
5
  Home-page: https://pretextbook.org
6
6
  License: GPL-3.0-or-later
@@ -19,7 +19,7 @@ from single_version import get_version
19
19
  VERSION = get_version("pretext", Path(__file__).parent.parent)
20
20
 
21
21
 
22
- CORE_COMMIT = "fc8221d5b8e7027f686729102e169c482fbd1fe5"
22
+ CORE_COMMIT = "ef5259cf8bcbd04278823139d9125d186aba7539"
23
23
 
24
24
 
25
25
  def activate() -> None:
@@ -80,9 +80,48 @@ def nice_errors(f: Callable[..., None]) -> Any:
80
80
 
81
81
  CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
82
82
 
83
+ _VERBOSITY_HELP = "Sets the severity of log messaging: DEBUG for all, INFO (default) for most, then WARNING, ERROR, and CRITICAL for decreasing verbosity."
84
+
85
+
86
+ def set_log_level(
87
+ _ctx: click.Context, _param: click.Parameter, value: Optional[str]
88
+ ) -> None:
89
+ _ = (_ctx, _param) # Click's callback protocol requires these; not used here.
90
+ if value:
91
+ log.setLevel(value.upper())
92
+
93
+
94
+ class PreTeXtGroup(click.Group):
95
+ """Click Group that injects a -v/--verbosity option into every subcommand so that
96
+ `pretext build -v debug` works in addition to the canonical `pretext -v debug build`.
97
+ """
98
+
99
+ def command(self, *args: Any, **kwargs: Any) -> Any:
100
+ original_decorator = super().command(*args, **kwargs)
101
+
102
+ def decorator(f: Callable[..., Any]) -> Any:
103
+ f = click.option(
104
+ "--verbosity",
105
+ "-v",
106
+ default=None,
107
+ expose_value=False,
108
+ is_eager=True,
109
+ callback=set_log_level,
110
+ type=click.Choice(
111
+ ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
112
+ case_sensitive=False,
113
+ ),
114
+ help=_VERBOSITY_HELP,
115
+ )(f)
116
+ return original_decorator(f)
117
+
118
+ return decorator
119
+
83
120
 
84
121
  # Click command-line interface
85
- @click.group(invoke_without_command=True, context_settings=CONTEXT_SETTINGS)
122
+ @click.group(
123
+ cls=PreTeXtGroup, invoke_without_command=True, context_settings=CONTEXT_SETTINGS
124
+ )
86
125
  @click.pass_context
87
126
  # Allow a verbosity command:
88
127
  @click_log.simple_verbosity_option(
@@ -96,8 +135,13 @@ CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
96
135
  is_flag=True,
97
136
  help='Display list of build/view "targets" available in the project manifest.',
98
137
  )
138
+ @click.option(
139
+ "--save-tmp-dirs",
140
+ is_flag=True,
141
+ help="Do not clean temporary directories after a build or generate. Might be useful for debugging (previously calling -v debug would also save these directories).",
142
+ )
99
143
  @nice_errors
100
- def main(ctx: click.Context, targets: bool) -> None:
144
+ def main(ctx: click.Context, targets: bool, save_tmp_dirs: bool) -> None:
101
145
  """
102
146
  Command line tools for quickly creating, authoring, and building PreTeXt projects.
103
147
 
@@ -177,7 +221,7 @@ def main(ctx: click.Context, targets: bool) -> None:
177
221
  f"No project.ptx manifest found in current workspace. Using global configuration specified in '~/.ptx/{VERSION}/project.ptx'."
178
222
  )
179
223
  # Add project to context so it can be used in subcommands
180
- ctx.obj = {"project": project}
224
+ ctx.obj = {"project": project, "save_tmp_dirs": save_tmp_dirs}
181
225
 
182
226
 
183
227
  @main.result_callback()
@@ -552,6 +596,7 @@ def build(
552
596
  # Create a new project, apply overlay, and get target. Note, the CLI always finds changes to the root folder of the project, so we don't need to specify a path to the project.ptx file.
553
597
  # Use the project discovered in the main command.
554
598
  project = ctx.obj["project"]
599
+ save_tmp_dirs = ctx.obj.get("save_tmp_dirs", False)
555
600
 
556
601
  # Check to see whether target_name is a path to a file:
557
602
  if target_name and Path(target_name).is_file():
@@ -620,7 +665,11 @@ def build(
620
665
  for t in targets:
621
666
  log.info(f"Generating assets for {t.name}")
622
667
  t.generate_assets(
623
- only_changed=False, xmlid=xmlid, clean=clean, skip_cache=True
668
+ only_changed=False,
669
+ xmlid=xmlid,
670
+ clean=clean,
671
+ skip_cache=True,
672
+ clean_tmp_dirs=not save_tmp_dirs,
624
673
  )
625
674
  no_generate = True
626
675
  except Exception as e:
@@ -645,6 +694,7 @@ def build(
645
694
  xmlid=xmlid,
646
695
  no_knowls=no_knowls,
647
696
  latex=latex,
697
+ clean_tmp_dirs=not save_tmp_dirs,
648
698
  )
649
699
  if t.format == "html" and t.compression is None:
650
700
  log.info(
@@ -761,6 +811,7 @@ def generate(
761
811
  return
762
812
 
763
813
  project = ctx.obj["project"]
814
+ save_tmp_dirs = ctx.obj.get("save_tmp_dirs", False)
764
815
  # Now create the target if the target_name is not missing.
765
816
  try:
766
817
  target = project.get_target(name=target_name)
@@ -780,6 +831,7 @@ def generate(
780
831
  clean=clean,
781
832
  skip_cache=force,
782
833
  slow=slow,
834
+ clean_tmp_dirs=not save_tmp_dirs,
783
835
  )
784
836
  # Check if there are errors reported by the build by looking at the error_flush_handler.
785
837
  if utils.has_errors(error_flush_handler):
@@ -533,18 +533,28 @@ def get_output_filename(xml, out_file, dest_dir, suffix):
533
533
  return os.path.join(dest_dir, derivedname)
534
534
 
535
535
 
536
- def release_temporary_directories():
537
- """Release scratch directories unless requesting debugging info"""
536
+ def release_temporary_directories(any_log_level):
537
+ """
538
+ Release scratch directories unless requesting debugging info
539
+ - any_log_level: can be set to True by an external tool to force cleanup even if log level is set to debug (log.level == 10)
540
+ """
538
541
 
539
542
  global __temps
540
543
 
541
544
  # log.level is 10 for debug, greater for all other levels.
542
- if log.level > 10:
543
- for td in __temps:
544
- log.info("Removing temporary directory {}".format(td))
545
- # conservatively, raise exception on errors
546
- shutil.rmtree(td, ignore_errors=False)
547
- # reset list of temp direcotries to empty, to avoid duplicate requests
545
+ if log.level > 10 or any_log_level:
546
+ try:
547
+ for td in __temps:
548
+ log.info("Removing temporary directory {}".format(td))
549
+ # let a removal failure raise, so it is caught and reported below
550
+ shutil.rmtree(td, ignore_errors=False)
551
+ log.debug("Removed temporary directory {}".format(td))
552
+ except Exception as e:
553
+ log.warning("Failed to remove temporary directories, starting with {} (and maybe some others): {}".format(td, str(e)))
554
+ finally:
555
+ # always empty the list, even if a removal raised partway, so a
556
+ # long-running caller (e.g. a server process) does not accumulate
557
+ # stale entries; this also avoids duplicate removal requests
548
558
  __temps = []
549
559
  else:
550
560
  log.debug("Temporary directories left behind for inspection: {}".format(__temps))
@@ -624,7 +624,7 @@ def webwork_to_xml(
624
624
  ww_image_path, ww_image_filename = os.path.split(ww_image_full_path)
625
625
  # split the filename into (name, extension). extension can be empty or like '.png'.
626
626
  ww_image_name, image_extension = os.path.splitext(ww_image_filename)
627
- # rename, eg, webwork-representations/webwork-5-image-3.png
627
+ # rename the image file to, e.g., webworkParentExerciseLabel-image-3.png
628
628
  ptx_image_name = problem + "-image-" + str(count)
629
629
  ptx_image_filename = ptx_image_name + image_extension
630
630
  if image_extension == ".tgz":
@@ -582,7 +582,7 @@ class Target(pxml.BaseXmlModel, tag="target", search_mode=SearchMode.UNORDERED):
582
582
  ) as f:
583
583
  json.dump(asset_table, f)
584
584
 
585
- def ensure_myopenmath_xml(self) -> None:
585
+ def ensure_myopenmath_xml(self, clean_tmp_dirs: bool = True) -> None:
586
586
  """
587
587
  Ensures that the myopenmath xml files are present if the source contains myopenmath exercises. Needed to generate other "static" assets and targets.
588
588
  """
@@ -607,14 +607,16 @@ class Target(pxml.BaseXmlModel, tag="target", search_mode=SearchMode.UNORDERED):
607
607
  f"MyOpenMath problem {prob_num} does not exist, generating"
608
608
  )
609
609
  self.generate_assets(
610
- requested_asset_types=["myopenmath"], only_changed=False
610
+ requested_asset_types=["myopenmath"],
611
+ only_changed=False,
612
+ clean_tmp_dirs=clean_tmp_dirs,
611
613
  )
612
614
  # Only need to generate once a single missing file is discovered.
613
615
  break
614
616
  else:
615
617
  log.debug("Source does not contain myopenmath problems")
616
618
 
617
- def ensure_webwork_reps(self) -> None:
619
+ def ensure_webwork_reps(self, clean_tmp_dirs: bool = True) -> None:
618
620
  """
619
621
  Ensures that the webwork representation file is present if the source contains webwork problems. This is needed to build or generate other assets.
620
622
  """
@@ -634,7 +636,9 @@ class Target(pxml.BaseXmlModel, tag="target", search_mode=SearchMode.UNORDERED):
634
636
  f'At least one WeBWorK representation file (for webwork problem with id "{id}") does not exist, generating'
635
637
  )
636
638
  self.generate_assets(
637
- requested_asset_types=["webwork"], only_changed=False
639
+ requested_asset_types=["webwork"],
640
+ only_changed=False,
641
+ clean_tmp_dirs=clean_tmp_dirs,
638
642
  )
639
643
  break
640
644
  else:
@@ -720,6 +724,7 @@ class Target(pxml.BaseXmlModel, tag="target", search_mode=SearchMode.UNORDERED):
720
724
  xmlid: t.Optional[str] = None,
721
725
  no_knowls: bool = False,
722
726
  latex: bool = False,
727
+ clean_tmp_dirs: bool = True,
723
728
  ) -> None:
724
729
  # Add cli.version to stringparams. Use only the major and minor version numbers.
725
730
  self.stringparams["cli.version"] = VERSION[: VERSION.rfind(".")]
@@ -744,11 +749,11 @@ class Target(pxml.BaseXmlModel, tag="target", search_mode=SearchMode.UNORDERED):
744
749
  self.ensure_asset_directories()
745
750
 
746
751
  # verify that a webwork_representations.xml file exists if it is needed; generated if needed.
747
- self.ensure_webwork_reps()
752
+ self.ensure_webwork_reps(clean_tmp_dirs=clean_tmp_dirs)
748
753
 
749
754
  # Generate needed assets unless requested not to.
750
755
  if generate:
751
- self.generate_assets(xmlid=xmlid)
756
+ self.generate_assets(xmlid=xmlid, clean_tmp_dirs=clean_tmp_dirs)
752
757
 
753
758
  # Ensure the output directories exist.
754
759
  self.ensure_output_directory()
@@ -936,7 +941,7 @@ class Target(pxml.BaseXmlModel, tag="target", search_mode=SearchMode.UNORDERED):
936
941
  log.critical(f"Unknown format {self.format}")
937
942
  # Delete temporary directories left behind by core:
938
943
  try:
939
- core.release_temporary_directories()
944
+ core.release_temporary_directories(any_log_level=clean_tmp_dirs)
940
945
  except Exception as e:
941
946
  log.error(
942
947
  "Unable to release temporary directories. Please report this error to pretext-support"
@@ -952,6 +957,7 @@ class Target(pxml.BaseXmlModel, tag="target", search_mode=SearchMode.UNORDERED):
952
957
  clean: bool = False,
953
958
  skip_cache: bool = False,
954
959
  slow: bool = False,
960
+ clean_tmp_dirs: bool = True,
955
961
  ) -> None:
956
962
  """
957
963
  Generates assets for the current target. Options:
@@ -1320,11 +1326,9 @@ class Target(pxml.BaseXmlModel, tag="target", search_mode=SearchMode.UNORDERED):
1320
1326
  # log.debug(e, exc_info=True)
1321
1327
  # Delete temporary directories left behind by core:
1322
1328
  try:
1323
- core.release_temporary_directories()
1329
+ core.release_temporary_directories(any_log_level=clean_tmp_dirs)
1324
1330
  except Exception as e:
1325
- log.error(
1326
- "Unable to release temporary directories. Please report this error to pretext-support"
1327
- )
1331
+ log.debug("Unable to release temporary directories.")
1328
1332
  log.debug(e, exc_info=True)
1329
1333
  # After all assets are generated, update the asset cache (but we shouldn't do this if we didn't generate any assets successfully)
1330
1334
  log.debug(f"Updated these assets successfully: {successful_assets}")
@@ -648,5 +648,14 @@
648
648
  "pretext-cli.yml": "709ecabfc8302bbdbbb9a06d10d8b9b6c3fd81c5ab2148d3e74d5f8fd60597f9",
649
649
  "pretext-deploy.yml": "133779603fcb4165d020fb473c6fe8b74d59b3ef9c556c17ec751321654cd111",
650
650
  "installPandoc.sh": "3ecee8f323703a5b249f7617abbca2c35db9a412471eaa91f5d51517bfc63aaf"
651
+ },
652
+ "2.41.3.dev20260609094354": {
653
+ "project.ptx": "a2c233b6d83e1e0e63b12325d731177b0f878580eb0bbcdaf766f7f0c7a6b634",
654
+ "codechat_config.yaml": "afcac12174cfff2eea97260a5aee54e6ebcf67dd357309db348557f9aed81554",
655
+ ".gitignore": "d63c34bdc2333143fb69f7c5d55212d07b3ce85c23ad37ee70476d99b9617721",
656
+ "devcontainer.json": "c5756c143f21bf44a9db4d51fb06bdc5f5d701967bbec510b99c0d98ea01a45b",
657
+ "pretext-cli.yml": "8a10efc684d81bf66eede76ea95ebb219aabd448602b0106dd7f17d3bdff2239",
658
+ "pretext-deploy.yml": "0ad3f9e428e9d25b22c7f1fe57cf49f5f092e079b46ac8fc4da1e6bd49f50028",
659
+ "installPandoc.sh": "2bbca356abefcbe9586cc3e3b5068d3fb41d4a1e2817e27cca6f30e2c3cb336e"
651
660
  }
652
661
  }
@@ -11,7 +11,7 @@
11
11
  # ----------------
12
12
  [tool.poetry]
13
13
  name = "pretext"
14
- version = "2.41.2"
14
+ version = "2.41.3.dev20260609094354"
15
15
  description = "A package to author, build, and deploy PreTeXt projects."
16
16
  readme = "README.md"
17
17
  homepage = "https://pretextbook.org"