pyDiffTools 0.1.48__tar.gz → 0.1.50__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 (123) hide show
  1. {pydifftools-0.1.48/pyDiffTools.egg-info → pydifftools-0.1.50}/PKG-INFO +16 -5
  2. {pydifftools-0.1.48 → pydifftools-0.1.50}/README.rst +15 -4
  3. {pydifftools-0.1.48 → pydifftools-0.1.50/pyDiffTools.egg-info}/PKG-INFO +16 -5
  4. {pydifftools-0.1.48 → pydifftools-0.1.50}/pyDiffTools.egg-info/SOURCES.txt +6 -0
  5. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/browser_lifecycle.py +60 -0
  6. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/command_line.py +35 -2
  7. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/command_registry.py +7 -0
  8. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/comment_tags.lua +10 -3
  9. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/comment_tags_margin.lua +10 -3
  10. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/comment_tags_no_comments.lua +10 -3
  11. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/comment_toggle.js +1 -1
  12. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/comments.css +5 -4
  13. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/continuous.py +161 -31
  14. pydifftools-0.1.50/pydifftools/flowchart/source_jump.js +158 -0
  15. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/flowchart/watch_graph.py +53 -3
  16. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/flowchart/wgrph_view.js +23 -0
  17. pydifftools-0.1.50/pydifftools/line_alignment.py +391 -0
  18. pydifftools-0.1.50/pydifftools/match_spaces.py +142 -0
  19. pydifftools-0.1.50/pydifftools/source_jump.py +128 -0
  20. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/wrap_sentences.py +80 -340
  21. pydifftools-0.1.50/pydifftools/wrapping_options.py +18 -0
  22. {pydifftools-0.1.48 → pydifftools-0.1.50}/pyproject.toml +2 -1
  23. pydifftools-0.1.50/tests/test_browser_lifecycle.py +171 -0
  24. {pydifftools-0.1.48 → pydifftools-0.1.50}/tests/test_command_line_help.py +126 -0
  25. {pydifftools-0.1.48 → pydifftools-0.1.50}/tests/test_continuous_shutdown.py +47 -17
  26. pydifftools-0.1.50/tests/test_line_alignment.py +131 -0
  27. pydifftools-0.1.50/tests/test_source_jump.py +85 -0
  28. {pydifftools-0.1.48 → pydifftools-0.1.50}/tests/test_wrap_check.py +305 -23
  29. {pydifftools-0.1.48 → pydifftools-0.1.50}/tests/test_wrapping.py +18 -2
  30. {pydifftools-0.1.48 → pydifftools-0.1.50}/tests/test_zotero.py +1 -1
  31. pydifftools-0.1.48/pydifftools/match_spaces.py +0 -380
  32. pydifftools-0.1.48/tests/test_browser_lifecycle.py +0 -30
  33. {pydifftools-0.1.48 → pydifftools-0.1.50}/LICENSE.md +0 -0
  34. {pydifftools-0.1.48 → pydifftools-0.1.50}/MANIFEST.in +0 -0
  35. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/_quarto.yml +0 -0
  36. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/__version__.txt +0 -0
  37. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/1a724af72b16f5a9e607e12b1c721645/base.ipynb +0 -0
  38. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/1b28fc9daac9081847e5161b2c546f8a/base.ipynb +0 -0
  39. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/231f64eee282fa225d1104935cf80a24/base.ipynb +0 -0
  40. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/26e56f6b0ff54851a45145157f2f0dc4/base.ipynb +0 -0
  41. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/311fabd7029ffd050d056e2f316eb50f/base.ipynb +0 -0
  42. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/57da2021e5b156ac3adf01398201c723/base.ipynb +0 -0
  43. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/62b24ea7da75011d92b0f8924faa208d/base.ipynb +0 -0
  44. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/7f1b20d69d889514ab5d1cc92e3cb14f/base.ipynb +0 -0
  45. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/86f74c8c54a87ff892d9b15dd714e8f0/base.ipynb +0 -0
  46. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/88893b4234eac2945d9d6cb2e277f186/base.ipynb +0 -0
  47. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/9a40046ada6f582ee34af00fbdbfb417/base.ipynb +0 -0
  48. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/a1bf4d270d0641ff41faf1d7cce3439a/base.ipynb +0 -0
  49. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/a3789f7d9585a781f2a1c60ce95ff10d/base.ipynb +0 -0
  50. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/be46ecba858d39ad5f0c46902ddf1c02/base.ipynb +0 -0
  51. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/d0cbc57a12f2ccce710a5afd04cc05e7/base.ipynb +0 -0
  52. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/d3e12d320b14228f701231ae32ddd7dd/base.ipynb +0 -0
  53. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/eb434f61555438d020a6970a5dbf9ee8/base.ipynb +0 -0
  54. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/f6b0e73aa7fa029134665d4dde57e096/base.ipynb +0 -0
  55. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/f719a6e4ff09873cb0ffb06ec9d232f9/base.ipynb +0 -0
  56. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/executed/feeee244a7ce3d60e1a227eb604df823/base.ipynb +0 -0
  57. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/.jupyter_cache/global.db +0 -0
  58. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/example.qmd +0 -0
  59. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/example.tex +0 -0
  60. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/index.qmd +0 -0
  61. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/subproject1/.jupyter_cache/__version__.txt +0 -0
  62. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/subproject1/.jupyter_cache/executed/ca90e4df5f4f0583df6554156a68dc7f/base.ipynb +0 -0
  63. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/subproject1/.jupyter_cache/global.db +0 -0
  64. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/subproject1/end_vs_he_sketch.jpg +0 -0
  65. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/subproject1/independent.qmd +0 -0
  66. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/subproject1/index.qmd +0 -0
  67. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/subproject1/tasks.qmd +0 -0
  68. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/subproject1/test_include.qmd +0 -0
  69. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/subproject1/tryforerror.qmd +0 -0
  70. {pydifftools-0.1.48 → pydifftools-0.1.50}/example_notebook/project1/test_include.qmd +0 -0
  71. {pydifftools-0.1.48 → pydifftools-0.1.50}/pyDiffTools.egg-info/dependency_links.txt +0 -0
  72. {pydifftools-0.1.48 → pydifftools-0.1.50}/pyDiffTools.egg-info/entry_points.txt +0 -0
  73. {pydifftools-0.1.48 → pydifftools-0.1.50}/pyDiffTools.egg-info/requires.txt +0 -0
  74. {pydifftools-0.1.48 → pydifftools-0.1.50}/pyDiffTools.egg-info/top_level.txt +0 -0
  75. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/__init__.py +0 -0
  76. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/bibliography.py +0 -0
  77. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/check_numbers.py +0 -0
  78. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/citation_dialog.py +0 -0
  79. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/comment_functions.py +0 -0
  80. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/comment_migration.py +0 -0
  81. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/comments_author_colors.css +0 -0
  82. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/copy_files.py +0 -0
  83. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/diff-doc.js +0 -0
  84. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/doc_contents.py +0 -0
  85. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/flowchart/__init__.py +0 -0
  86. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/flowchart/comparison.py +0 -0
  87. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/flowchart/dot_to_yaml.py +0 -0
  88. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/flowchart/graph.py +0 -0
  89. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/flowchart/svg-pan-zoom.min.js +0 -0
  90. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/forward_search.py +0 -0
  91. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/git_gd.py +0 -0
  92. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/git_gd_history.py +0 -0
  93. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/git_gd_image.py +0 -0
  94. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/git_gd_qt.py +0 -0
  95. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/html_comments.py +0 -0
  96. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/html_uncomments.py +0 -0
  97. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/log_example.py +0 -0
  98. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/notebook/__init__.py +0 -0
  99. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/notebook/display.py +0 -0
  100. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/notebook/fast_build.py +0 -0
  101. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/notebook/tex_to_qmd.py +0 -0
  102. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/onewordify.py +0 -0
  103. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/onewordify_undo.py +0 -0
  104. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/outline.py +0 -0
  105. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/rearrange_tex.py +0 -0
  106. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/searchacro.py +0 -0
  107. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/separate_comments.py +0 -0
  108. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/split_conflict.py +0 -0
  109. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/unseparate_comments.py +0 -0
  110. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/update_check.py +0 -0
  111. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/xml2xlsx.vbs +0 -0
  112. {pydifftools-0.1.48 → pydifftools-0.1.50}/pydifftools/zotero.py +0 -0
  113. {pydifftools-0.1.48 → pydifftools-0.1.50}/setup.cfg +0 -0
  114. {pydifftools-0.1.48 → pydifftools-0.1.50}/tests/test_bibliography.py +0 -0
  115. {pydifftools-0.1.48 → pydifftools-0.1.50}/tests/test_check_single_use.py +0 -0
  116. {pydifftools-0.1.48 → pydifftools-0.1.50}/tests/test_comment_migration.py +0 -0
  117. {pydifftools-0.1.48 → pydifftools-0.1.50}/tests/test_forward_search.py +0 -0
  118. {pydifftools-0.1.48 → pydifftools-0.1.50}/tests/test_git_gd_history.py +0 -0
  119. {pydifftools-0.1.48 → pydifftools-0.1.50}/tests/test_git_gd_image.py +0 -0
  120. {pydifftools-0.1.48 → pydifftools-0.1.50}/tests/test_git_gd_qt.py +0 -0
  121. {pydifftools-0.1.48 → pydifftools-0.1.50}/tests/test_rrng.py +0 -0
  122. {pydifftools-0.1.48 → pydifftools-0.1.50}/tests/test_tex_to_qmd.py +0 -0
  123. {pydifftools-0.1.48 → pydifftools-0.1.50}/tests/test_update_check.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyDiffTools
