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,969 +0,0 @@
1
- """Settings for reformater."""
2
- # pylint: disable=C0301,C0103
3
- # flake8: noqa
4
-
5
-
6
- import json
7
- import logging
8
-
9
- ## get pyproject.toml settings
10
- from pathlib import Path
11
- from typing import Dict, List, Optional, Tuple, Union
12
-
13
- import yaml
14
- from click import echo
15
- from colorama import Fore
16
- from HtmlTagNames import html_tag_names
17
- from HtmlVoidElements import html_void_elements
18
- from pathspec import PathSpec
19
- from pathspec.patterns.gitwildmatch import GitWildMatchPatternError
20
-
21
- try:
22
- import tomllib
23
- except ImportError:
24
- import tomli as tomllib # type: ignore
25
-
26
- logger = logging.getLogger(__name__)
27
-
28
-
29
- def find_project_root(src: Path) -> Path:
30
- """Attempt to get the project root."""
31
- for directory in [src, *src.resolve().parents]:
32
- if (directory / ".git").exists():
33
- return directory
34
-
35
- if (directory / ".hg").is_dir():
36
- return directory
37
-
38
- if (directory / "pyproject.toml").is_file():
39
- return directory
40
-
41
- if (directory / ".djlintrc").is_file():
42
- return directory
43
-
44
- # pylint: disable=W0631
45
- return directory
46
-
47
-
48
- def load_gitignore(root: Path) -> PathSpec:
49
- """Search upstream for a .gitignore file."""
50
-
51
- gitignore = root / ".gitignore"
52
- git_lines: List[str] = []
53
- if gitignore.is_file():
54
- with gitignore.open(encoding="utf-8") as this_file:
55
- git_lines = this_file.readlines()
56
-
57
- try:
58
- return PathSpec.from_lines("gitwildmatch", git_lines)
59
-
60
- except GitWildMatchPatternError as e:
61
- echo(f"Could not parse {gitignore}: {e}", err=True)
62
- raise
63
-
64
-
65
- def find_pyproject(root: Path) -> Optional[Path]:
66
- """Search upstream for a pyproject.toml file."""
67
-
68
- pyproject = root / "pyproject.toml"
69
-
70
- if pyproject.is_file():
71
- return pyproject
72
-
73
- return None
74
-
75
-
76
- def find_djlintrc(root: Path) -> Optional[Path]:
77
- """Search upstream for a pyproject.toml file."""
78
-
79
- djlintrc = root / ".djlintrc"
80
-
81
- if djlintrc.is_file():
82
- return djlintrc
83
-
84
- return None
85
-
86
-
87
- def find_djlint_rules(root: Path) -> Optional[Path]:
88
- """Search upstream for a pyproject.toml file."""
89
-
90
- rules = root / ".djlint_rules.yaml"
91
-
92
- if rules.is_file():
93
- return rules
94
-
95
- return None
96
-
97
-
98
- def load_project_settings(src: Path, config: Optional[str]) -> Dict:
99
- """Load djlint config from pyproject.toml."""
100
-
101
- djlint_content: Dict = {}
102
-
103
- if config:
104
- try:
105
- djlint_content = json.loads(
106
- Path(config).resolve().read_text(encoding="utf8")
107
- )
108
-
109
- # pylint: disable=broad-except
110
- except BaseException as error:
111
- logger.error(
112
- "%sFailed to load config file %s. %s",
113
- Fore.RED,
114
- Path(config).resolve(),
115
- error,
116
- )
117
-
118
- pyproject_file = find_pyproject(src)
119
-
120
- if pyproject_file:
121
- content = tomllib.loads(pyproject_file.read_text(encoding="utf8"))
122
- try:
123
- return {**djlint_content, **content["tool"]["djlint"]} # type: ignore
124
- except KeyError:
125
- logger.info("No pyproject.toml found.")
126
-
127
- djlintrc_file = find_djlintrc(src)
128
-
129
- if djlintrc_file:
130
- try:
131
- return {
132
- **djlint_content,
133
- **json.loads(djlintrc_file.read_text(encoding="utf8")),
134
- }
135
- # pylint: disable=broad-except
136
- except BaseException as error:
137
- logger.error("%sFailed to load .djlintrc file. %s", Fore.RED, error)
138
-
139
- return djlint_content
140
-
141
-
142
- def validate_rules(rules: List) -> List:
143
- """Validate a list of linter rules. Returns valid rules."""
144
- clean_rules = []
145
-
146
- for rule in rules:
147
- # check for name
148
- warning = 0
149
- name = rule["rule"].get("name", "undefined")
150
- if "name" not in rule["rule"]:
151
- warning += 1
152
- echo(Fore.RED + "Warning: A rule is missing a name! 😢")
153
- if "patterns" not in rule["rule"] and "python_module" not in rule["rule"]:
154
- warning += 1
155
- echo(
156
- Fore.RED
157
- + f"Warning: Rule {name} is missing a pattern or a python_module! 😢"
158
- )
159
- if "message" not in rule["rule"]:
160
- warning += 1
161
- echo(Fore.RED + f"Warning: Rule {name} is missing a message! 😢")
162
-
163
- if warning == 0:
164
- clean_rules.append(rule)
165
-
166
- return clean_rules
167
-
168
-
169
- def load_custom_rules(src: Path) -> List:
170
- """Load djlint config from pyproject.toml."""
171
-
172
- djlint_content: List = []
173
- djlint_rules_file = find_djlint_rules(src)
174
-
175
- if djlint_rules_file:
176
- djlint_content = yaml.load(
177
- Path(djlint_rules_file).read_text(encoding="utf8"),
178
- Loader=yaml.SafeLoader,
179
- )
180
-
181
- return djlint_content
182
-
183
-
184
- def build_custom_blocks(custom_blocks: Union[str, None]) -> Optional[str]:
185
- """Build regex string for custom template blocks."""
186
- if custom_blocks:
187
- # need to also do "end<tag>"
188
- open_tags = [x.strip() for x in custom_blocks.split(",")]
189
- close_tags = ["end" + x.strip() for x in custom_blocks.split(",")]
190
- # Group all tags together with a negative lookahead.
191
- tags = {tag + r"\b" for tag in open_tags + close_tags}
192
- return "|" + "|".join(sorted(tags))
193
- return None
194
-
195
-
196
- def build_ignore_blocks(ignore_blocks: Union[str, None]) -> Optional[str]:
197
- """Build regex string for template blocks to not format."""
198
- if ignore_blocks:
199
- # need to also do "end<tag>"
200
- open_tags = [x.strip() + r"\b" for x in ignore_blocks.split(",")]
201
- close_tags = ["end" + x.strip() + r"\b" for x in ignore_blocks.split(",")]
202
- return "|".join(sorted(set(open_tags + close_tags)))
203
- return None
204
-
205
-
206
- def build_custom_html(custom_html: Union[str, None]) -> Optional[str]:
207
- """Build regex string for custom HTML blocks."""
208
- if custom_html:
209
- return "|" + "|".join(x.strip() for x in custom_html.split(","))
210
- return None
211
-
212
-
213
- class Config:
214
- """Djlint Config."""
215
-
216
- def __init__(
217
- self,
218
- src: str,
219
- ignore: Optional[str] = None,
220
- extension: Optional[str] = None,
221
- indent: Optional[int] = None,
222
- quiet: bool = False,
223
- profile: Optional[str] = None,
224
- require_pragma: bool = False,
225
- reformat: bool = False,
226
- check: bool = False,
227
- lint: bool = False,
228
- use_gitignore: bool = False,
229
- warn: bool = False,
230
- preserve_leading_space: bool = False,
231
- preserve_blank_lines: bool = False,
232
- format_css: bool = False,
233
- format_js: bool = False,
234
- configuration: Optional[str] = None,
235
- statistics: bool = False,
236
- include: Optional[str] = None,
237
- ignore_case: bool = False,
238
- ignore_blocks: str = "",
239
- custom_blocks: str = "",
240
- blank_line_after_tag: str = "",
241
- blank_line_before_tag: str = "",
242
- line_break_after_multiline_tag: bool = False,
243
- custom_html: str = "",
244
- exclude: str = "",
245
- extend_exclude: str = "",
246
- linter_output_format: str = "",
247
- max_line_length: Optional[int] = None,
248
- max_attribute_length: Optional[int] = None,
249
- format_attribute_template_tags: bool = False,
250
- per_file_ignores: Optional[List[Tuple[str, str]]] = None,
251
- indent_css: Optional[int] = None,
252
- indent_js: Optional[int] = None,
253
- close_void_tags: bool = False,
254
- no_line_after_yaml: bool = False,
255
- ):
256
- self.reformat = reformat
257
- self.check = check
258
- self.lint = lint
259
- self.warn = warn
260
-
261
- if src == "-":
262
- self.project_root = find_project_root(Path.cwd())
263
- else:
264
- self.project_root = find_project_root(Path(src))
265
-
266
- djlint_settings = load_project_settings(self.project_root, configuration)
267
-
268
- self.gitignore = load_gitignore(self.project_root)
269
- # custom configuration options
270
-
271
- self.use_gitignore: bool = use_gitignore or djlint_settings.get(
272
- "use_gitignore", False
273
- )
274
- self.extension: str = str(extension or djlint_settings.get("extension", "html"))
275
- self.quiet: bool = quiet or djlint_settings.get("quiet", False)
276
- self.require_pragma: bool = (
277
- require_pragma
278
- or str(djlint_settings.get("require_pragma", "false")).lower() == "true"
279
- )
280
-
281
- self.custom_blocks: str = str(
282
- build_custom_blocks(custom_blocks or djlint_settings.get("custom_blocks"))
283
- or ""
284
- )
285
-
286
- self.custom_html: str = str(
287
- build_custom_html(custom_html or djlint_settings.get("custom_html")) or ""
288
- )
289
-
290
- self.format_attribute_template_tags: bool = (
291
- format_attribute_template_tags
292
- or djlint_settings.get("format_attribute_template_tags", False)
293
- )
294
-
295
- self.preserve_leading_space: bool = (
296
- preserve_leading_space
297
- or djlint_settings.get("preserve_leading_space", False)
298
- )
299
- self.ignore_blocks: Optional[str] = build_ignore_blocks(
300
- ignore_blocks or djlint_settings.get("ignore_blocks", "")
301
- )
302
-
303
- self.preserve_blank_lines: bool = preserve_blank_lines or djlint_settings.get(
304
- "preserve_blank_lines", False
305
- )
306
-
307
- self.format_js: bool = format_js or djlint_settings.get("format_js", False)
308
-
309
- self.js_config = (
310
- {"indent_size": indent_js} if indent_js else djlint_settings.get("js")
311
- ) or {}
312
-
313
- self.css_config = (
314
- {"indent_size": indent_css} if indent_css else djlint_settings.get("css")
315
- ) or {}
316
-
317
- self.format_css: bool = format_css or djlint_settings.get("format_css", False)
318
-
319
- self.ignore_case: bool = ignore_case or djlint_settings.get(
320
- "ignore_case", False
321
- )
322
-
323
- self.close_void_tags: bool = close_void_tags or djlint_settings.get(
324
- "close_void_tags", False
325
- )
326
- self.no_line_after_yaml: bool = no_line_after_yaml or djlint_settings.get(
327
- "no_line_after_yaml", False
328
- )
329
-
330
- # ignore is based on input and also profile
331
- self.ignore: str = str(ignore or djlint_settings.get("ignore", ""))
332
- self.include: str = str(include or djlint_settings.get("include", ""))
333
-
334
- self.files: Optional[List[str]] = djlint_settings.get("files", None)
335
- self.stdin = False
336
-
337
- # codes to exclude
338
- profile_dict: Dict[str, List[str]] = {
339
- "html": ["D", "J", "T", "N", "M"],
340
- "django": ["J", "N", "M"],
341
- "jinja": ["D", "N", "M"],
342
- "nunjucks": ["D", "J", "M"],
343
- "handlebars": ["D", "J", "N"],
344
- "golang": ["D", "J", "N", "M"],
345
- "angular": ["D", "J", "H012", "H026", "H028"],
346
- }
347
-
348
- self.profile_code: List[str] = profile_dict.get(
349
- str(profile or djlint_settings.get("profile", "html")).lower(), []
350
- )
351
- self.profile: str = str(
352
- profile or djlint_settings.get("profile", "all")
353
- ).lower()
354
-
355
- self.linter_output_format: str = linter_output_format or djlint_settings.get(
356
- "linter_output_format", "{code} {line} {message} {match}"
357
- )
358
-
359
- # load linter rules
360
- rule_set = validate_rules(
361
- yaml.load(
362
- (Path(__file__).parent / "rules.yaml").read_text(encoding="utf8"),
363
- Loader=yaml.SafeLoader,
364
- )
365
- + load_custom_rules(self.project_root)
366
- )
367
-
368
- self.linter_rules = list(
369
- filter(
370
- lambda x: x["rule"]["name"] not in self.ignore.split(",")
371
- and not any(
372
- x["rule"]["name"].startswith(code) for code in self.profile_code
373
- )
374
- and self.profile not in x["rule"].get("exclude", [])
375
- and (
376
- x["rule"].get("default", True)
377
- or x["rule"]["name"] in self.include.split(",")
378
- ),
379
- rule_set,
380
- )
381
- )
382
-
383
- self.statistics = statistics
384
-
385
- # base options
386
- default_indent = 4
387
- if not indent:
388
- try:
389
- indent = int(djlint_settings.get("indent", default_indent))
390
- except ValueError:
391
- echo(
392
- Fore.RED
393
- + f"Error: Invalid pyproject.toml indent value {djlint_settings['indent']}"
394
- )
395
- indent = default_indent
396
- self.indent_size = indent
397
- self.indent: str = int(indent) * " "
398
-
399
- default_exclude: str = r"""
400
- \.venv
401
- | venv/
402
- | \.tox
403
- | \.eggs
404
- | \.git
405
- | \.hg
406
- | \.mypy_cache
407
- | \.nox
408
- | \.svn
409
- | \.bzr
410
- | _build/
411
- | buck-out/
412
- | build/
413
- | dist/
414
- | \.pants\.d
415
- | \.direnv
416
- | node_modules/
417
- | __pypackages__
418
- """
419
-
420
- self.exclude: str = exclude or djlint_settings.get("exclude", default_exclude)
421
-
422
- extend_exclude = extend_exclude or djlint_settings.get("extend_exclude", "")
423
-
424
- if extend_exclude:
425
- self.exclude += r" | " + r" | ".join(
426
- x.strip() for x in extend_exclude.split(",")
427
- )
428
-
429
- self.per_file_ignores = (
430
- ({x: y for x, y in per_file_ignores})
431
- if per_file_ignores
432
- else djlint_settings.get("per-file-ignores", {})
433
- )
434
-
435
- # add blank line after load tags
436
- self.blank_line_after_tag: Optional[
437
- str
438
- ] = blank_line_after_tag or djlint_settings.get("blank_line_after_tag", None)
439
-
440
- # add blank line before load tags
441
- self.blank_line_before_tag: Optional[
442
- str
443
- ] = blank_line_before_tag or djlint_settings.get("blank_line_before_tag", None)
444
-
445
- # add line break after multi-line tags
446
- self.line_break_after_multiline_tag: bool = (
447
- line_break_after_multiline_tag
448
- or djlint_settings.get("line_break_after_multiline_tag", False)
449
- )
450
-
451
- # contents of tags will not be formatted
452
- self.ignored_block_opening: str = r"""
453
- <style
454
- | {\*
455
- | <\?php
456
- | <script
457
- | <!--
458
- | [^\{]{\#(?!\s*djlint\:\s*(?:on|off))
459
- | ^{\#(?!\s*djlint\:\s*(?:on|off))
460
- | <pre
461
- | <textarea
462
- | {%[ ]*?blocktrans(?:late)?(?:(?!%}|\btrimmed\b).)*?%}
463
- | {\#\s*djlint\:\s*off\s*\#}
464
- | {%[ ]+?comment[ ]+?(?:(?!%}).)*?%}
465
- | {{!--\s*djlint\:off\s*--}}
466
- | {{-?\s*/\*\s*djlint\:off\s*\*/\s*-?}}
467
- """
468
-
469
- self.ignored_block_closing: str = r"""
470
- </style
471
- | \*}
472
- | \?>
473
- | </script
474
- | -->
475
- | ^(?:(?!{\#).)*\#} # lines that have a #}, but not a {#
476
- | </pre
477
- | </textarea
478
- | {\#\s*djlint\:\s*on\s*\#}
479
- | (?<!djlint:off\s*?){%[ ]+?endcomment[ ]+?%}
480
- | {{!--\s*djlint\:on\s*--}}
481
- | {{-?\s*/\*\s*djlint\:on\s*\*/\s*-?}}
482
- | {%[ ]*?endblocktrans(?:late)?(?:(?!%}).)*?%}
483
- """
484
-
485
- # ignored block closing tags that
486
- # we can safely indent.
487
- self.safe_closing_tag: str = r"""
488
- </script
489
- | </style
490
- | {\#\s*djlint\:\s*on\s*\#}
491
- | {%[ ]+?endcomment[ ]+?%}
492
- | {{!--\s*djlint\:on\s*--}}
493
- | {{-?\s*/\*\s*djlint\:on\s*\*/\s*-?}}
494
- """
495
-
496
- # all html tags possible
497
- self.indent_html_tags: str = "|".join(html_tag_names) + self.custom_html
498
-
499
- self.indent_template_tags: str = (
500
- (rf"(?!{self.ignore_blocks})" if self.ignore_blocks else "")
501
- + r""" (?:if
502
- | for
503
- | block(?!trans|translate)
504
- | spaceless
505
- | compress
506
- | addto
507
- | language
508
- | with
509
- | assets
510
- | verbatim
511
- | autoescape
512
- | filter
513
- | each
514
- | macro
515
- | call
516
- | raw
517
- | blocktrans(?!late)
518
- | blocktranslate
519
- | set(?!(?:(?!%}).)*=)
520
- """
521
- + self.custom_blocks
522
- + r")"
523
- )
524
-
525
- self.template_indent: str = (
526
- r"""
527
- (?:\{\{\#|\{%-?)[ ]*?
528
- ("""
529
- + self.indent_template_tags
530
- + r"""
531
- )"""
532
- )
533
-
534
- self.template_unindent: str = r"""
535
- (?:
536
- (?:\{\{\/)
537
- | (?:\{%-?[ ]*?end(?!comment))
538
- )
539
- """
540
-
541
- # these tags should be unindented and next line will be indented
542
- self.tag_unindent_line: str = r"""
543
- (?:\{%-?[ ]*?(?:elif|else|empty|plural))
544
- | (?:
545
- \{\{[ ]*?
546
- (
547
- (?:else|\^)
548
- [ ]*?\}\}
549
- )
550
- )
551
- """
552
-
553
- self.break_before = r"(?<!\n[ ]*?)"
554
-
555
- # if lines are longer than x
556
- self.max_line_length = 120
557
-
558
- try:
559
- self.max_line_length = max_line_length or int(
560
- djlint_settings.get("max_line_length", self.max_line_length)
561
- )
562
- except ValueError:
563
- echo(
564
- Fore.RED
565
- + f"Error: Invalid pyproject.toml max_line_length value {djlint_settings['max_line_length']}"
566
- )
567
-
568
- self.max_attribute_length = 70
569
-
570
- try:
571
- self.max_attribute_length = max_attribute_length or int(
572
- djlint_settings.get("max_attribute_length", self.max_attribute_length)
573
- )
574
- except ValueError:
575
- echo(
576
- Fore.RED
577
- + f"Error: Invalid pyproject.toml max_attribute_length value {djlint_settings['max_attribute_length']}"
578
- )
579
-
580
- self.template_if_for_pattern = (
581
- r"(?:{%-?\s?(?:if|for)[^}]*?%}(?:.*?{%\s?end(?:if|for)[^}]*?-?%})+?)"
582
- )
583
-
584
- self.attribute_pattern: str = (
585
- rf"""
586
- (?:
587
- (
588
- (?:\w|-|\.|\:|@|/(?!>))+ | required | checked
589
- )? # attribute name
590
- (?: [ ]*?=[ ]*? # followed by "="
591
- (
592
- \"[^\"]*? # double quoted attribute
593
- (?:
594
- {self.template_if_for_pattern} # if or for loop
595
- | {{{{.*?}}}} # template stuff
596
- | {{%[^}}]*?%}}
597
- | [^\"] # anything else
598
- )*?
599
- \" # closing quote
600
- | '[^']*? # single quoted attribute
601
- (?:
602
- {self.template_if_for_pattern} # if or for loop
603
- | {{{{.*?}}}} # template stuff
604
- | {{%[^}}]*?%}}
605
- | [^'] # anything else
606
- )*?
607
- \' # closing quote
608
- | (?:\w|-)+ # or a non-quoted string value
609
- | {{{{.*?}}}} # a non-quoted template var
610
- | {{%[^}}]*?%}} # a non-quoted template tag
611
- | {self.template_if_for_pattern} # a non-quoted if statement
612
-
613
- )
614
- )? # attribute value
615
- )
616
- | ({self.template_if_for_pattern}
617
- """
618
- + r"""
619
- | {{.*?}}
620
- | {\#.*?\#}
621
- | {%.*?%})
622
- """
623
- )
624
-
625
- self.html_tag_regex = r"""
626
- (</?(?:!(?!--))?) # an opening bracket (< or </ or <!), but not a comment
627
- ([^\s>!\[]+\b) # a tag name
628
- ((?:\s*?(?:\"[^\"]*\"|'[^']*'|{{(?:(?!}}).)*}}|{%(?:(?!%}).)*%}|[^'\">{}/\s]|/(?!>)))+)? # any attributes
629
- \s*? # potentially some whitespace
630
- (/?>) # a closing braket (/> or >)
631
- """
632
-
633
- self.attribute_style_pattern: str = r"^(.*?)(style=)([\"|'])(([^\"']+?;)+?)\3"
634
-
635
- self.ignored_attributes = [
636
- "href",
637
- "action",
638
- "data-url",
639
- "src",
640
- "url",
641
- "srcset",
642
- "data-src",
643
- ]
644
-
645
- self.start_template_tags: str = (
646
- (rf"(?!{self.ignore_blocks})" if self.ignore_blocks else "")
647
- + r"""
648
- (?:if
649
- | for
650
- | block(?!trans)
651
- | spaceless
652
- | compress
653
- | load
654
- | assets
655
- | addto
656
- | language
657
- | with
658
- | assets
659
- | autoescape
660
- | filter
661
- | verbatim
662
- | each
663
- | macro
664
- | call
665
- | raw
666
- | blocktrans(?!late)
667
- | blocktranslate
668
- | set(?!(?:(?!%}).)*=)
669
-
670
- """
671
- + self.custom_blocks
672
- + r""")
673
- """
674
- )
675
-
676
- self.break_template_tags: str = (
677
- (rf"(?!{self.ignore_blocks})" if self.ignore_blocks else "")
678
- + r"""
679
- (?:if
680
- | endif
681
- | for
682
- | endfor
683
- | block(?!trans)
684
- | endblock(?!trans)
685
- | else
686
- | plural
687
- | spaceless
688
- | endspaceless
689
- | compress
690
- | endcompress
691
- | load
692
- | include
693
- | assets
694
- | endassets
695
- | addto
696
- | language
697
- | with
698
- | endwith
699
- | autoescape
700
- | endautoescape
701
- | filter
702
- | endfilter
703
- | elif
704
- | resetcycle
705
- | verbatim
706
- | endverbatim
707
- | each
708
- | macro
709
- | endmacro
710
- | raw
711
- | endraw
712
- | call
713
- | endcall
714
- | image
715
- | blocktrans(?!late)
716
- | endblocktrans(?!late)
717
- | blocktranslate
718
- | endblocktranslate
719
- | set(?!(?:(?!%}).)*=)
720
- | endset
721
- """
722
- + self.custom_blocks
723
- + r""")
724
- """
725
- )
726
- self.template_blocks: str = r"""
727
- {%((?!%}).)+%}
728
- """
729
-
730
- self.ignored_linter_blocks: str = r"""
731
- {%-?[ ]*?raw\b(?:(?!%}).)*?-?%}.*?(?={%-?[ ]*?endraw[ ]*?-?%})
732
- """
733
-
734
- self.unformatted_blocks: str = r"""
735
- # html comment
736
- | <!--\s*djlint\:off\s*-->.*?(?=<!--\s*djlint\:on\s*-->)
737
- # django/jinja/nunjucks
738
- | {\#\s*djlint\:\s*off\s*\#}.*?(?={\#\s*djlint\:\s*on\s*\#})
739
- | {%\s*comment\s*%\}\s*djlint\:off\s*\{%\s*endcomment\s*%\}.*?(?={%\s*comment\s*%\}\s*djlint\:on\s*\{%\s*endcomment\s*%\})
740
- # inline jinja comments
741
- | {\#(?!\s*djlint\:\s*(?:off|on)).*?\#}
742
- # handlebars
743
- | {{!--\s*djlint\:off\s*--}}.*?(?={{!--\s*djlint\:on\s*--}})
744
- # golang
745
- | {{-?\s*/\*\s*djlint\:off\s*\*/\s*-?}}.*?(?={{-?\s*/\*\s*djlint\:on\s*\*/\s*-?}})
746
- | ^---[\s\S]+?---
747
- """
748
-
749
- self.ignored_blocks: str = r"""
750
- <(pre|textarea).*?</(\1)>
751
- | <(script|style).*?(?=(\</(?:\3)>))
752
- # html comment
753
- | <!--\s*djlint\:off\s*-->.*?(?=<!--\s*djlint\:on\s*-->)
754
- # django/jinja/nunjucks
755
- | {\#\s*djlint\:\s*off\s*\#}(?:(?!{\#\s*djlint\:\s*on\s*\#}).)*
756
- | {%\s*comment\s*%\}\s*djlint\:off\s*\{%\s*endcomment\s*%\}(?:(?!{%\s*comment\s*%\}\s*djlint\:on\s*\{%\s*endcomment\s*%\}).)*
757
- # inline jinja comments
758
- | {\#(?!\s*djlint\:\s*(?:off|on)).*?\#}
759
- # handlebars
760
- | {{!--\s*djlint\:off\s*--}}(?:(?!{{!--\s*djlint\:on\s*--}}).)*
761
- # golang
762
- | {{-?\s*/\*\s*djlint\:off\s*\*/\s*-?}}(?:(?!{{-?\s*/\*\s*djlint\:on\s*\*/\s*-?}}).)*
763
- | <!--.*?-->
764
- | <\?php.*?\?>
765
- | {%[ ]*?blocktranslate\b(?:(?!%}|\btrimmed\b).)*?%}.*?{%[ ]*?endblocktranslate[ ]*?%}
766
- | {%[ ]*?blocktrans\b(?:(?!%}|\btrimmed\b).)*?%}.*?{%[ ]*?endblocktrans[ ]*?%}
767
- | {%[ ]*?comment\b(?:(?!%}).)*?%}(?:(?!djlint:(?:off|on)).)*?(?={%[ ]*?endcomment[ ]*?%})
768
- | ^---[\s\S]+?---
769
- """
770
- self.ignored_blocks_inline: str = r"""
771
- <(pre|textarea).*?</(\1)>
772
- | <(script|style).*?(?=(\</(?:\3)>))
773
- # html comment
774
- | <!--\s*djlint\:off\s*-->.*?(?=<!--\s*djlint\:on\s*-->)
775
- # django/jinja/nunjucks
776
- | {\#\s*djlint\:\s*off\s*\#}.*?(?={\#\s*djlint\:\s*on\s*\#})
777
- | {%\s*comment\s*%\}\s*djlint\:off\s*\{%\s*endcomment\s*%\}.*?(?={%\s*comment\s*%\}\s*djlint\:on\s*\{%\s*endcomment\s*%\})
778
- # inline jinja comments
779
- | {\#(?!\s*djlint\:\s*(?:off|on)).*?\#}
780
- # handlebars
781
- | {{!--\s*djlint\:off\s*--}}.*?(?={{!--\s*djlint\:on\s*--}})
782
- # golang
783
- | {{-?\s*/\*\s*djlint\:off\s*\*/\s*-?}}.*?(?={{-?\s*/\*\s*djlint\:on\s*\*/\s*-?}})
784
- | <!--.*?-->
785
- | <\?php.*?\?>
786
- | {%[ ]*?blocktranslate\b(?:(?!%}|\btrimmed\b).)*?%}.*?{%[ ]*?endblocktranslate[ ]*?%}
787
- | {%[ ]*?blocktrans\b(?:(?!%}|\btrimmed\b).)*?%}.*?{%[ ]*?endblocktrans[ ]*?%}
788
- | {%[ ]*?comment\b(?:(?!%}).)*?%}(?:(?!djlint:(?:off|on)).)*?(?={%[ ]*?endcomment[ ]*?%})
789
- | ^---[\s\S]+?---
790
- """
791
-
792
- self.ignored_rules: List[str] = [
793
- # html comment
794
- r"<!--\s*djlint\:off(.+?)-->(?:(?!<!--\s*djlint\:on\s*-->).)*",
795
- # django/jinja/nunjucks
796
- r"{\#\s*djlint\:\s*off(.+?)\#}(?:(?!{\#\s*djlint\:\s*on\s*\#}).)*",
797
- r"{%\s*comment\s*%\}\s*djlint\:off(.*?)\{%\s*endcomment\s*%\}(?:(?!{%\s*comment\s*%\}\s*djlint\:on\s*\{%\s*endcomment\s*%\}).)*",
798
- # handlebars
799
- r"{{!--\s*djlint\:off(.*?)--}}(?:(?!{{!--\s*djlint\:on\s*--}}).)*",
800
- # golang
801
- r"{{-?\s*/\*\s*djlint\:off(.*?)\*/\s*-?}}(?:(?!{{-?\s*/\*\s*djlint\:on\s*\*/\s*-?}}).)*",
802
- ]
803
-
804
- self.ignored_trans_blocks: str = r"""
805
- {%[ ]*?blocktranslate?\b(?:(?!%}|\btrimmed\b).)*?%}.*?{%[ ]*?endblocktranslate?[ ]*?%}
806
- | {%[ ]*?blocktrans\b(?:(?!%}|\btrimmed\b).)*?%}.*?{%[ ]*?endblocktrans[ ]*?%}
807
- """
808
- self.trans_trimmed_blocks: str = r"""
809
- {%[ ]*?blocktranslate\b(?:(?!%}).)*?\btrimmed\b(?:(?!%}).)*?%}.*?{%[ ]*?endblocktranslate[ ]*?%}
810
- | {%[ ]*?blocktrans\b(?:(?!%}).)*?\btrimmed\b(?:(?!%}).)*?%}.*?{%[ ]*?endblocktrans[ ]*?%}
811
- """
812
- self.ignored_trans_blocks_closing: str = r"""
813
- {%[ ]*?endblocktrans(?:late)?(?:(?!%}).)*?%}
814
- """
815
-
816
- self.ignored_inline_blocks: str = r"""
817
- <!--.*?-->
818
- | <script.*?\</script>
819
- | <style.*?\</style>
820
- | {\*.*?\*}
821
- | {\#(?!.*djlint:[ ]*?(?:off|on)\b).*\#}
822
- | <\?php.*?\?>
823
- | {%[ ]*?comment\b(?:(?!%}).)*?%}(?:(?!djlint:(?:off|on)).)*?{%[ ]*?endcomment[ ]*?%}
824
- | {%[ ]*?blocktrans(?:late)?\b(?:(?!%}|\btrimmed\b).)*?%}.*?{%[ ]*?endblocktrans(?:late)?[ ]*?%}
825
- """
826
-
827
- self.optional_single_line_html_tags: str = r"""
828
- button
829
- | a
830
- | h1
831
- | h2
832
- | h3
833
- | h4
834
- | h5
835
- | h6
836
- | td
837
- | th
838
- | strong
839
- | small
840
- | em
841
- | icon
842
- | span
843
- | title
844
- | link
845
- | path
846
- | label
847
- | div
848
- | li
849
- | script
850
- | style
851
- | head
852
- | body
853
- | p
854
- | select
855
- | article
856
- | option
857
- | legend
858
- | summary
859
- | dt
860
- | figcaption
861
- | tr
862
- | li
863
- """
864
-
865
- self.always_self_closing_html_tags: str = "|".join(html_void_elements)
866
-
867
- self.optional_single_line_template_tags: str = r"""
868
- if
869
- | for
870
- | block
871
- | with
872
- """
873
-
874
- self.break_html_tags: str = (
875
- r"""
876
- html
877
- | head
878
- | body
879
- | div
880
- # | a # a gets no breaks #177
881
- | nav
882
- | ul
883
- | ol
884
- | dl
885
- | dd
886
- | dt
887
- | li
888
- | table
889
- | thead
890
- | tbody
891
- | tr
892
- | th
893
- | td
894
- | blockquote
895
- | select
896
- | form
897
- | option
898
- | optgroup
899
- | fieldset
900
- | legend
901
- | label
902
- | header
903
- | cache
904
- | main
905
- | section
906
- | aside
907
- | footer
908
- | figure
909
- | figcaption
910
- | video
911
- # | span # span gets no breaks #171
912
- | p
913
- | g
914
- | svg
915
- | h\d
916
- | button
917
- | path
918
- | picture
919
- | script
920
- | style
921
- | details
922
- | summary
923
- | """
924
- + self.always_self_closing_html_tags
925
- + self.custom_html
926
- + """
927
- """
928
- )
929
-
930
- # the contents of these tag blocks will be indented, then unindented
931
- self.tag_indent: str = (
932
- self.template_indent
933
- + """
934
- | (?:<
935
- (?:
936
- """
937
- + self.indent_html_tags
938
- + """
939
- )\\b
940
- )
941
- """
942
- )
943
-
944
- # either a template tag at the start of a line,
945
- # a html tag at the start of a line,
946
- # or an html tag as the end of a line.
947
- # Nothing in between!
948
- self.tag_unindent: str = (
949
- r"""
950
- ^
951
- """
952
- + self.template_unindent
953
- + """
954
- | (?:^</
955
- (?:
956
- """
957
- + self.indent_html_tags
958
- + """
959
- )\\b
960
- )
961
- | (?:</
962
- (?:
963
- """
964
- + self.indent_html_tags
965
- + """
966
- )>$
967
- )
968
- """
969
- )