djlint 1.30.0 → 1.30.2

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 (368) hide show
  1. package/package.json +3 -2
  2. package/.coveragerc +0 -9
  3. package/.editorconfig +0 -21
  4. package/.flake8 +0 -0
  5. package/.github/FUNDING.yml +0 -2
  6. package/.github/ISSUE_TEMPLATE/config.yml +0 -6
  7. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -19
  8. package/.github/ISSUE_TEMPLATE/formatter_but_report.md +0 -30
  9. package/.github/ISSUE_TEMPLATE/linter_bug_report.md +0 -34
  10. package/.github/ISSUE_TEMPLATE/translation.md +0 -14
  11. package/.github/config.yml +0 -4
  12. package/.github/pull_request_template.md +0 -10
  13. package/.github/workflows/cancel.yml +0 -17
  14. package/.github/workflows/demo.yml +0 -98
  15. package/.github/workflows/issues.yml +0 -23
  16. package/.github/workflows/linkcheck.yaml +0 -21
  17. package/.github/workflows/lint.yml +0 -25
  18. package/.github/workflows/release.yml +0 -57
  19. package/.github/workflows/test.yml +0 -85
  20. package/.pre-commit-config.yaml +0 -45
  21. package/.pre-commit-hooks.yaml +0 -71
  22. package/.prettierignore +0 -7
  23. package/.prettierrc +0 -11
  24. package/.releaserc +0 -16
  25. package/CHANGELOG.md +0 -13
  26. package/MANIFEST.in +0 -2
  27. package/build_demo.sh +0 -17
  28. package/docs/.eleventy.js +0 -425
  29. package/docs/.eleventyignore +0 -2
  30. package/docs/.prettierignore +0 -3
  31. package/docs/.prettierrc +0 -11
  32. package/docs/package.json +0 -73
  33. package/docs/readme.md +0 -17
  34. package/docs/src/_data/configuration.json +0 -646
  35. package/docs/src/_data/eleventyComputed.js +0 -22
  36. package/docs/src/_data/i18n/index.js +0 -159
  37. package/docs/src/_data/js.js +0 -7
  38. package/docs/src/_data/locales.js +0 -17
  39. package/docs/src/_data/site.json +0 -8
  40. package/docs/src/_includes/demo.njk +0 -157
  41. package/docs/src/_includes/docs_layout.njk +0 -34
  42. package/docs/src/_includes/foot.njk +0 -26
  43. package/docs/src/_includes/index.njk +0 -187
  44. package/docs/src/_includes/languages_layout.njk +0 -11
  45. package/docs/src/_includes/layout.njk +0 -111
  46. package/docs/src/_includes/nav.njk +0 -85
  47. package/docs/src/_utils/minify-html.js +0 -14
  48. package/docs/src/_utils/rollupper.js +0 -91
  49. package/docs/src/_utils/scripts.11ty.js +0 -27
  50. package/docs/src/demo.njk +0 -4
  51. package/docs/src/docs/best-practices.md +0 -78
  52. package/docs/src/docs/changelog.md +0 -452
  53. package/docs/src/docs/configuration.md +0 -145
  54. package/docs/src/docs/docs.json +0 -4
  55. package/docs/src/docs/formatter.md +0 -82
  56. package/docs/src/docs/getting-started.md +0 -126
  57. package/docs/src/docs/ignoring-code.md +0 -75
  58. package/docs/src/docs/integrations.md +0 -120
  59. package/docs/src/docs/languages/angular.md +0 -31
  60. package/docs/src/docs/languages/django.md +0 -40
  61. package/docs/src/docs/languages/golang.md +0 -31
  62. package/docs/src/docs/languages/handlebars.md +0 -31
  63. package/docs/src/docs/languages/jinja.md +0 -39
  64. package/docs/src/docs/languages/languages.json +0 -3
  65. package/docs/src/docs/languages/mustache.md +0 -31
  66. package/docs/src/docs/languages/nunjucks.md +0 -39
  67. package/docs/src/docs/languages/twig.md +0 -41
  68. package/docs/src/docs/linter.md +0 -199
  69. package/docs/src/fr/demo.njk +0 -4
  70. package/docs/src/fr/docs/best-practices.md +0 -78
  71. package/docs/src/fr/docs/changelog.md +0 -452
  72. package/docs/src/fr/docs/configuration.md +0 -144
  73. package/docs/src/fr/docs/docs.json +0 -3
  74. package/docs/src/fr/docs/formatter.md +0 -83
  75. package/docs/src/fr/docs/getting-started.md +0 -127
  76. package/docs/src/fr/docs/ignoring-code.md +0 -75
  77. package/docs/src/fr/docs/integrations.md +0 -100
  78. package/docs/src/fr/docs/languages/angular.md +0 -31
  79. package/docs/src/fr/docs/languages/django.md +0 -31
  80. package/docs/src/fr/docs/languages/golang.md +0 -31
  81. package/docs/src/fr/docs/languages/handlebars.md +0 -31
  82. package/docs/src/fr/docs/languages/jinja.md +0 -31
  83. package/docs/src/fr/docs/languages/languages.json +0 -3
  84. package/docs/src/fr/docs/languages/mustache.md +0 -31
  85. package/docs/src/fr/docs/languages/nunjucks.md +0 -31
  86. package/docs/src/fr/docs/languages/twig.md +0 -31
  87. package/docs/src/fr/docs/linter.md +0 -207
  88. package/docs/src/fr/fr.json +0 -4
  89. package/docs/src/fr/index.njk +0 -4
  90. package/docs/src/index.njk +0 -4
  91. package/docs/src/lib/generate-content-hash.js +0 -13
  92. package/docs/src/robots.txt +0 -4
  93. package/docs/src/ru/demo.njk +0 -4
  94. package/docs/src/ru/docs/best-practices.md +0 -78
  95. package/docs/src/ru/docs/changelog.md +0 -453
  96. package/docs/src/ru/docs/configuration.md +0 -142
  97. package/docs/src/ru/docs/docs.json +0 -3
  98. package/docs/src/ru/docs/formatter.md +0 -82
  99. package/docs/src/ru/docs/getting-started.md +0 -127
  100. package/docs/src/ru/docs/ignoring-code.md +0 -75
  101. package/docs/src/ru/docs/integrations.md +0 -100
  102. package/docs/src/ru/docs/languages/angular.md +0 -31
  103. package/docs/src/ru/docs/languages/django.md +0 -31
  104. package/docs/src/ru/docs/languages/golang.md +0 -31
  105. package/docs/src/ru/docs/languages/handlebars.md +0 -31
  106. package/docs/src/ru/docs/languages/jinja.md +0 -31
  107. package/docs/src/ru/docs/languages/languages.json +0 -3
  108. package/docs/src/ru/docs/languages/mustache.md +0 -31
  109. package/docs/src/ru/docs/languages/nunjucks.md +0 -31
  110. package/docs/src/ru/docs/languages/twig.md +0 -31
  111. package/docs/src/ru/docs/linter.md +0 -126
  112. package/docs/src/ru/index.njk +0 -4
  113. package/docs/src/ru/ru.json +0 -4
  114. package/docs/src/sitemap.njk +0 -16
  115. package/docs/src/static/css/site.scss +0 -467
  116. package/docs/src/static/font/fontawesome/stylesheet.scss +0 -78
  117. package/docs/src/static/img/apple-touch-icon.png +0 -0
  118. package/docs/src/static/img/demo-min.gif +0 -0
  119. package/docs/src/static/img/demo.gif +0 -0
  120. package/docs/src/static/img/demo.webm +0 -0
  121. package/docs/src/static/img/favicon-16x16.png +0 -0
  122. package/docs/src/static/img/favicon-32x32.png +0 -0
  123. package/docs/src/static/img/favicon.ico +0 -0
  124. package/docs/src/static/img/icon-square.indd +0 -0
  125. package/docs/src/static/img/icon-square.png +0 -0
  126. package/docs/src/static/img/icon.png +0 -0
  127. package/docs/src/static/img/logo-192x192.png +0 -0
  128. package/docs/src/static/img/logo-512x512.png +0 -0
  129. package/docs/src/static/img/logos/angular.png +0 -0
  130. package/docs/src/static/img/logos/django.png +0 -0
  131. package/docs/src/static/img/logos/golang.png +0 -0
  132. package/docs/src/static/img/logos/handlebars.png +0 -0
  133. package/docs/src/static/img/logos/jinja.png +0 -0
  134. package/docs/src/static/img/logos/mustache.png +0 -0
  135. package/docs/src/static/img/logos/nunjucks.png +0 -0
  136. package/docs/src/static/img/logos/twig.png +0 -0
  137. package/docs/src/static/img/old_demo.gif +0 -0
  138. package/docs/src/static/img/style.css +0 -122
  139. package/docs/src/static/js/animate.js +0 -69
  140. package/docs/src/static/js/editor.js +0 -171
  141. package/docs/src/static/js/hamburger.js +0 -19
  142. package/docs/src/static/js/modal.js +0 -47
  143. package/docs/src/static/js/worker.js +0 -142
  144. package/docs/src/static/py/EditorConfig-99-py3-none-any.whl +0 -0
  145. package/docs/src/static/py/PyYAML-99-py3-none-any.whl +0 -0
  146. package/docs/src/static/py/click-99-py3-none-any.whl +0 -0
  147. package/docs/src/static/py/colorama-99-py3-none-any.whl +0 -0
  148. package/docs/src/static/py/cssbeautifier-99-py3-none-any.whl +0 -0
  149. package/docs/src/static/py/djlint-99-py3-none-any.whl +0 -0
  150. package/docs/src/static/py/html_tag_names-99-py3-none-any.whl +0 -0
  151. package/docs/src/static/py/html_void_elements-99-py3-none-any.whl +0 -0
  152. package/docs/src/static/py/jsbeautifier-99-py3-none-any.whl +0 -0
  153. package/docs/src/static/py/json5-99-py3-none-any.whl +0 -0
  154. package/docs/src/static/py/pathspec-99-py3-none-any.whl +0 -0
  155. package/docs/src/static/py/regex-2023.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +0 -0
  156. package/docs/src/static/py/six-1.16.0-py2.py3-none-any.whl +0 -0
  157. package/docs/src/static/py/tomli-2.0.1-py3-none-any.whl +0 -0
  158. package/docs/src/static/py/tqdm-4.65.0-py3-none-any.whl +0 -0
  159. package/icon.xcf +0 -0
  160. package/poetry.lock +0 -835
  161. package/pyproject.toml +0 -100
  162. package/renovate.json +0 -44
  163. package/scripts/updateVersion.js +0 -16
  164. package/src/djlint/__init__.py +0 -451
  165. package/src/djlint/__main__.py +0 -4
  166. package/src/djlint/formatter/__init__.py +0 -1
  167. package/src/djlint/formatter/attributes.py +0 -212
  168. package/src/djlint/formatter/compress.py +0 -64
  169. package/src/djlint/formatter/condense.py +0 -221
  170. package/src/djlint/formatter/css.py +0 -60
  171. package/src/djlint/formatter/expand.py +0 -111
  172. package/src/djlint/formatter/indent.py +0 -418
  173. package/src/djlint/formatter/js.py +0 -58
  174. package/src/djlint/helpers.py +0 -321
  175. package/src/djlint/lint.py +0 -128
  176. package/src/djlint/output.py +0 -220
  177. package/src/djlint/reformat.py +0 -63
  178. package/src/djlint/rules/H025.py +0 -65
  179. package/src/djlint/rules.yaml +0 -279
  180. package/src/djlint/settings.py +0 -969
  181. package/src/djlint/src.py +0 -91
  182. package/tests/__init__.py +0 -0
  183. package/tests/conftest.py +0 -239
  184. package/tests/test_cli.py +0 -71
  185. package/tests/test_config/__init__.py +0 -0
  186. package/tests/test_config/test_blank_line_after_tag.py +0 -135
  187. package/tests/test_config/test_blank_line_before_tag.py +0 -141
  188. package/tests/test_config/test_close_void_tags.py +0 -31
  189. package/tests/test_config/test_custom_blocks.py +0 -56
  190. package/tests/test_config/test_custom_html.py +0 -45
  191. package/tests/test_config/test_djlintrc/.djlintrc +0 -38
  192. package/tests/test_config/test_djlintrc/__init__.py +0 -0
  193. package/tests/test_config/test_djlintrc/test_config.py +0 -44
  194. package/tests/test_config/test_djlintrc_custom/.djlint-cust +0 -38
  195. package/tests/test_config/test_djlintrc_custom/.djlintrc +0 -2
  196. package/tests/test_config/test_djlintrc_custom/__init__.py +0 -0
  197. package/tests/test_config/test_djlintrc_custom/test_config.py +0 -48
  198. package/tests/test_config/test_excludes/__init__.py +0 -0
  199. package/tests/test_config/test_excludes/excluded.html +0 -1
  200. package/tests/test_config/test_excludes/foo/excluded.html +0 -1
  201. package/tests/test_config/test_excludes/html.html +0 -1
  202. package/tests/test_config/test_excludes/pyproject.toml +0 -3
  203. package/tests/test_config/test_excludes/test_config.py +0 -30
  204. package/tests/test_config/test_extension/__init__.py +0 -0
  205. package/tests/test_config/test_extension/html.test +0 -1
  206. package/tests/test_config/test_extension/pyproject.toml +0 -3
  207. package/tests/test_config/test_extension/test_config.py +0 -27
  208. package/tests/test_config/test_files/.djlintrc_global +0 -9
  209. package/tests/test_config/test_files/test.html +0 -3
  210. package/tests/test_config/test_files/test_config.py +0 -123
  211. package/tests/test_config/test_files/test_two.html +0 -1
  212. package/tests/test_config/test_format_attribute_template_tags.py +0 -280
  213. package/tests/test_config/test_format_css.py +0 -197
  214. package/tests/test_config/test_format_js.py +0 -220
  215. package/tests/test_config/test_gitignore/__init__.py +0 -0
  216. package/tests/test_config/test_gitignore/html_one.html +0 -1
  217. package/tests/test_config/test_gitignore/html_two.html +0 -1
  218. package/tests/test_config/test_gitignore/test_config.py +0 -142
  219. package/tests/test_config/test_ignore/__init__.py +0 -0
  220. package/tests/test_config/test_ignore/html.html +0 -1
  221. package/tests/test_config/test_ignore/html_two.html +0 -12
  222. package/tests/test_config/test_ignore/pyproject.toml +0 -3
  223. package/tests/test_config/test_ignore/test_config.py +0 -32
  224. package/tests/test_config/test_ignore_blocks.py +0 -45
  225. package/tests/test_config/test_ignore_case.py +0 -39
  226. package/tests/test_config/test_indent.py +0 -63
  227. package/tests/test_config/test_linter_output_format/__init__.py +0 -0
  228. package/tests/test_config/test_linter_output_format/html-one.html +0 -1
  229. package/tests/test_config/test_linter_output_format/html-two.html +0 -1
  230. package/tests/test_config/test_linter_output_format/pyproject.toml +0 -3
  231. package/tests/test_config/test_linter_output_format/test_config.py +0 -34
  232. package/tests/test_config/test_max_attribute_length.py +0 -100
  233. package/tests/test_config/test_max_line_length.py +0 -94
  234. package/tests/test_config/test_per_file_ignores/__init__.py +0 -0
  235. package/tests/test_config/test_per_file_ignores/html.html +0 -2
  236. package/tests/test_config/test_per_file_ignores/pyproject.toml +0 -2
  237. package/tests/test_config/test_per_file_ignores/test_config.py +0 -25
  238. package/tests/test_config/test_pragmas/__init__.py +0 -0
  239. package/tests/test_config/test_pragmas/html_five.html +0 -2
  240. package/tests/test_config/test_pragmas/html_four.html +0 -5
  241. package/tests/test_config/test_pragmas/html_one.html +0 -1
  242. package/tests/test_config/test_pragmas/html_six.html +0 -2
  243. package/tests/test_config/test_pragmas/html_three.html +0 -4
  244. package/tests/test_config/test_pragmas/html_two.html +0 -2
  245. package/tests/test_config/test_pragmas/pyproject.toml +0 -3
  246. package/tests/test_config/test_pragmas/test_config.py +0 -142
  247. package/tests/test_config/test_preserve_blank_lines.py +0 -109
  248. package/tests/test_config/test_preserve_leading_space.py +0 -159
  249. package/tests/test_config/test_profile/__init__.py +0 -0
  250. package/tests/test_config/test_profile/html.html +0 -2
  251. package/tests/test_config/test_profile/pyproject.toml +0 -3
  252. package/tests/test_config/test_profile/test_config.py +0 -64
  253. package/tests/test_config/test_pyproject/__init__.py +0 -0
  254. package/tests/test_config/test_pyproject/blank.html +0 -0
  255. package/tests/test_config/test_pyproject/pyproject.toml +0 -36
  256. package/tests/test_config/test_pyproject/test_config.py +0 -44
  257. package/tests/test_django/__init__.py +0 -0
  258. package/tests/test_django/test_asset.py +0 -32
  259. package/tests/test_django/test_autoescape.py +0 -25
  260. package/tests/test_django/test_block.py +0 -29
  261. package/tests/test_django/test_blocktrans.py +0 -236
  262. package/tests/test_django/test_blocktrans_trimmed.py +0 -283
  263. package/tests/test_django/test_comments.py +0 -164
  264. package/tests/test_django/test_filter.py +0 -30
  265. package/tests/test_django/test_for.py +0 -34
  266. package/tests/test_django/test_if.py +0 -34
  267. package/tests/test_django/test_ifchanged.py +0 -37
  268. package/tests/test_django/test_include.py +0 -24
  269. package/tests/test_django/test_load.py +0 -24
  270. package/tests/test_django/test_quoted.py +0 -34
  271. package/tests/test_django/test_spaceless.py +0 -30
  272. package/tests/test_django/test_tag_spaces.py +0 -35
  273. package/tests/test_django/test_templatetag.py +0 -40
  274. package/tests/test_django/test_verbatim.py +0 -24
  275. package/tests/test_django/test_with.py +0 -32
  276. package/tests/test_djlint/-.html +0 -1
  277. package/tests/test_djlint/__init__.py +0 -0
  278. package/tests/test_djlint/bad.html +0 -6
  279. package/tests/test_djlint/bad.html.dj +0 -23
  280. package/tests/test_djlint/bad.html.dj2 +0 -2
  281. package/tests/test_djlint/multiple_files/a/a.html +0 -1
  282. package/tests/test_djlint/multiple_files/b/b1.html +0 -1
  283. package/tests/test_djlint/multiple_files/b/b2.html +0 -1
  284. package/tests/test_djlint/test_djlint.py +0 -242
  285. package/tests/test_golang/__init__.py +0 -0
  286. package/tests/test_golang/test_if.py +0 -24
  287. package/tests/test_golang/test_range.py +0 -24
  288. package/tests/test_handlebars/__init__.py +0 -0
  289. package/tests/test_handlebars/test_each.py +0 -34
  290. package/tests/test_handlebars/test_else.py +0 -24
  291. package/tests/test_handlebars/test_with.py +0 -24
  292. package/tests/test_html/__init__.py +0 -0
  293. package/tests/test_html/test_alpinejs.py +0 -65
  294. package/tests/test_html/test_attributes.py +0 -935
  295. package/tests/test_html/test_aurelia.py +0 -24
  296. package/tests/test_html/test_basics.py +0 -905
  297. package/tests/test_html/test_bracket_same_line.py +0 -177
  298. package/tests/test_html/test_case.py +0 -81
  299. package/tests/test_html/test_cdata.py +0 -34
  300. package/tests/test_html/test_comments.py +0 -333
  301. package/tests/test_html/test_css.py +0 -193
  302. package/tests/test_html/test_doctype_declarations.py +0 -202
  303. package/tests/test_html/test_ignored.py +0 -193
  304. package/tests/test_html/test_interpolation.py +0 -56
  305. package/tests/test_html/test_line_break_after_multiline_tag.py +0 -95
  306. package/tests/test_html/test_next_line_empty.py +0 -53
  307. package/tests/test_html/test_selfclosing.py +0 -55
  308. package/tests/test_html/test_single_attribute_per_line.py +0 -87
  309. package/tests/test_html/test_srcset.py +0 -43
  310. package/tests/test_html/test_svg.py +0 -104
  311. package/tests/test_html/test_symbol_entities.py +0 -34
  312. package/tests/test_html/test_tag_code.py +0 -24
  313. package/tests/test_html/test_tag_dd.py +0 -24
  314. package/tests/test_html/test_tag_details_summary.py +0 -24
  315. package/tests/test_html/test_tag_dt.py +0 -24
  316. package/tests/test_html/test_tag_fig_caption.py +0 -29
  317. package/tests/test_html/test_tag_hr.py +0 -29
  318. package/tests/test_html/test_tag_picture.py +0 -32
  319. package/tests/test_html/test_tag_pre.py +0 -45
  320. package/tests/test_html/test_tag_script.py +0 -516
  321. package/tests/test_html/test_tag_small.py +0 -24
  322. package/tests/test_html/test_tag_span.py +0 -119
  323. package/tests/test_html/test_tag_textarea.py +0 -82
  324. package/tests/test_html/test_tags.py +0 -842
  325. package/tests/test_html/test_text.py +0 -34
  326. package/tests/test_html/test_whitespace.py +0 -477
  327. package/tests/test_html/test_yaml.py +0 -156
  328. package/tests/test_jinja/__init__.py +0 -0
  329. package/tests/test_jinja/test_call.py +0 -34
  330. package/tests/test_jinja/test_parenthesis.py +0 -24
  331. package/tests/test_linter/__init__.py +0 -0
  332. package/tests/test_linter/test_custom_rules/.djlint_rules.yaml +0 -6
  333. package/tests/test_linter/test_custom_rules/__init__.py +0 -0
  334. package/tests/test_linter/test_custom_rules/html.html +0 -1
  335. package/tests/test_linter/test_custom_rules/pyproject.toml +0 -1
  336. package/tests/test_linter/test_custom_rules/test_linter.py +0 -29
  337. package/tests/test_linter/test_custom_rules_bad/.djlint_rules.yaml +0 -24
  338. package/tests/test_linter/test_custom_rules_bad/__init__.py +0 -0
  339. package/tests/test_linter/test_custom_rules_bad/html.html +0 -1
  340. package/tests/test_linter/test_custom_rules_bad/pyproject.toml +0 -1
  341. package/tests/test_linter/test_custom_rules_bad/test_linter.py +0 -29
  342. package/tests/test_linter/test_django_linter.py +0 -476
  343. package/tests/test_linter/test_h005.py +0 -45
  344. package/tests/test_linter/test_h006.py +0 -81
  345. package/tests/test_linter/test_h007.py +0 -45
  346. package/tests/test_linter/test_h008.py +0 -60
  347. package/tests/test_linter/test_h009.py +0 -45
  348. package/tests/test_linter/test_h010.py +0 -44
  349. package/tests/test_linter/test_h037.py +0 -150
  350. package/tests/test_linter/test_ignore_rules.py +0 -45
  351. package/tests/test_linter/test_jinja_linter.py +0 -227
  352. package/tests/test_linter/test_linter.py +0 -691
  353. package/tests/test_linter/test_nunjucks_linter.py +0 -59
  354. package/tests/test_linter/test_python_module_rules/.djlint_rules.yaml +0 -4
  355. package/tests/test_linter/test_python_module_rules/__init__.py +0 -0
  356. package/tests/test_linter/test_python_module_rules/html_bad.html +0 -3
  357. package/tests/test_linter/test_python_module_rules/html_ok.html +0 -3
  358. package/tests/test_linter/test_python_module_rules/my_module.py +0 -32
  359. package/tests/test_linter/test_python_module_rules/pyproject.toml +0 -1
  360. package/tests/test_linter/test_python_module_rules/test_linter.py +0 -26
  361. package/tests/test_nunjucks/__init__.py +0 -0
  362. package/tests/test_nunjucks/test_functions.py +0 -94
  363. package/tests/test_nunjucks/test_macros.py +0 -41
  364. package/tests/test_nunjucks/test_set.py +0 -206
  365. package/tests/test_nunjucks/test_spaceless.py +0 -24
  366. package/tests/test_twig/__init__.py +0 -0
  367. package/tests/test_twig/test_comments.py +0 -51
  368. package/tox.ini +0 -48