3
- Version: 0.1.48
3
+ Version: 0.1.50
4
4
  Summary: Diff tools
5
5
  Author: J M Franck
6
6
  License: Copyright (c) 2015, jmfranck
@@ -215,10 +215,21 @@ included are (listed in order of fun/utility):
215
215
 
216
216
  * this allows you to use an original file with good whitespace formatting as a "template" that you can match other (e.g. pandoc converted file) onto another
217
217
 
218
- * changed prose lines exceeding 1.5 times the nearby reference width are
219
- wrapped using the same sentence and punctuation rules as ``wr``.
220
- Existing surrounding line breaks are retained; the fallback width is
221
- 80 columns when the reference provides too little prose.
218
+ * ``cpb`` and ``wmatch`` share a matcher that finds changed hunks, aligns
219
+ their words using Git's minimal diff, and restores reference whitespace.
220
+ It then considers extra breaks that preserve an unchanged reference line
221
+ without stranding a tiny edited fragment, and checks wrapping rules.
222
+
223
+ * ``--wrapnumber`` sets the maximum width (79 for ``cpb`` and ``wmatch``).
224
+ Wmatch also uses nearby reference widths for large edits, retaining
225
+ unchanged reference lines and protected Markdown blocks.
226
+
227
+ * ``--trailing-dependent-phrase`` defaults to 20: a clause boundary within
228
+ 20 characters of the maximum width must end the line, even when its
229
+ trailing phrase would still fit. Commas, semicolons, colons, parentheses,
230
+ dashes, and inline-math boundaries are supported. Set it to 0 to disable
231
+ this rule. The option is shared by ``cpb``, ``wmatch``, ``wr`` and
232
+ ``wrchk``; ``--punctuation-slop`` remains an alias.
222
233
 
223
234
  - `pydifft wd` ("word diff"): generate "track changes" word files starting from pandoc markdown in a git history. Assuming that you have copied diff-doc.js (copied + licensed from elsewhere) into your home directory, this will use pandoc to convert the markdown files to MS Word, then use the MS Word comparison tool to generate a document where all relevant changes are shown with "track changes."
224
235
 
@@ -160,10 +160,21 @@ included are (listed in order of fun/utility):
160
160
 
161
161
  * this allows you to use an original file with good whitespace formatting as a "template" that you can match other (e.g. pandoc converted file) onto another
162
162
 
163
- * changed prose lines exceeding 1.5 times the nearby reference width are
164
- wrapped using the same sentence and punctuation rules as ``wr``.
165
- Existing surrounding line breaks are retained; the fallback width is
166
- 80 columns when the reference provides too little prose.
163
+ * ``cpb`` and ``wmatch`` share a matcher that finds changed hunks, aligns
164
+ their words using Git's minimal diff, and restores reference whitespace.
165
+ It then considers extra breaks that preserve an unchanged reference line
166
+ without stranding a tiny edited fragment, and checks wrapping rules.
167
+
168
+ * ``--wrapnumber`` sets the maximum width (79 for ``cpb`` and ``wmatch``).
169
+ Wmatch also uses nearby reference widths for large edits, retaining
170
+ unchanged reference lines and protected Markdown blocks.
171
+
172
+ * ``--trailing-dependent-phrase`` defaults to 20: a clause boundary within
173
+ 20 characters of the maximum width must end the line, even when its
174
+ trailing phrase would still fit. Commas, semicolons, colons, parentheses,
175
+ dashes, and inline-math boundaries are supported. Set it to 0 to disable
176
+ this rule. The option is shared by ``cpb``, ``wmatch``, ``wr`` and
177
+ ``wrchk``; ``--punctuation-slop`` remains an alias.
167
178
 