@@ -1,212 +0,0 @@
1
- """Format attributes."""
2
-
3
- from functools import partial
4
-
5
- import regex as re
6
-
7
- from ..helpers import child_of_ignored_block
8
- from ..settings import Config
9
-
10
-
11
- def format_template_tags(config: Config, attributes: str, spacing: int) -> str:
12
- """Format template tags in attributes."""
13
- # find break tags, add breaks + indent
14
- # find unindent lines and move back
15
- # put short stuff back on one line
16
-
17
- def add_indentation(config: Config, attributes: str, spacing: int) -> str:
18
- """Indent template tags.
19
-
20
- | <form class="this"
21
- | ----- attribute name
22
- |
23
- | <form class="this"
24
- |---^ leading space
25
- |
26
- | <form class="this"
27
- | ^----^ base indent
28
- |
29
- """
30
- indent = 0
31
- indented = ""
32
- indent_adder = spacing or 0
33
-
34
- for line_number, line in enumerate(attributes.splitlines()):
35
- # when checking for template tag, use "match" to force start of line check.
36
- if re.match(
37
- re.compile(config.template_unindent, re.I | re.X), line.strip()
38
- ):
39
- indent = indent - 1
40
- tmp = (indent * config.indent) + (indent_adder * " ") + line.strip()
41
-
42
- elif re.match(
43
- re.compile(config.tag_unindent_line, re.I | re.X), line.strip()
44
- ):
45
- # if we are leaving an indented group, then remove the indent_adder
46
- tmp = (
47
- max(indent - 1, 0) * config.indent
48
- + indent_adder * " "
49
- + line.strip()
50
- )
51
-
52
- elif re.search(
53
- re.compile(config.template_indent, re.I | re.X), line.strip()
54
- ) and not re.search(
55
- re.compile(config.template_unindent, re.I | re.X), line.strip()
56
- ):
57
- # for open tags, search, but then check that they are not closed.
58
- tmp = (indent * config.indent) + (indent_adder * " ") + line.strip()
59
- indent = indent + 1
60
-
61
- else:
62
- tmp = (indent * config.indent) + (indent_adder * " ") + line.strip()
63
-
64
- if line_number == 0:
65
- # don't touch first line
66
- indented += line.strip()
67
- elif tmp.strip():
68
- indented += f"\n{tmp}"
69
-
70
- return indented
71
-
72
- def add_break(pattern: str, match: re.Match) -> str:
73
- """Make a decision if a break should be added."""
74
- if pattern == "before":
75
- return f"\n{match.group()}"
76
-
77
- return f"{match.group(1)}\n{match.group(2).strip()}"
78
-
79
- break_char = config.break_before
80
-
81
- func = partial(add_break, "before")
82
-
83
- attributes = re.sub(
84
- re.compile(
85
- break_char
86
- + r".\K((?:{%|{{\#)[ ]*?(?:"
87
- + config.break_template_tags
88
- + ")[^}]+?[%|}]})",
89
- flags=re.IGNORECASE | re.MULTILINE | re.VERBOSE,
90
- ),
91
- func,
92
- attributes,
93
- )
94
-
95
- func = partial(add_break, "after")
96
- # break after
97
- attributes = re.sub(
98
- re.compile(
99
- r"((?:{%|{{\#)[ ]*?(?:"
100
- + config.break_template_tags
101
- + ")[^}]+?[%|}]})([^\n]+)$",
102
- flags=re.IGNORECASE | re.MULTILINE | re.VERBOSE,
103
- ),
104
- func,
105
- attributes,
106
- )
107
- attributes = add_indentation(config, attributes, spacing)
108
-
109
- return attributes
110
-
111
-
112
- def format_attributes(config: Config, html: str, match: re.match) -> str:
113
- """Spread long attributes over multiple lines."""
114
- # check that we are not inside an ignored block
115
- if (
116
- child_of_ignored_block(config, html, match)
117
- or len(match.group(3).strip()) < config.max_attribute_length
118
- ):
119
- return match.group()
120
-
121
- leading_space = match.group(1)
122
-
123
- tag = match.group(2) + " "
124
-
125
- spacing = leading_space + len(tag) * " "
126
-
127
- attributes = []
128
-
129
- # format attributes as groups
130
- for attr_grp in re.finditer(
131
- config.attribute_pattern, match.group(3).strip(), re.VERBOSE
132
- ):
133
- attrib_name = attr_grp.group(1)
134
- is_quoted = attr_grp.group(2) and attr_grp.group(2)[0] in ["'", '"']
135
- quote = attr_grp.group(2)[0] if is_quoted else '"'
136
-
137
- attrib_value = None
138
-
139
- if attr_grp.group(2) and attr_grp.group(2)[0] == attr_grp.group(2)[-1]:
140
- if attr_grp.group(2)[0] == "'":
141
- attrib_value = attr_grp.group(2).strip("'")
142
-
143
- elif attr_grp.group(2)[0] == '"':
144
- attrib_value = attr_grp.group(2).strip('"')
145
-
146
- else:
147
- attrib_value = attr_grp.group(2)
148
- else:
149
- attrib_value = attr_grp.group(2)
150
-
151
- standalone = attr_grp.group(3)
152
-
153
- quote_length = 1
154
-
155
- if attrib_name and attrib_value:
156
- # for the equals sign
157
- quote_length += 1
158
-
159
- if config.format_attribute_template_tags:
160
- join_space = "\n" + spacing
161
- else:
162
- join_space = (
163
- "\n" + spacing + int(quote_length + len(attrib_name or "")) * " "
164
- )
165
-
166
- # format style attribute
167
- if attrib_name and attrib_name.lower() == "style":
168
- attrib_value = (";" + join_space).join(
169
- [value.strip() for value in attrib_value.split(";") if value.strip()]
170
- )
171
-
172
- elif attrib_name and attrib_name.lower() in ["srcset", "data-srcset", "sizes"]:
173
- # vw
174
- attrib_value = ("w," + join_space).join(
175
- [value.strip() for value in attrib_value.split("w,") if value.strip()]
176
- )
177
- # px
178
- attrib_value = ("x," + join_space).join(
179
- [value.strip() for value in attrib_value.split("x,") if value.strip()]
180
- )
181
-
182
- # format template stuff
183
- if config.format_attribute_template_tags:
184
- if attrib_value and attrib_name not in config.ignored_attributes:
185
- attrib_value = format_template_tags(
186
- config,
187
- attrib_value,
188
- int(len(spacing) + len(attrib_name or "") + quote_length),
189
- )
190
-
191
- if standalone:
192
- standalone = format_template_tags(
193
- config, standalone, int(len(spacing) + len(attrib_name or ""))
194
- )
195
-
196
- if attrib_name and attrib_value or is_quoted:
197
- attrib_value = attrib_value or ""
198
- attributes.append(f"{attrib_name}={quote}{attrib_value}{quote}")
199
- else:
200
- attributes.append(
201
- (attrib_name or "") + (attrib_value or "") + (standalone or "")
202
- )
203
- attribute_string = ("\n" + spacing).join([x for x in attributes if x])
204
-
205
- close = match.group(4)
206
-
207
- attribute_string = f"{leading_space}{tag}{attribute_string}{close}"
208
-
209
- # clean trailing spaces added by breaks
210
- attribute_string = "\n".join([x.rstrip() for x in attribute_string.splitlines()])
211
-
212
- return f"{attribute_string}"
@@ -1,64 +0,0 @@
1
- """Compress html.
2
-
3
- 1. flatten attributes
4
- """
5
-
6
- import regex as re
7
- from HtmlTagNames import html_tag_names
8
- from HtmlVoidElements import html_void_elements
9
-
10
- from ..helpers import child_of_unformatted_block
11
- from ..settings import Config
12
-
13
-
14
- def compress_html(html: str, config: Config) -> str:
15
- """Compress html."""
16
-
17
- def _fix_case(tag):
18
- if config.ignore_case is False and tag.lower() in html_tag_names:
19
- return tag.lower()
20
-
21
- if config.ignore_case is False and tag.lower() == "doctype":
22
- return "DOCTYPE"
23
- return tag
24
-
25
- def _clean_tag(match: re.Match) -> str:
26
- """Flatten multiline attributes back to one line.
27
-
28
- Skip when attribute is ignored.
29
- Attribute name can be in group one or group 2.
30
- for now, skipping if they are anywhere
31
-
32
- tags starting ignored blocks can have their attributes formatted,
33
- for example <textarea class="..." id="..."> can be formatted.
34
- """
35
- if child_of_unformatted_block(config, html, match):
36
- return match.group()
37
-
38
- open_braket = match.group(1)
39
- tag = _fix_case(match.group(2))
40
-
41
- attributes = (
42
- (" " + " ".join(x.strip() for x in match.group(3).strip().splitlines()))
43
- if match.group(3)
44
- else ""
45
- )
46
- if tag.lower() in html_void_elements and config.close_void_tags:
47
- close_braket = " />"
48
- else:
49
- close_braket = (
50
- match.group(4) if "/" not in match.group(4) else f" {match.group(4)}"
51
- )
52
-
53
- return f"{open_braket}{tag}{attributes}{close_braket}"
54
-
55
- html = re.sub(
56
- re.compile(
57
- config.html_tag_regex,
58
- flags=re.MULTILINE | re.VERBOSE | re.IGNORECASE,
59
- ),
60
- _clean_tag,
61
- html,
62
- )
63
-
64
- return html
@@ -1,221 +0,0 @@
1
- """Condense HTML.
2
-
3
- 1. Put short html tags back on one line
4
- 2. Put short template tags back on one line
5
- """
6
-
7
- from functools import partial
8
-
9
- import regex as re
10
-
11
- from ..helpers import (
12
- inside_ignored_block,
13
- inside_protected_trans_block,
14
- is_safe_closing_tag,
15
- )
16
- from ..settings import Config
17
-
18
-
19
- def clean_whitespace(html: str, config: Config) -> str:
20
- """Compress back tags that do not need to be expanded."""
21
- # put empty tags on one line
22
-
23
- def strip_space(config: Config, html: str, match: re.Match) -> str:
24
- """Trim leading whitespace."""
25
- # either inside a block, or this is a newline + closing block tag.
26
- # if it is a newline + closing block we can format it.
27
-
28
- if inside_ignored_block(config, html, match) and not is_safe_closing_tag(
29
- config, match.group()
30
- ):
31
- return match.group()
32
-
33
- # trimmed blocks should not be here.
34
- # we need to full html to check what type of
35
- # opening block it was - trimmed or not trimmed
36
- if inside_protected_trans_block(config, html[: match.end()], match):
37
- return match.group().rstrip()
38
-
39
- return match.group(1)
40
-
41
- func = partial(strip_space, config, html)
42
-
43
- line_contents = r"(.*?)"
44
- trailing_contents = r"\n \t"
45
-
46
- if config.preserve_blank_lines:
47
- line_contents = r"([^\n]+?)"
48
- trailing_contents = r" \t"
49
-
50
- if not config.preserve_leading_space:
51
- # remove any leading/trailing space
52
- html = re.sub(
53
- re.compile(rf"^[ \t]*{line_contents}[{trailing_contents}]*$", re.M),
54
- func,
55
- html,
56
- )
57
-
58
- else:
59
- # only remove leading space in front of tags
60
- # <, {%
61
- html = re.sub(
62
- re.compile(rf"^[ \t]*((?:<|{{%).*?)[{trailing_contents}]*$", re.M),
63
- func,
64
- html,
65
- )
66
- html = re.sub(
67
- re.compile(rf"^{line_contents}[{trailing_contents}]*$", re.M), func, html
68
- )
69
-
70
- def add_blank_line_after(config: Config, html: str, match: re.Match) -> str:
71
- """Add break after if not in ignored block."""
72
- if inside_ignored_block(config, html, match):
73
- return match.group()
74
-
75
- # check that next line is not blank.
76
- if html[match.end() : match.end() + 1] != "\n": # noqa:E203
77
- return match.group() + "\n"
78
-
79
- return match.group()
80
-
81
- func = partial(add_blank_line_after, config, html)
82
-
83
- # should we add blank lines after load tags?
84
- if config.blank_line_after_tag:
85
- for tag in [x.strip() for x in config.blank_line_after_tag.split(",")]:
86
- html = re.sub(
87
- re.compile(
88
- rf"((?:{{%\s*?{tag}\b[^}}]+?%}}\n?)+)",
89
- re.IGNORECASE | re.MULTILINE | re.DOTALL,
90
- ),
91
- func,
92
- html,
93
- )
94
-
95
- def add_blank_line_before(config: Config, html: str, match: re.Match) -> str:
96
- """Add break before if not in ignored block and not first line in file."""
97
- if inside_ignored_block(config, html, match) or match.start() == 0:
98
- return match.group()
99
-
100
- return "\n" + match.group()
101
-
102
- func = partial(add_blank_line_before, config, html)
103
-
104
- # should we add blank lines before load tags?
105
- if config.blank_line_before_tag:
106
- for tag in [x.strip() for x in config.blank_line_before_tag.split(",")]:
107
- html = re.sub(
108
- re.compile(
109
- rf"(?<!^\n)((?:{{%\s*?{tag}\b[^}}]+?%}}\n?)+)",
110
- re.IGNORECASE | re.MULTILINE | re.DOTALL,
111
- ),
112
- func,
113
- html,
114
- )
115
-
116
- # add line after yaml front matter
117
-
118
- def yaml_add_blank_line_after(html: str, match: re.Match) -> str:
119
- """Add break after if not in ignored block."""
120
- if match.start() == 0 and not html.startswith("\n\n", match.end()):
121
- # verify there are not already blank lines
122
- return match.group() + "\n"
123
-
124
- return match.group()
125
-
126
- if config.no_line_after_yaml is False:
127
- func = partial(yaml_add_blank_line_after, html)
128
- html = re.sub(
129
- re.compile(
130
- r"(^---.+?---)$",
131
- re.MULTILINE | re.DOTALL,
132
- ),
133
- func,
134
- html,
135
- )
136
-
137
- return html
138
-
139
-
140
- def condense_html(html, config):
141
- """Put short tags back on a single line."""
142
- if config.preserve_leading_space:
143
- # if a user is attempting to reuse any leading
144
- # space for other purposes, we should not try to remove it.
145
- return html
146
-
147
- def condense_line(config: Config, html: str, match: re.Match) -> str:
148
- """Put contents on a single line if below max line length."""
149
- # match.group(1) contains the opening tag, which may be split over multiple lines
150
- if config.line_break_after_multiline_tag:
151
- combined_length = len(match.group(1) + match.group(3) + match.group(4))
152
- else:
153
- combined_length = len(
154
- match.group(1).splitlines()[-1] + match.group(3) + match.group(4)
155
- )
156
-
157
- if (
158
- not inside_ignored_block(config, html, match)
159
- and combined_length < config.max_line_length
160
- and if_blank_line_after_match(config, match.group(3))
161
- and if_blank_line_before_match(config, match.group(3))
162
- ):
163
- return match.group(1) + match.group(3) + match.group(4)
164
-
165
- return match.group()
166
-
167
- def if_blank_line_after_match(config: Config, html: str) -> bool:
168
- """Check if there should be a blank line after."""
169
- if config.blank_line_after_tag:
170
- return not any(
171
- re.findall(
172
- re.compile(
173
- rf"((?:{{%\s*?{tag}[^}}]+?%}}\n?)+)",
174
- re.IGNORECASE | re.MULTILINE | re.DOTALL,
175
- ),
176
- html,
177
- )
178
- for tag in [x.strip() for x in config.blank_line_after_tag.split(",")]
179
- )
180
- return True
181
-
182
- def if_blank_line_before_match(config: Config, html: str) -> bool:
183
- """Check if there should be a blank line before."""
184
- if config.blank_line_before_tag:
185
- return not any(
186
- re.findall(
187
- re.compile(
188
- rf"((?:{{%\s*?{tag}[^}}]+?%}}\n?)+)",
189
- re.IGNORECASE | re.MULTILINE | re.DOTALL,
190
- ),
191
- html,
192
- )
193
- for tag in [x.strip() for x in config.blank_line_before_tag.split(",")]
194
- )
195
- return True
196
-
197
- # add blank lines before tags
198
- func = partial(condense_line, config, html)
199
-
200
- # put short single line tags on one line
201
- html = re.sub(
202
- re.compile(
203
- rf"(<({config.optional_single_line_html_tags})\b(?:\"[^\"]*\"|'[^']*'|{{[^}}]*}}|[^'\">{{}}])*>)\s*([^<\n]*?)\s*?(</(\2)>)",
204
- re.IGNORECASE | re.MULTILINE | re.DOTALL | re.VERBOSE,
205
- ),
206
- func,
207
- html,
208
- )
209
-
210
- # put short template tags back on one line. must have leading space
211
- # jinja +%} and {%+ intentionally omitted.
212
- html = re.sub(
213
- re.compile(
214
- rf"((?:\s|^){{%-?[ ]*?({config.optional_single_line_template_tags})(?:(?!\n|%}}).)*?%}})\s*([^%\n]*?)\s*?({{%-?[ ]+?end(\2)[ ]*?%}})",
215
- flags=re.IGNORECASE | re.MULTILINE | re.VERBOSE,
216
- ),
217
- func,
218
- html,
219
- )
220
-
221
- return html
@@ -1,60 +0,0 @@
1
- """djLint function to call cssbeautifier."""
2
- from functools import partial
3
-
4
- import cssbeautifier
5
- import regex as re
6
- from jsbeautifier.javascript.options import BeautifierOptions
7
-
8
- from ..helpers import child_of_unformatted_block
9
- from ..settings import Config
10
-
11
-
12
- def format_css(html: str, config: Config) -> str:
13
- """Format css inside <style> tags."""
14
-
15
- def launch_formatter(config: Config, html: str, match: re.Match) -> str:
16
- """Add break after if not in ignored block."""
17
- if child_of_unformatted_block(config, html, match):
18
- return match.group()
19
-
20
- if not match.group(3).strip():
21
- return match.group()
22
-
23
- indent = len(match.group(1)) * " "
24
-
25
- # because of the param options for js-beautifier we cannot pass
26
- # in a fixed space leading.
27
- # so, call formatter twice, once with a fake indent.
28
- # check which lines changed (these are the formattable lines)
29
- # and add the leading space to them.
30
-
31
- config.css_config["indent_level"] = 1
32
- opts = BeautifierOptions(config.css_config)
33
- beautified_lines = cssbeautifier.beautify(match.group(3), opts).splitlines()
34
-
35
- config.js_config["indent_level"] = 2
36
- opts = BeautifierOptions(config.js_config)
37
- beautified_lines_test = cssbeautifier.beautify(
38
- match.group(3), opts
39
- ).splitlines()
40
-
41
- beautified = ""
42
- for line, test in zip(beautified_lines, beautified_lines_test):
43
- beautified += "\n"
44
- if line == test:
45
- beautified += line
46
- continue
47
- beautified += indent + line
48
-
49
- return match.group(1) + match.group(2) + beautified + "\n" + indent
50
-
51
- func = partial(launch_formatter, config, html)
52
-
53
- return re.sub(
54
- re.compile(
55
- r"([ ]*?)(<(?:style)\b(?:\"[^\"]*\"|'[^']*'|{[^}]*}|[^'\">{}])*>)(.*?)(?=</style>)",
56
- re.IGNORECASE | re.DOTALL,
57
- ),
58
- func,
59
- html,
60
- )
@@ -1,111 +0,0 @@
1
- """Expand html.
2
-
3
- 1. put html tags on individual lines, if needed.
4
- 2. put template tags on individual lines, if needed.
5
- """
6
-
7
- from functools import partial
8
-
9
- import regex as re
10
-
11
- from ..helpers import inside_ignored_block, inside_template_block
12
- from ..settings import Config
13
-
14
-
15
- def expand_html(html: str, config: Config) -> str:
16
- """Split single line html into many lines based on tags."""
17
-
18
- def add_html_line(out_format: str, match: re.Match) -> str:
19
- """Add whitespace.
20
-
21
- Do not add whitespace if the tag is in a non indent block.
22
-
23
- Do not add whitespace if the tag is a in a template block
24
- """
25
- if inside_ignored_block(config, html, match):
26
- return match.group(1)
27
-
28
- if inside_template_block(config, html, match):
29
- return match.group(1)
30
-
31
- if out_format == "\n%s" and match.start() == 0:
32
- return match.group(1)
33
-
34
- return out_format % match.group(1)
35
-
36
- html_tags = config.break_html_tags
37
-
38
- add_left = partial(add_html_line, "\n%s")
39
- add_right = partial(add_html_line, "%s\n")
40
-
41
- break_char = config.break_before
42
-
43
- # html tags - break before
44
- html = re.sub(
45
- re.compile(
46
- rf"{break_char}\K(</?(?:{html_tags})\b(\"[^\"]*\"|'[^']*'|{{[^}}]*}}|[^'\">{{}}])*>)",
47
- flags=re.IGNORECASE | re.VERBOSE,
48
- ),
49
- add_left,
50
- html,
51
- )
52
-
53
- # html tags - break after
54
- html = re.sub(
55
- re.compile(
56
- rf"(</?(?:{html_tags})\b(\"[^\"]*\"|'[^']*'|{{[^}}]*}}|[^'\">{{}}])*>)(?!\s*?\n)(?=[^\n])",
57
- flags=re.IGNORECASE | re.VERBOSE,
58
- ),
59
- add_right,
60
- html,
61
- )
62
-
63
- # template tag breaks
64
- def should_i_move_template_tag(out_format: str, match: re.Match) -> str:
65
- # ensure template tag is not inside an html tag and also not the first line of the file
66
- if inside_ignored_block(config, html, match):
67
- return match.group(1)
68
-
69
- if not re.findall(
70
- r"\<(?:" + str(config.indent_html_tags)
71
- # added > as not allowed inside a "" or '' to prevent invalid wild html matches
72
- # for issue #640
73
- + r")\b(?:\"[^\">]*\"|'[^'>]*'|{{[^}]*}}|{%[^%]*%}|{\#[^\#]*\#}|[^>{}])*?"
74
- + re.escape(match.group(1))
75
- + "$",
76
- html[: match.end()],
77
- re.MULTILINE | re.VERBOSE,
78
- ):
79
- if out_format == "\n%s" and match.start() == 0:
80
- return match.group(1)
81
- return out_format % match.group(1)
82
-
83
- return match.group(1)
84
-
85
- # template tags
86
- # break before
87
- html = re.sub(
88
- re.compile(
89
- break_char
90
- + r"\K((?:{%|{{\#)[ ]*?(?:"
91
- + config.break_template_tags
92
- + ")[^}]+?[%}]})",
93
- flags=re.IGNORECASE | re.MULTILINE | re.VERBOSE,
94
- ),
95
- partial(should_i_move_template_tag, "\n%s"),
96
- html,
97
- )
98
-
99
- # break after
100
- html = re.sub(
101
- re.compile(
102
- r"((?:{%|{{\#)[ ]*?(?:"
103
- + config.break_template_tags
104
- + ")[^}]+?[%}]})(?=[^\n])",
105
- flags=re.IGNORECASE | re.MULTILINE | re.VERBOSE,
106
- ),
107
- partial(should_i_move_template_tag, "%s\n"),
108
- html,
109
- )
110
-
111
- return html