168
179
  - `pydifft wd` ("word diff"): generate "track changes" word files starting from pandoc markdown in a git history. Assuming that you have copied diff-doc.js (copied + licensed from elsewhere) into your home directory, this will use pandoc to convert the markdown files to MS Word, then use the MS Word comparison tool to generate a document where all relevant changes are shown with "track changes."
169
180
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyDiffTools
3
- Version: 0.1.48
3
+ Version: 0.1.50
4
4
  Summary: Diff tools
5
5
  Author: J M Franck
6
6
  License: Copyright (c) 2015, jmfranck
@@ -215,10 +215,21 @@ included are (listed in order of fun/utility):
215
215
 
216
216
  * this allows you to use an original file with good whitespace formatting as a "template" that you can match other (e.g. pandoc converted file) onto another
217
217
 
218
- * changed prose lines exceeding 1.5 times the nearby reference width are
219
- wrapped using the same sentence and punctuation rules as ``wr``.
220
- Existing surrounding line breaks are retained; the fallback width is
221
- 80 columns when the reference provides too little prose.
218
+ * ``cpb`` and ``wmatch`` share a matcher that finds changed hunks, aligns
219
+ their words using Git's minimal diff, and restores reference whitespace.
220
+ It then considers extra breaks that preserve an unchanged reference line
221
+ without stranding a tiny edited fragment, and checks wrapping rules.
222
+
223
+ * ``--wrapnumber`` sets the maximum width (79 for ``cpb`` and ``wmatch``).
224
+ Wmatch also uses nearby reference widths for large edits, retaining
225
+ unchanged reference lines and protected Markdown blocks.
226
+
227
+ * ``--trailing-dependent-phrase`` defaults to 20: a clause boundary within
228
+ 20 characters of the maximum width must end the line, even when its
229
+ trailing phrase would still fit. Commas, semicolons, colons, parentheses,
230
+ dashes, and inline-math boundaries are supported. Set it to 0 to disable
231
+ this rule. The option is shared by ``cpb``, ``wmatch``, ``wr`` and
232
+ ``wrchk``; ``--punctuation-slop`` remains an alias.
222
233
 
223
234
  - `pydifft wd` ("word diff"): generate "track changes" word files starting from pandoc markdown in a git history. Assuming that you have copied diff-doc.js (copied + licensed from elsewhere) into your home directory, this will use pandoc to convert the markdown files to MS Word, then use the MS Word comparison tool to generate a document where all relevant changes are shown with "track changes."
224
235
 
@@ -70,6 +70,7 @@ pydifftools/git_gd_image.py
70
70
  pydifftools/git_gd_qt.py
71
71
  pydifftools/html_comments.py
72
72
  pydifftools/html_uncomments.py
73
+ pydifftools/line_alignment.py
73
74
  pydifftools/log_example.py
74
75
  pydifftools/match_spaces.py
75
76
  pydifftools/onewordify.py
@@ -78,16 +79,19 @@ pydifftools/outline.py
78
79
  pydifftools/rearrange_tex.py
79
80
  pydifftools/searchacro.py
80
81
  pydifftools/separate_comments.py
82
+ pydifftools/source_jump.py
81
83
  pydifftools/split_conflict.py
82
84
  pydifftools/unseparate_comments.py
83
85
  pydifftools/update_check.py
84
86
  pydifftools/wrap_sentences.py
87
+ pydifftools/wrapping_options.py
85
88
  pydifftools/xml2xlsx.vbs
86
89
  pydifftools/zotero.py
87
90
  pydifftools/flowchart/__init__.py
88
91
  pydifftools/flowchart/comparison.py
89
92
  pydifftools/flowchart/dot_to_yaml.py
90
93
  pydifftools/flowchart/graph.py
94
+ pydifftools/flowchart/source_jump.js
91
95
  pydifftools/flowchart/svg-pan-zoom.min.js
92
96
  pydifftools/flowchart/watch_graph.py
93
97
  pydifftools/flowchart/wgrph_view.js
@@ -105,7 +109,9 @@ tests/test_forward_search.py
105
109
  tests/test_git_gd_history.py
106
110
  tests/test_git_gd_image.py
107
111
  tests/test_git_gd_qt.py
112
+ tests/test_line_alignment.py
108
113
  tests/test_rrng.py
114
+ tests/test_source_jump.py
109
115
  tests/test_tex_to_qmd.py
110
116
  tests/test_update_check.py
111
117
  tests/test_wrap_check.py
@@ -1,12 +1,72 @@
1
1
  import os
2
+ import re
2
3
  import shutil
3
4
  import subprocess
5
+ import sys
4
6
 
5
7
  # callbacks that run before any dialog needs the user; cpb registers one
6
8
  # that closes its live preview, so issues are dealt with before it reopens
7
9
  dialog_callbacks = []
8
10
 
9
11
 
12
+ def launch_chrome(webdriver, **kwargs):
13
+ """Start Chrome, retrying version mismatches with a warning."""
14
+ from selenium.common.exceptions import SessionNotCreatedException
15
+ from selenium.webdriver.chrome.service import Service
16
+
17
+ try:
18
+ return webdriver.Chrome(**kwargs)
19
+ except SessionNotCreatedException as exc:
20
+ # {{{ Retry only ChromeDriver's explicit browser-version rejection
21
+ details = str(exc)
22
+ driver_match = re.search(
23
+ r"ChromeDriver only supports Chrome version (\d+)", details
24
+ )
25
+ browser_match = re.search(
26
+ r"Current browser version is (\d+)", details
27
+ )
28
+ if driver_match is None or browser_match is None:
29
+ raise
30
+ print(
31
+ "pydifft: warning: ChromeDriver "
32
+ f"{driver_match.group(1)} and Chrome {browser_match.group(1)} "
33
+ "do not match; retrying with the driver version check disabled.",
34
+ file=sys.stderr,
35
+ )
36
+ service = kwargs.get("service")
37
+ kwargs["service"] = Service(
38
+ executable_path=service.path if service else None,
39
+ service_args=[
40
+ *(service.service_args if service else []),
41
+ "--disable-build-check",
42
+ ],
43
+ )
44
+ return webdriver.Chrome(**kwargs)
45
+ # }}}
46
+
47
+
48
+ def start_chrome():
49
+ """Use an installed driver without an online Selenium Manager lookup."""
50
+ # Keep Selenium imports lazy, as in the watch commands.
51
+ from selenium import webdriver
52
+ from selenium.webdriver.chrome.service import Service
53
+
54
+ driver_path = shutil.which("chromedriver")
55
+ if driver_path:
56
+ options = webdriver.ChromeOptions()
57
+ # Debian's driver defaults to Chromium even if Chrome is installed;
58
+ # retain Selenium Manager's preference for Google Chrome.
59
+ browser_path = shutil.which("google-chrome") or shutil.which(
60
+ "google-chrome-stable"
61
+ )
62
+ if browser_path:
63
+ options.binary_location = browser_path
64
+ return launch_chrome(
65
+ webdriver, service=Service(driver_path), options=options
66
+ )
67
+ return launch_chrome(webdriver)
68
+
69
+
10
70
  def prepare_for_dialog():
11
71
  """Let watch commands close their preview before a dialog appears."""
12
72
  for callback in list(dialog_callbacks):
@@ -11,6 +11,7 @@ import nbformat
11
11
  import difflib
12
12
  import shutil
13
13
  import importlib.util
14
+ import importlib.metadata
14
15
  from pathlib import Path
15
16
  from . import (
16
17
  match_spaces,
@@ -46,6 +47,9 @@ from .notebook.fast_build import (
46
47
  )
47
48
 
48
49
  from .command_registry import _COMMAND_SPECS, register_command
50
+ from .wrapping_options import (
51
+ DEFAULT_WIDTH, DEFAULT_TRAILING_DEPENDENT_PHRASE, WRAPPING_ARGUMENTS,
52
+ )
49
53
 
50
54
  _ARGCOMPLETE_SPEC = importlib.util.find_spec("argcomplete")
51
55
  if (
@@ -366,9 +370,19 @@ def gvr(arguments):
366
370
  @register_command(
367
371
  "match whitespace",
368
372
  filename_extensions={"arguments": [".md", ".tex"]},
373
+ argument_options={
374
+ **WRAPPING_ARGUMENTS,
375
+ "arguments": {
376
+ "nargs": 2, "metavar": ("REFERENCE", "FILE"),
377
+ "help": "Reference file and current file to reflow.",
378
+ },
379
+ },
369
380
  )
370
- def wmatch(arguments):
371
- match_spaces.run(arguments)
381
+ def wmatch(
382
+ arguments, wrapnumber=DEFAULT_WIDTH,
383
+ trailing_dependent_phrase=DEFAULT_TRAILING_DEPENDENT_PHRASE,
384
+ ):
385
+ match_spaces.run(arguments, wrapnumber, trailing_dependent_phrase)
372
386
 
373
387
 
374
388
  @register_command("split conflict")
@@ -879,6 +893,12 @@ def build_parser():
879
893
  formatter_class=argparse.RawDescriptionHelpFormatter,
880
894
  is_root_parser=True,
881
895
  )
896
+ parser.add_argument(
897
+ "--ver",
898
+ "--version",
899
+ action="version",
900
+ version=importlib.metadata.version("pyDiffTools"),
901
+ )
882
902
  parser.epilog = _subcommand_help_hint(parser.prog)
883
903
  parser._pydifft_subparsers = {}
884
904
  subparsers = parser.add_subparsers(dest="command")
@@ -913,6 +933,9 @@ def build_parser():
913
933
  def main(argv=None):
914
934
  if argv is None:
915
935
  argv = sys.argv[1:]
936
+ if argv and argv[0] in ("--ver", "--version"):
937
+ build_parser().parse_args(argv)
938
+ return
916
939
  # Run the PyPI update check once per UTC day so users see a notice but
917
940
  # startup stays fast when offline. The date is stored in the
918
941
  # PYDIFFTOOLS_UPDATE_CHECK_LAST_RAN_UTC_DATE environment variable.
@@ -959,6 +982,16 @@ def main(argv=None):
959
982
  parser._pydifft_subparsers[subcommand].print_help()
960
983
  return
961
984
  namespace = parser.parse_args(argv)
985
+ # Shared wrapping arguments are validated identically for each command.
986
+ if hasattr(namespace, "wrapnumber") and namespace.wrapnumber < 1:
987
+ parser._pydifft_subparsers[namespace.command].error(
988
+ "--wrapnumber must be at least 1"
989
+ )
990
+ if getattr(namespace, "trailing_dependent_phrase",
991
+ getattr(namespace, "punctuation_slop", 0)) < 0:
992
+ parser._pydifft_subparsers[namespace.command].error(
993
+ "--trailing-dependent-phrase must be nonnegative"
994
+ )
962
995
  if (
963
996
  namespace.command == "cpb"
964
997
  and namespace.comments_to_margin
@@ -15,6 +15,7 @@ def register_command(
15
15
  description=None,
16
16
  help=None,
17
17
  filename_extensions=None,
18
+ argument_options=None,
18
19
  ):
19
20
  """Register a command handler for the CLI dispatcher."""
20
21
 
@@ -108,6 +109,12 @@ def register_command(
108
109
  kwargs["type"] = type(parameter.default)
109
110
  if parameter.name in argument_help:
110
111
  kwargs["help"] = argument_help[parameter.name].strip()
112
+ if argument_options is not None:
113
+ kwargs.update(argument_options.get(parameter.name, {}))
114
+ override_flags = kwargs.pop("flags", None)
115
+ if override_flags is not None:
116
+ flags = override_flags
117
+ kwargs["dest"] = parameter.name
111
118
  argument_spec = {"flags": flags, "kwargs": kwargs}
112
119
  if parameter.name in completion_allowednames:
113
120
  argument_spec["completion_allowednames"] = (
@@ -237,9 +237,13 @@ local function detect_block_opener(block)
237
237
  end
238
238
 
239
239
  if para_like_t(block) then
240
- for k, opener_spec in pairs(OPENERS) do
241
- local found, before, after = split_inline_block_at_tag(block, k)
242
- if found then
240
+ -- Scan the paragraph once, regardless of the number of authors.
241
+ local content = block.content
242
+ for index = 1, #content do
243
+ local tag = raw_inline_html(content[index])
244
+ local opener_spec = tag and OPENERS[tag] or nil
245
+ if opener_spec then
246
+ local _, before, after = split_inline_block_at_tag(block, tag)
243
247
  return opener_spec, before, after
244
248
  end
245
249
  end
@@ -452,3 +456,6 @@ function Pandoc(doc)
452
456
  end
453
457
  return doc:walk({ Inlines = Inlines, Blocks = Blocks, Div = Div })
454
458
  end
459
+
460
+ -- Initialize authors before walking comments, without an implicit first walk.
461
+ return {{ Pandoc = Pandoc }}
@@ -273,9 +273,13 @@ local function detect_block_opener(block)
273
273
  end
274
274
 
275
275
  if para_like_t(block) then
276
- for k, opener_spec in pairs(OPENERS) do
277
- local found, before, after = split_inline_block_at_tag(block, k)
278
- if found then
276
+ -- Scan the paragraph once, regardless of the number of authors.
277
+ local content = block.content
278
+ for index = 1, #content do
279
+ local tag = raw_inline_html(content[index])
280
+ local opener_spec = tag and OPENERS[tag] or nil
281
+ if opener_spec then
282
+ local _, before, after = split_inline_block_at_tag(block, tag)
279
283
  return opener_spec, before, after
280
284
  end
281
285
  end
@@ -487,3 +491,6 @@ function Pandoc(doc)
487
491
  end
488
492
  return doc:walk({ Inlines = Inlines, Blocks = Blocks, Div = Div })
489
493
  end
494
+
495
+ -- Initialize authors before walking comments, without an implicit first walk.
496
+ return {{ Pandoc = Pandoc }}
@@ -166,9 +166,13 @@ local function detect_block_opener(block)
166
166
  end
167
167
 
168
168
  if para_like_t(block) then
169
- for k, opener_spec in pairs(OPENERS) do
170
- local found, before, after = split_inline_block_at_tag(block, k)
171
- if found then
169
+ -- Scan the paragraph once, regardless of the number of authors.
170
+ local content = block.content
171
+ for index = 1, #content do
172
+ local tag = raw_inline_html(content[index])
173
+ local opener_spec = tag and OPENERS[tag] or nil
174
+ if opener_spec then
175
+ local _, before, after = split_inline_block_at_tag(block, tag)
172
176
  return opener_spec, before, after
173
177
  end
174
178
  end
@@ -348,3 +352,6 @@ function Pandoc(doc)
348
352
  end
349
353
  return doc:walk({ Inlines = Inlines, Blocks = Blocks, Div = Div })
350
354
  end
355
+
356
+ -- Initialize authors before walking comments, without an implicit first walk.
357
+ return {{ Pandoc = Pandoc }}
@@ -34,7 +34,7 @@
34
34
  }
35
35
 
36
36
  function positionComments() {
37
- const useMobileFlow = window.matchMedia("(max-width: 900px)").matches;
37
+ const useMobileFlow = window.matchMedia("(max-width: 600px)").matches;
38
38
  // Inline comment bubbles are absolutely positioned relative to a zero-width
39
39
  // pin. We nudge overlapping bubbles so adjacent <comment> tags visibly
40
40
  // separate, and we raise the bubbles so the pointer aims at the source point.
@@ -4,9 +4,10 @@ html {
4
4
  }
5
5
  body {
6
6
  margin: 0 auto;
7
- max-width: 36em;
8
- padding-left: 50px;
9
- padding-right: 50px;
7
+ /* Keep 75% of the previous side margins and give the rest to the text. */
8
+ max-width: calc(27em + 25%);
9
+ padding-left: 37.5px;
10
+ padding-right: 37.5px;
10
11
  padding-top: 50px;
11
12
  padding-bottom: 50px;
12
13
  hyphens: auto;
@@ -311,7 +312,7 @@ span.comment-pin > span.comment-left::after {
311
312
  }
312
313
 
313
314
  /* ---------- Mobile fallback ---------- */
314
- @media (max-width: 900px) {
315
+ @media (max-width: 600px) {
315
316
  div.comment-right,
316
317
  div.comment-left,
317
318
  span.comment-pin > span.comment-right,