herb 0.10.4-x86-linux-musl → 0.11.0-x86-linux-musl

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 (788) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +16 -6
  3. data/README.md +36 -119
  4. data/Rakefile +2 -11
  5. data/config/action_view_helpers/actioncable/action_cable_helper/action_cable_meta_tag.yml +12 -8
  6. data/config/action_view_helpers/actionpack/content_security_policy/content_security_policy?.yml +9 -6
  7. data/config/action_view_helpers/actionpack/content_security_policy/content_security_policy_nonce.yml +9 -6
  8. data/config/action_view_helpers/actionpack/polymorphic_routes/polymorphic_path.yml +20 -12
  9. data/config/action_view_helpers/actionpack/polymorphic_routes/polymorphic_url.yml +30 -18
  10. data/config/action_view_helpers/actionpack/request_forgery_protection/form_authenticity_token.yml +15 -9
  11. data/config/action_view_helpers/actionpack/request_forgery_protection/protect_against_forgery?.yml +9 -6
  12. data/config/action_view_helpers/actiontext/content_helper/render_action_text_content.yml +15 -9
  13. data/config/action_view_helpers/actiontext/content_helper/sanitize_action_text_content.yml +15 -9
  14. data/config/action_view_helpers/actiontext/tag_helper/rich_textarea_tag.yml +34 -22
  15. data/config/action_view_helpers/actionview/active_model_helper/error_message.yml +9 -6
  16. data/config/action_view_helpers/actionview/active_model_helper/error_wrapping.yml +9 -6
  17. data/config/action_view_helpers/actionview/active_model_helper/object.yml +9 -6
  18. data/config/action_view_helpers/actionview/asset_tag_helper/apply_stylesheet_media_default.yml +9 -6
  19. data/config/action_view_helpers/actionview/asset_tag_helper/audio_tag.yml +40 -27
  20. data/config/action_view_helpers/actionview/asset_tag_helper/auto_discovery_link_tag.yml +37 -23
  21. data/config/action_view_helpers/actionview/asset_tag_helper/auto_include_nonce.yml +9 -6
  22. data/config/action_view_helpers/actionview/asset_tag_helper/auto_include_nonce_for_scripts.yml +9 -6
  23. data/config/action_view_helpers/actionview/asset_tag_helper/auto_include_nonce_for_styles.yml +9 -6
  24. data/config/action_view_helpers/actionview/asset_tag_helper/favicon_link_tag.yml +32 -22
  25. data/config/action_view_helpers/actionview/asset_tag_helper/image_decoding.yml +9 -6
  26. data/config/action_view_helpers/actionview/asset_tag_helper/image_loading.yml +9 -6
  27. data/config/action_view_helpers/actionview/asset_tag_helper/image_tag.yml +67 -46
  28. data/config/action_view_helpers/actionview/asset_tag_helper/javascript_include_tag.yml +58 -39
  29. data/config/action_view_helpers/actionview/asset_tag_helper/picture_tag.yml +22 -14
  30. data/config/action_view_helpers/actionview/asset_tag_helper/preload_link_tag.yml +45 -30
  31. data/config/action_view_helpers/actionview/asset_tag_helper/preload_links_header.yml +9 -6
  32. data/config/action_view_helpers/actionview/asset_tag_helper/stylesheet_link_tag.yml +49 -30
  33. data/config/action_view_helpers/actionview/asset_tag_helper/video_tag.yml +53 -35
  34. data/config/action_view_helpers/actionview/asset_url_helper/asset_path.yml +16 -10
  35. data/config/action_view_helpers/actionview/asset_url_helper/asset_url.yml +16 -10
  36. data/config/action_view_helpers/actionview/asset_url_helper/audio_path.yml +16 -10
  37. data/config/action_view_helpers/actionview/asset_url_helper/audio_url.yml +16 -10
  38. data/config/action_view_helpers/actionview/asset_url_helper/compute_asset_extname.yml +9 -6
  39. data/config/action_view_helpers/actionview/asset_url_helper/compute_asset_host.yml +9 -6
  40. data/config/action_view_helpers/actionview/asset_url_helper/compute_asset_path.yml +9 -6
  41. data/config/action_view_helpers/actionview/asset_url_helper/font_path.yml +16 -10
  42. data/config/action_view_helpers/actionview/asset_url_helper/font_url.yml +16 -10
  43. data/config/action_view_helpers/actionview/asset_url_helper/image_path.yml +16 -10
  44. data/config/action_view_helpers/actionview/asset_url_helper/image_url.yml +16 -10
  45. data/config/action_view_helpers/actionview/asset_url_helper/javascript_path.yml +16 -10
  46. data/config/action_view_helpers/actionview/asset_url_helper/javascript_url.yml +16 -10
  47. data/config/action_view_helpers/actionview/asset_url_helper/public_compute_asset_path.yml +9 -6
  48. data/config/action_view_helpers/actionview/asset_url_helper/stylesheet_path.yml +16 -10
  49. data/config/action_view_helpers/actionview/asset_url_helper/stylesheet_url.yml +16 -10
  50. data/config/action_view_helpers/actionview/asset_url_helper/video_path.yml +16 -10
  51. data/config/action_view_helpers/actionview/asset_url_helper/video_url.yml +16 -10
  52. data/config/action_view_helpers/actionview/atom_feed_helper/atom_feed.yml +52 -27
  53. data/config/action_view_helpers/actionview/cache_helper/cache.yml +25 -15
  54. data/config/action_view_helpers/actionview/cache_helper/cache_fragment_name.yml +9 -6
  55. data/config/action_view_helpers/actionview/cache_helper/cache_if.yml +20 -12
  56. data/config/action_view_helpers/actionview/cache_helper/cache_unless.yml +20 -12
  57. data/config/action_view_helpers/actionview/cache_helper/caching_predicate.yml +9 -6
  58. data/config/action_view_helpers/actionview/cache_helper/digest_path_from_template.yml +9 -6
  59. data/config/action_view_helpers/actionview/cache_helper/fragment_for.yml +9 -6
  60. data/config/action_view_helpers/actionview/cache_helper/fragment_name_with_digest.yml +9 -6
  61. data/config/action_view_helpers/actionview/cache_helper/read_fragment_for.yml +9 -6
  62. data/config/action_view_helpers/actionview/cache_helper/uncacheable.yml +9 -6
  63. data/config/action_view_helpers/actionview/cache_helper/write_fragment_for.yml +9 -6
  64. data/config/action_view_helpers/actionview/capture_helper/capture.yml +9 -6
  65. data/config/action_view_helpers/actionview/capture_helper/content_for.yml +20 -12
  66. data/config/action_view_helpers/actionview/capture_helper/content_for_predicate.yml +15 -9
  67. data/config/action_view_helpers/actionview/capture_helper/provide.yml +15 -9
  68. data/config/action_view_helpers/actionview/capture_helper/with_output_buffer.yml +9 -6
  69. data/config/action_view_helpers/actionview/content_exfiltration_prevention_helper/prepend_content_exfiltration_prevention.yml +9 -6
  70. data/config/action_view_helpers/actionview/content_exfiltration_prevention_helper/prevent_content_exfiltration.yml +9 -6
  71. data/config/action_view_helpers/actionview/controller_helper/action_name.yml +9 -6
  72. data/config/action_view_helpers/actionview/controller_helper/assign_controller.yml +9 -6
  73. data/config/action_view_helpers/actionview/controller_helper/controller.yml +9 -6
  74. data/config/action_view_helpers/actionview/controller_helper/controller_name.yml +9 -6
  75. data/config/action_view_helpers/actionview/controller_helper/controller_path.yml +9 -6
  76. data/config/action_view_helpers/actionview/controller_helper/cookies.yml +9 -6
  77. data/config/action_view_helpers/actionview/controller_helper/flash.yml +9 -6
  78. data/config/action_view_helpers/actionview/controller_helper/headers.yml +9 -6
  79. data/config/action_view_helpers/actionview/controller_helper/logger.yml +9 -6
  80. data/config/action_view_helpers/actionview/controller_helper/params.yml +9 -6
  81. data/config/action_view_helpers/actionview/controller_helper/request.yml +9 -6
  82. data/config/action_view_helpers/actionview/controller_helper/request_forgery_protection_token.yml +9 -6
  83. data/config/action_view_helpers/actionview/controller_helper/response.yml +9 -6
  84. data/config/action_view_helpers/actionview/controller_helper/session.yml +9 -6
  85. data/config/action_view_helpers/actionview/csp_helper/csp_meta_tag.yml +18 -11
  86. data/config/action_view_helpers/actionview/csrf_helper/csrf_meta_tags.yml +16 -10
  87. data/config/action_view_helpers/actionview/date_helper/date_select.yml +85 -51
  88. data/config/action_view_helpers/actionview/date_helper/datetime_select.yml +65 -39
  89. data/config/action_view_helpers/actionview/date_helper/distance_of_time_in_words.yml +30 -18
  90. data/config/action_view_helpers/actionview/date_helper/relative_time_in_words.yml +35 -21
  91. data/config/action_view_helpers/actionview/date_helper/select_date.yml +50 -30
  92. data/config/action_view_helpers/actionview/date_helper/select_datetime.yml +65 -39
  93. data/config/action_view_helpers/actionview/date_helper/select_day.yml +40 -24
  94. data/config/action_view_helpers/actionview/date_helper/select_hour.yml +50 -30
  95. data/config/action_view_helpers/actionview/date_helper/select_minute.yml +40 -24
  96. data/config/action_view_helpers/actionview/date_helper/select_month.yml +60 -36
  97. data/config/action_view_helpers/actionview/date_helper/select_second.yml +35 -21
  98. data/config/action_view_helpers/actionview/date_helper/select_time.yml +55 -33
  99. data/config/action_view_helpers/actionview/date_helper/select_year.yml +45 -27
  100. data/config/action_view_helpers/actionview/date_helper/time_ago_in_words.yml +21 -13
  101. data/config/action_view_helpers/actionview/date_helper/time_select.yml +60 -36
  102. data/config/action_view_helpers/actionview/date_helper/time_tag.yml +32 -20
  103. data/config/action_view_helpers/actionview/debug_helper/debug.yml +15 -9
  104. data/config/action_view_helpers/actionview/form_builder/button.yml +60 -0
  105. data/config/action_view_helpers/actionview/form_builder/submit.yml +48 -0
  106. data/config/action_view_helpers/actionview/form_helper/apply_form_for_options.yml +9 -6
  107. data/config/action_view_helpers/actionview/form_helper/checkbox.yml +41 -25
  108. data/config/action_view_helpers/actionview/form_helper/color_field.yml +25 -15
  109. data/config/action_view_helpers/actionview/form_helper/date_field.yml +35 -21
  110. data/config/action_view_helpers/actionview/form_helper/datetime_field.yml +41 -25
  111. data/config/action_view_helpers/actionview/form_helper/email_field.yml +25 -15
  112. data/config/action_view_helpers/actionview/form_helper/emitted_hidden_id.yml +9 -6
  113. data/config/action_view_helpers/actionview/form_helper/fields.yml +37 -18
  114. data/config/action_view_helpers/actionview/form_helper/fields_for.yml +33 -15
  115. data/config/action_view_helpers/actionview/form_helper/file_field.yml +45 -27
  116. data/config/action_view_helpers/actionview/form_helper/form_for.yml +45 -24
  117. data/config/action_view_helpers/actionview/form_helper/form_with.yml +56 -30
  118. data/config/action_view_helpers/actionview/form_helper/form_with_generates_ids.yml +9 -6
  119. data/config/action_view_helpers/actionview/form_helper/form_with_generates_remote_forms.yml +9 -6
  120. data/config/action_view_helpers/actionview/form_helper/hidden_field.yml +25 -15
  121. data/config/action_view_helpers/actionview/form_helper/label.yml +52 -27
  122. data/config/action_view_helpers/actionview/form_helper/month_field.yml +25 -15
  123. data/config/action_view_helpers/actionview/form_helper/multipart.yml +9 -6
  124. data/config/action_view_helpers/actionview/form_helper/multiple_file_field_include_hidden.yml +9 -6
  125. data/config/action_view_helpers/actionview/form_helper/number_field.yml +45 -27
  126. data/config/action_view_helpers/actionview/form_helper/password_field.yml +25 -15
  127. data/config/action_view_helpers/actionview/form_helper/radio_button.yml +30 -18
  128. data/config/action_view_helpers/actionview/form_helper/range_field.yml +45 -27
  129. data/config/action_view_helpers/actionview/form_helper/search_field.yml +25 -15
  130. data/config/action_view_helpers/actionview/form_helper/telephone_field.yml +26 -16
  131. data/config/action_view_helpers/actionview/form_helper/text_field.yml +25 -15
  132. data/config/action_view_helpers/actionview/form_helper/textarea.yml +31 -19
  133. data/config/action_view_helpers/actionview/form_helper/time_field.yml +40 -24
  134. data/config/action_view_helpers/actionview/form_helper/url_field.yml +25 -15
  135. data/config/action_view_helpers/actionview/form_helper/week_field.yml +25 -15
  136. data/config/action_view_helpers/actionview/form_options_helper/collection_checkboxes.yml +58 -31
  137. data/config/action_view_helpers/actionview/form_options_helper/collection_radio_buttons.yml +57 -30
  138. data/config/action_view_helpers/actionview/form_options_helper/collection_select.yml +65 -39
  139. data/config/action_view_helpers/actionview/form_options_helper/grouped_collection_select.yml +65 -39
  140. data/config/action_view_helpers/actionview/form_options_helper/grouped_options_for_select.yml +35 -21
  141. data/config/action_view_helpers/actionview/form_options_helper/option_groups_from_collection_for_select.yml +40 -24
  142. data/config/action_view_helpers/actionview/form_options_helper/options_for_select.yml +20 -12
  143. data/config/action_view_helpers/actionview/form_options_helper/options_from_collection_for_select.yml +30 -18
  144. data/config/action_view_helpers/actionview/form_options_helper/select.yml +60 -36
  145. data/config/action_view_helpers/actionview/form_options_helper/time_zone_options_for_select.yml +25 -15
  146. data/config/action_view_helpers/actionview/form_options_helper/time_zone_select.yml +50 -30
  147. data/config/action_view_helpers/actionview/form_options_helper/weekday_options_for_select.yml +30 -18
  148. data/config/action_view_helpers/actionview/form_options_helper/weekday_select.yml +30 -18
  149. data/config/action_view_helpers/actionview/form_tag_helper/button_tag.yml +39 -21
  150. data/config/action_view_helpers/actionview/form_tag_helper/checkbox_tag.yml +33 -21
  151. data/config/action_view_helpers/actionview/form_tag_helper/color_field_tag.yml +26 -17
  152. data/config/action_view_helpers/actionview/form_tag_helper/date_field_tag.yml +27 -17
  153. data/config/action_view_helpers/actionview/form_tag_helper/datetime_field_tag.yml +28 -18
  154. data/config/action_view_helpers/actionview/form_tag_helper/default_enforce_utf8.yml +9 -6
  155. data/config/action_view_helpers/actionview/form_tag_helper/email_field_tag.yml +27 -17
  156. data/config/action_view_helpers/actionview/form_tag_helper/embed_authenticity_token_in_remote_forms.yml +9 -6
  157. data/config/action_view_helpers/actionview/form_tag_helper/field_id.yml +30 -18
  158. data/config/action_view_helpers/actionview/form_tag_helper/field_name.yml +30 -18
  159. data/config/action_view_helpers/actionview/form_tag_helper/field_set_tag.yml +23 -15
  160. data/config/action_view_helpers/actionview/form_tag_helper/file_field_tag.yml +35 -22
  161. data/config/action_view_helpers/actionview/form_tag_helper/form_tag.yml +38 -24
  162. data/config/action_view_helpers/actionview/form_tag_helper/hidden_field_tag.yml +27 -17
  163. data/config/action_view_helpers/actionview/form_tag_helper/image_submit_tag.yml +31 -21
  164. data/config/action_view_helpers/actionview/form_tag_helper/label_tag.yml +33 -17
  165. data/config/action_view_helpers/actionview/form_tag_helper/month_field_tag.yml +27 -17
  166. data/config/action_view_helpers/actionview/form_tag_helper/number_field_tag.yml +47 -29
  167. data/config/action_view_helpers/actionview/form_tag_helper/password_field_tag.yml +27 -17
  168. data/config/action_view_helpers/actionview/form_tag_helper/radio_button_tag.yml +32 -20
  169. data/config/action_view_helpers/actionview/form_tag_helper/range_field_tag.yml +47 -29
  170. data/config/action_view_helpers/actionview/form_tag_helper/search_field_tag.yml +27 -17
  171. data/config/action_view_helpers/actionview/form_tag_helper/select_tag.yml +47 -29
  172. data/config/action_view_helpers/actionview/form_tag_helper/submit_tag.yml +33 -21
  173. data/config/action_view_helpers/actionview/form_tag_helper/telephone_field_tag.yml +28 -18
  174. data/config/action_view_helpers/actionview/form_tag_helper/text_field_tag.yml +27 -17
  175. data/config/action_view_helpers/actionview/form_tag_helper/textarea_tag.yml +31 -20
  176. data/config/action_view_helpers/actionview/form_tag_helper/time_field_tag.yml +27 -17
  177. data/config/action_view_helpers/actionview/form_tag_helper/url_field_tag.yml +27 -17
  178. data/config/action_view_helpers/actionview/form_tag_helper/utf8_enforcer_tag.yml +9 -6
  179. data/config/action_view_helpers/actionview/form_tag_helper/week_field_tag.yml +28 -18
  180. data/config/action_view_helpers/actionview/javascript_helper/escape_javascript.yml +16 -10
  181. data/config/action_view_helpers/actionview/javascript_helper/javascript_cdata_section.yml +9 -6
  182. data/config/action_view_helpers/actionview/javascript_helper/javascript_tag.yml +41 -27
  183. data/config/action_view_helpers/actionview/number_helper/number_to_currency.yml +29 -18
  184. data/config/action_view_helpers/actionview/number_helper/number_to_human.yml +25 -15
  185. data/config/action_view_helpers/actionview/number_helper/number_to_human_size.yml +20 -12
  186. data/config/action_view_helpers/actionview/number_helper/number_to_percentage.yml +20 -12
  187. data/config/action_view_helpers/actionview/number_helper/number_to_phone.yml +33 -20
  188. data/config/action_view_helpers/actionview/number_helper/number_with_delimiter.yml +21 -13
  189. data/config/action_view_helpers/actionview/number_helper/number_with_precision.yml +25 -15
  190. data/config/action_view_helpers/actionview/output_safety_helper/raw.yml +15 -9
  191. data/config/action_view_helpers/actionview/output_safety_helper/safe_join.yml +20 -12
  192. data/config/action_view_helpers/actionview/output_safety_helper/to_sentence.yml +24 -15
  193. data/config/action_view_helpers/actionview/record_identifier/dom_class.yml +20 -12
  194. data/config/action_view_helpers/actionview/record_identifier/dom_id.yml +20 -12
  195. data/config/action_view_helpers/actionview/record_identifier/dom_target.yml +15 -9
  196. data/config/action_view_helpers/actionview/record_identifier/model_name_from_record_or_class.yml +9 -6
  197. data/config/action_view_helpers/actionview/rendering_helper/render.yml +108 -22
  198. data/config/action_view_helpers/actionview/sanitize_helper/sanitize.yml +25 -15
  199. data/config/action_view_helpers/actionview/sanitize_helper/sanitize_css.yml +15 -9
  200. data/config/action_view_helpers/actionview/sanitize_helper/sanitizer_vendor.yml +9 -6
  201. data/config/action_view_helpers/actionview/sanitize_helper/strip_links.yml +15 -9
  202. data/config/action_view_helpers/actionview/sanitize_helper/strip_tags.yml +15 -9
  203. data/config/action_view_helpers/actionview/tag_helper/cdata_section.yml +15 -9
  204. data/config/action_view_helpers/actionview/tag_helper/content_tag.yml +59 -38
  205. data/config/action_view_helpers/actionview/tag_helper/escape_once.yml +15 -9
  206. data/config/action_view_helpers/actionview/tag_helper/tag.yml +54 -31
  207. data/config/action_view_helpers/actionview/tag_helper/token_list.yml +16 -10
  208. data/config/action_view_helpers/actionview/text_helper/concat.yml +15 -9
  209. data/config/action_view_helpers/actionview/text_helper/current_cycle.yml +15 -9
  210. data/config/action_view_helpers/actionview/text_helper/cycle.yml +23 -14
  211. data/config/action_view_helpers/actionview/text_helper/excerpt.yml +33 -20
  212. data/config/action_view_helpers/actionview/text_helper/highlight.yml +37 -18
  213. data/config/action_view_helpers/actionview/text_helper/pluralize.yml +30 -18
  214. data/config/action_view_helpers/actionview/text_helper/reset_cycle.yml +15 -9
  215. data/config/action_view_helpers/actionview/text_helper/safe_concat.yml +9 -6
  216. data/config/action_view_helpers/actionview/text_helper/simple_format.yml +33 -20
  217. data/config/action_view_helpers/actionview/text_helper/truncate.yml +38 -23
  218. data/config/action_view_helpers/actionview/text_helper/word_wrap.yml +25 -15
  219. data/config/action_view_helpers/actionview/translation_helper/debug_missing_translation.yml +9 -6
  220. data/config/action_view_helpers/actionview/translation_helper/localize.yml +26 -16
  221. data/config/action_view_helpers/actionview/translation_helper/translate.yml +31 -19
  222. data/config/action_view_helpers/actionview/url_helper/button_to.yml +57 -33
  223. data/config/action_view_helpers/actionview/url_helper/button_to_generates_button_tag.yml +9 -6
  224. data/config/action_view_helpers/actionview/url_helper/current_page?.yml +25 -15
  225. data/config/action_view_helpers/actionview/url_helper/link_to.yml +76 -53
  226. data/config/action_view_helpers/actionview/url_helper/link_to_if.yml +54 -20
  227. data/config/action_view_helpers/actionview/url_helper/link_to_unless.yml +54 -20
  228. data/config/action_view_helpers/actionview/url_helper/link_to_unless_current.yml +49 -17
  229. data/config/action_view_helpers/actionview/url_helper/mail_to.yml +60 -34
  230. data/config/action_view_helpers/actionview/url_helper/phone_to.yml +40 -22
  231. data/config/action_view_helpers/actionview/url_helper/sms_to.yml +45 -25
  232. data/config/action_view_helpers/actionview/url_helper/url_for.yml +15 -9
  233. data/config/action_view_helpers/importmap-rails/importmap_tags_helper/javascript_import_module_tag.yml +32 -0
  234. data/config/action_view_helpers/importmap-rails/importmap_tags_helper/javascript_importmap_module_preload_tags.yml +39 -0
  235. data/config/action_view_helpers/importmap-rails/importmap_tags_helper/javascript_importmap_tags.yml +35 -0
  236. data/config/action_view_helpers/importmap-rails/importmap_tags_helper/javascript_inline_importmap_tag.yml +32 -0
  237. data/config/action_view_helpers/importmap-rails/importmap_tags_helper/javascript_module_preload_tag.yml +35 -0
  238. data/config/action_view_helpers/turbo-rails/drive_helper/turbo_exempts_page_from_cache.yml +9 -6
  239. data/config/action_view_helpers/turbo-rails/drive_helper/turbo_exempts_page_from_cache_tag.yml +12 -8
  240. data/config/action_view_helpers/turbo-rails/drive_helper/turbo_exempts_page_from_preview.yml +9 -6
  241. data/config/action_view_helpers/turbo-rails/drive_helper/turbo_exempts_page_from_preview_tag.yml +12 -8
  242. data/config/action_view_helpers/turbo-rails/drive_helper/turbo_page_requires_reload.yml +9 -6
  243. data/config/action_view_helpers/turbo-rails/drive_helper/turbo_page_requires_reload_tag.yml +12 -8
  244. data/config/action_view_helpers/turbo-rails/drive_helper/turbo_refresh_method_tag.yml +17 -11
  245. data/config/action_view_helpers/turbo-rails/drive_helper/turbo_refresh_scroll_tag.yml +17 -11
  246. data/config/action_view_helpers/turbo-rails/drive_helper/turbo_refreshes_with.yml +20 -12
  247. data/config/action_view_helpers/turbo-rails/frames_helper/turbo_frame_tag.yml +54 -33
  248. data/config/action_view_helpers/turbo-rails/includes_helper/turbo_include_tags.yml +9 -6
  249. data/config/action_view_helpers/turbo-rails/streams_action_helper/turbo_stream_action_tag.yml +32 -20
  250. data/config/action_view_helpers/turbo-rails/streams_action_helper/turbo_stream_refresh_tag.yml +18 -11
  251. data/config/action_view_helpers/turbo-rails/streams_helper/turbo_stream.yml +9 -6
  252. data/config/action_view_helpers/turbo-rails/streams_helper/turbo_stream_from.yml +28 -18
  253. data/config/html_elements.yml +597 -0
  254. data/config/options.yml +1 -0
  255. data/config/slots/components.yml +52 -0
  256. data/config/state/kind.yml +61 -0
  257. data/config/state/operators.yml +27 -0
  258. data/config/state/predicates.yml +39 -0
  259. data/config/state/transforms.yml +18 -0
  260. data/config/view_context_methods/actionview/base/annotate_rendered_view_with_filenames.yml +4 -4
  261. data/config/view_context_methods/actionview/base/assign.yml +4 -4
  262. data/config/view_context_methods/actionview/base/assigns.yml +4 -4
  263. data/config/view_context_methods/actionview/base/automatically_disable_submit_tag.yml +4 -4
  264. data/config/view_context_methods/actionview/base/compiled_method_container.yml +4 -4
  265. data/config/view_context_methods/actionview/base/config.yml +4 -4
  266. data/config/view_context_methods/actionview/base/default_form_builder.yml +4 -4
  267. data/config/view_context_methods/actionview/base/default_formats.yml +4 -4
  268. data/config/view_context_methods/actionview/base/field_error_proc.yml +4 -4
  269. data/config/view_context_methods/actionview/base/formats.yml +4 -4
  270. data/config/view_context_methods/actionview/base/in_rendering_context.yml +4 -4
  271. data/config/view_context_methods/actionview/base/locale.yml +4 -4
  272. data/config/view_context_methods/actionview/base/lookup_context.yml +4 -4
  273. data/config/view_context_methods/actionview/base/output_buffer.yml +4 -4
  274. data/config/view_context_methods/actionview/base/prefix_partial_path_with_controller_namespace.yml +4 -4
  275. data/config/view_context_methods/actionview/base/remove_hidden_field_autocomplete.yml +4 -4
  276. data/config/view_context_methods/actionview/base/streaming_completion_on_exception.yml +4 -4
  277. data/config/view_context_methods/actionview/base/view_flow.yml +4 -4
  278. data/config/view_context_methods/actionview/base/view_paths.yml +4 -4
  279. data/config/view_context_methods/actionview/base/view_renderer.yml +4 -4
  280. data/config/view_context_methods/actionview/template/local_assigns.yml +4 -4
  281. data/config/view_context_methods/activemodel/conversion/convert_to_model.yml +4 -4
  282. data/config/view_context_methods/activesupport/benchmarkable/benchmark.yml +4 -4
  283. data/config.yml +1240 -790
  284. data/exe/herb +2 -0
  285. data/ext/herb/error_helpers.c +355 -17
  286. data/ext/herb/error_helpers.h +1 -1
  287. data/ext/herb/extconf.rb +4 -2
  288. data/ext/herb/extension.c +137 -89
  289. data/ext/herb/extension_helpers.c +81 -42
  290. data/ext/herb/extension_helpers.h +4 -1
  291. data/ext/herb/nodes.c +826 -358
  292. data/ext/herb/nodes.h +3 -2
  293. data/ext/herb/parser_options_helpers.c +151 -0
  294. data/ext/herb/parser_options_helpers.h +14 -0
  295. data/herb.gemspec +2 -2
  296. data/lib/herb/3.2/herb.so +0 -0
  297. data/lib/herb/3.3/herb.so +0 -0
  298. data/lib/herb/3.4/herb.so +0 -0
  299. data/lib/herb/4.0/herb.so +0 -0
  300. data/lib/herb/action_view/helper_registry.rb +1358 -62
  301. data/lib/herb/analysis/partial_declaration.rb +140 -0
  302. data/lib/herb/analysis/partial_index.rb +189 -0
  303. data/lib/herb/analysis/partial_resolution.rb +161 -0
  304. data/lib/herb/analysis/partial_resolver.rb +144 -0
  305. data/lib/herb/analysis/project_index.rb +152 -0
  306. data/lib/herb/{action_view → analysis}/render_analyzer.rb +287 -77
  307. data/lib/herb/analysis/render_graph/ancestor_chain.rb +27 -0
  308. data/lib/herb/analysis/render_graph/builder.rb +376 -0
  309. data/lib/herb/analysis/render_graph/call_frame.rb +9 -0
  310. data/lib/herb/analysis/render_graph/call_site_location.rb +23 -0
  311. data/lib/herb/analysis/render_graph/inferred_signature.rb +21 -0
  312. data/lib/herb/analysis/render_graph/partial_call_site.rb +40 -0
  313. data/lib/herb/analysis/render_graph/partial_context.rb +46 -0
  314. data/lib/herb/analysis/render_graph/template_roots.rb +31 -0
  315. data/lib/herb/analysis/render_graph.rb +285 -0
  316. data/lib/herb/analysis/ruby_locals_index/local.rb +25 -0
  317. data/lib/herb/analysis/ruby_locals_index/named_reference.rb +22 -0
  318. data/lib/herb/analysis/ruby_locals_index/offset_table.rb +44 -0
  319. data/lib/herb/analysis/ruby_locals_index/reference_collector.rb +80 -0
  320. data/lib/herb/analysis/ruby_locals_index/state_locals.rb +49 -0
  321. data/lib/herb/analysis/ruby_locals_index.rb +165 -0
  322. data/lib/herb/analysis/ruby_reference.rb +67 -0
  323. data/lib/herb/analysis/template_dependencies/dependency_collector.rb +179 -0
  324. data/lib/herb/analysis/template_dependencies/node_dependency_collector.rb +309 -0
  325. data/lib/herb/analysis/template_dependencies.rb +562 -0
  326. data/lib/herb/ast/erb_render_node.rb +26 -94
  327. data/lib/herb/ast/helpers.rb +90 -10
  328. data/lib/herb/ast/herb_directive_node.rb +18 -0
  329. data/lib/herb/ast/node.rb +32 -2
  330. data/lib/herb/ast/nodes.rb +1342 -105
  331. data/lib/herb/backend.rb +73 -0
  332. data/lib/herb/bootstrap.rb +3 -7
  333. data/lib/herb/cli.rb +550 -32
  334. data/lib/herb/colors.rb +14 -0
  335. data/lib/herb/configuration.rb +71 -35
  336. data/lib/herb/defaults.yml +2 -1
  337. data/lib/herb/dev/assets.rb +57 -0
  338. data/lib/herb/dev/classifier.rb +84 -0
  339. data/lib/herb/dev/embedded.rb +27 -0
  340. data/lib/herb/dev/pipeline.rb +305 -0
  341. data/lib/herb/dev/protocol.rb +221 -0
  342. data/lib/herb/dev/runner.rb +175 -175
  343. data/lib/herb/dev/server.rb +89 -26
  344. data/lib/herb/dev/server_entry.rb +41 -6
  345. data/lib/herb/dev/watcher.rb +181 -0
  346. data/lib/herb/dev.rb +163 -0
  347. data/lib/herb/diagnostic/formatter.rb +88 -0
  348. data/lib/herb/diagnostic.rb +172 -0
  349. data/lib/herb/diff/operation.rb +36 -0
  350. data/lib/herb/diff/result.rb +62 -0
  351. data/lib/herb/diff.rb +10 -0
  352. data/lib/herb/engine/collector.rb +62 -0
  353. data/lib/herb/engine/compiler.rb +346 -108
  354. data/lib/herb/engine/component_tags/constant_resolver.rb +28 -0
  355. data/lib/herb/engine/component_tags/partial_resolver.rb +54 -0
  356. data/lib/herb/engine/component_tags/resolver.rb +32 -0
  357. data/lib/herb/engine/component_tags/visitor.rb +231 -0
  358. data/lib/herb/engine/css_inliner/inliner.rb +101 -0
  359. data/lib/herb/engine/css_inliner/visitor.rb +174 -0
  360. data/lib/herb/engine/errors.rb +122 -0
  361. data/lib/herb/engine/helpers.rb +82 -0
  362. data/lib/herb/engine/inline_render/inliner.rb +122 -0
  363. data/lib/herb/engine/inline_render/visitor.rb +267 -0
  364. data/lib/herb/engine/runtime/entry.rb +62 -0
  365. data/lib/herb/engine/runtime/error_page.rb +362 -0
  366. data/lib/herb/engine/runtime/html_safe_assertions.rb +217 -0
  367. data/lib/herb/engine/runtime/journal/summary.rb +227 -0
  368. data/lib/herb/engine/runtime/journal.rb +379 -0
  369. data/lib/herb/engine/runtime/middleware.rb +212 -0
  370. data/lib/herb/engine/runtime/observations.rb +73 -0
  371. data/lib/herb/engine/runtime/report.rb +204 -0
  372. data/lib/herb/engine/runtime/session.rb +437 -0
  373. data/lib/herb/engine/runtime.rb +21 -0
  374. data/lib/herb/engine/scoped_style/channel.rb +66 -0
  375. data/lib/herb/engine/scoped_style/collector.rb +74 -0
  376. data/lib/herb/engine/scoped_style/visitor.rb +533 -0
  377. data/lib/herb/engine/slots/annotation.rb +98 -0
  378. data/lib/herb/engine/slots/bindings.rb +61 -0
  379. data/lib/herb/engine/slots/callee.rb +118 -0
  380. data/lib/herb/engine/slots/component_definitions.rb +67 -0
  381. data/lib/herb/engine/slots/components/async.rb +24 -0
  382. data/lib/herb/engine/slots/components/base.rb +132 -0
  383. data/lib/herb/engine/slots/components/deferred.rb +81 -0
  384. data/lib/herb/engine/slots/components/fallback.rb +27 -0
  385. data/lib/herb/engine/slots/components/fragment.rb +99 -0
  386. data/lib/herb/engine/slots/components/lazy.rb +24 -0
  387. data/lib/herb/engine/slots/components.rb +52 -0
  388. data/lib/herb/engine/slots/dependencies/channel.rb +72 -0
  389. data/lib/herb/engine/slots/dependencies.rb +269 -0
  390. data/lib/herb/engine/slots/dynamics_compiler.rb +854 -0
  391. data/lib/herb/engine/slots/identifier.rb +35 -0
  392. data/lib/herb/engine/slots/manifest/channel.rb +74 -0
  393. data/lib/herb/engine/slots/manifest/collector.rb +75 -0
  394. data/lib/herb/engine/slots/markers.rb +128 -0
  395. data/lib/herb/engine/slots/render_bindings.rb +141 -0
  396. data/lib/herb/engine/slots/schema_compiler.rb +94 -0
  397. data/lib/herb/engine/slots/state_anchor.rb +94 -0
  398. data/lib/herb/engine/slots/state_compiler.rb +1326 -0
  399. data/lib/herb/engine/slots/state_directives.rb +854 -0
  400. data/lib/herb/engine/slots/state_kinds.rb +54 -0
  401. data/lib/herb/engine/slots/state_operators.rb +36 -0
  402. data/lib/herb/engine/slots/state_overrides.rb +79 -0
  403. data/lib/herb/engine/slots/state_predicates.rb +65 -0
  404. data/lib/herb/engine/slots/state_transforms.rb +42 -0
  405. data/lib/herb/engine/slots/statics.rb +185 -0
  406. data/lib/herb/engine/slots/subtree.rb +82 -0
  407. data/lib/herb/engine/slots/subtree_compiler.rb +255 -0
  408. data/lib/herb/engine/slots/types.rb +42 -0
  409. data/lib/herb/engine/slots/visitor.rb +2256 -0
  410. data/lib/herb/engine/validators/accessibility_validator.rb +3 -3
  411. data/lib/herb/engine/validators/base.rb +36 -0
  412. data/lib/herb/engine/validators/generator_template_validator.rb +39 -0
  413. data/lib/herb/engine/validators/nesting_validator.rb +3 -3
  414. data/lib/herb/engine/validators/render_validator.rb +13 -33
  415. data/lib/herb/engine/validators/security_validator.rb +3 -17
  416. data/lib/herb/engine/validators.rb +43 -0
  417. data/lib/herb/engine/visitors/auto_close_omitted_tags_visitor.rb +48 -0
  418. data/lib/herb/engine/visitors/content_for_visitor.rb +127 -0
  419. data/lib/herb/engine/{debug_visitor.rb → visitors/debug_visitor.rb} +121 -93
  420. data/lib/herb/engine/visitors/html_safe_assertions_visitor.rb +281 -0
  421. data/lib/herb/engine/visitors/instrumentation_visitor.rb +290 -0
  422. data/lib/herb/engine/visitors/optimize_visitor.rb +728 -0
  423. data/lib/herb/engine/visitors/remove_comments_visitor.rb +106 -0
  424. data/lib/herb/engine/visitors/source_attribution_visitor.rb +177 -0
  425. data/lib/herb/engine.rb +218 -257
  426. data/lib/herb/ensure_installed.rb +43 -0
  427. data/lib/herb/errors.rb +646 -157
  428. data/lib/herb/fingerprint.rb +82 -0
  429. data/lib/herb/html/elements.rb +18 -0
  430. data/lib/herb/html/util.rb +21 -2
  431. data/lib/herb/lex_result.rb +0 -10
  432. data/lib/herb/locate.rb +163 -0
  433. data/lib/herb/location.rb +20 -0
  434. data/lib/herb/parse_result.rb +17 -11
  435. data/lib/herb/parser_options.rb +65 -46
  436. data/lib/herb/position.rb +19 -0
  437. data/lib/herb/prism_inspect.rb +1 -4
  438. data/lib/herb/project.rb +28 -15
  439. data/lib/herb/range.rb +5 -0
  440. data/lib/herb/result.rb +2 -2
  441. data/lib/herb/ruby_program.rb +110 -0
  442. data/lib/herb/source_path.rb +232 -0
  443. data/lib/herb/token.rb +14 -3
  444. data/lib/herb/version.rb +1 -1
  445. data/lib/herb/visitor/context/origin.rb +52 -0
  446. data/lib/herb/visitor/context/replacements.rb +59 -0
  447. data/lib/herb/visitor/context.rb +169 -0
  448. data/lib/herb/visitor/context_aware.rb +45 -0
  449. data/lib/herb/visitor/diagnostics.rb +148 -0
  450. data/lib/herb/visitor/experimental.rb +33 -0
  451. data/lib/herb/visitor/parser_option_requirements.rb +151 -0
  452. data/lib/herb/visitor/stack.rb +192 -0
  453. data/lib/herb/visitor.rb +47 -1
  454. data/lib/herb/warnings.rb +25 -0
  455. data/lib/herb.rb +74 -63
  456. data/sig/herb/action_view/helper_registry.rbs +82 -10
  457. data/sig/herb/analysis/partial_declaration.rbs +80 -0
  458. data/sig/herb/analysis/partial_index.rbs +66 -0
  459. data/sig/herb/analysis/partial_resolution.rbs +57 -0
  460. data/sig/herb/analysis/partial_resolver.rbs +76 -0
  461. data/sig/herb/analysis/project_index.rbs +57 -0
  462. data/sig/herb/{action_view → analysis}/render_analyzer.rbs +25 -4
  463. data/sig/herb/analysis/render_graph/ancestor_chain.rbs +22 -0
  464. data/sig/herb/analysis/render_graph/builder.rbs +180 -0
  465. data/sig/herb/analysis/render_graph/call_frame.rbs +26 -0
  466. data/sig/herb/analysis/render_graph/call_site_location.rbs +28 -0
  467. data/sig/herb/analysis/render_graph/inferred_signature.rbs +27 -0
  468. data/sig/herb/analysis/render_graph/partial_call_site.rbs +36 -0
  469. data/sig/herb/analysis/render_graph/partial_context.rbs +31 -0
  470. data/sig/herb/analysis/render_graph/template_roots.rbs +32 -0
  471. data/sig/herb/analysis/render_graph.rbs +83 -0
  472. data/sig/herb/analysis/ruby_locals_index/local.rbs +21 -0
  473. data/sig/herb/analysis/ruby_locals_index/named_reference.rbs +20 -0
  474. data/sig/herb/analysis/ruby_locals_index/offset_table.rbs +26 -0
  475. data/sig/herb/analysis/ruby_locals_index/reference_collector.rbs +40 -0
  476. data/sig/herb/analysis/ruby_locals_index/state_locals.rbs +19 -0
  477. data/sig/herb/analysis/ruby_locals_index.rbs +62 -0
  478. data/sig/herb/analysis/ruby_reference.rbs +28 -0
  479. data/sig/herb/analysis/template_dependencies/dependency_collector.rbs +52 -0
  480. data/sig/herb/analysis/template_dependencies/node_dependency_collector.rbs +81 -0
  481. data/sig/herb/analysis/template_dependencies.rbs +125 -0
  482. data/sig/herb/ast/erb_render_node.rbs +10 -2
  483. data/sig/herb/ast/helpers.rbs +31 -1
  484. data/sig/herb/ast/herb_directive_node.rbs +13 -0
  485. data/sig/herb/ast/node.rbs +9 -0
  486. data/sig/herb/ast/nodes.rbs +662 -89
  487. data/sig/herb/backend.rbs +52 -0
  488. data/sig/herb/colors.rbs +3 -0
  489. data/sig/herb/configuration.rbs +27 -3
  490. data/sig/herb/dev/assets.rbs +27 -0
  491. data/sig/herb/dev/classifier.rbs +57 -0
  492. data/sig/herb/dev/embedded.rbs +21 -0
  493. data/sig/herb/dev/pipeline.rbs +118 -0
  494. data/sig/herb/dev/protocol.rbs +78 -0
  495. data/sig/herb/dev/runner.rbs +61 -23
  496. data/sig/herb/dev/server.rbs +49 -22
  497. data/sig/herb/dev/server_entry.rbs +46 -21
  498. data/sig/herb/dev/watcher.rbs +84 -0
  499. data/sig/herb/dev.rbs +58 -0
  500. data/sig/herb/diagnostic/formatter.rbs +28 -0
  501. data/sig/herb/diagnostic.rbs +88 -0
  502. data/sig/herb/diff/operation.rbs +36 -0
  503. data/sig/herb/diff/result.rbs +36 -0
  504. data/sig/herb/diff.rbs +6 -0
  505. data/sig/herb/engine/collector.rbs +48 -0
  506. data/sig/herb/engine/compiler.rbs +62 -23
  507. data/sig/herb/engine/component_tags/constant_resolver.rbs +19 -0
  508. data/sig/herb/engine/component_tags/partial_resolver.rbs +30 -0
  509. data/sig/herb/engine/component_tags/resolver.rbs +25 -0
  510. data/sig/herb/engine/component_tags/visitor.rbs +69 -0
  511. data/sig/herb/engine/css_inliner/inliner.rbs +65 -0
  512. data/sig/herb/engine/css_inliner/visitor.rbs +87 -0
  513. data/sig/herb/engine/errors.rbs +68 -0
  514. data/sig/herb/engine/helpers.rbs +28 -0
  515. data/sig/herb/engine/inline_render/inliner.rbs +39 -0
  516. data/sig/herb/engine/inline_render/visitor.rbs +104 -0
  517. data/sig/herb/engine/runtime/entry.rbs +43 -0
  518. data/sig/herb/engine/runtime/error_page.rbs +115 -0
  519. data/sig/herb/engine/runtime/html_safe_assertions.rbs +99 -0
  520. data/sig/herb/engine/runtime/journal/summary.rbs +172 -0
  521. data/sig/herb/engine/runtime/journal.rbs +126 -0
  522. data/sig/herb/engine/runtime/middleware.rbs +96 -0
  523. data/sig/herb/engine/runtime/observations.rbs +38 -0
  524. data/sig/herb/engine/runtime/report.rbs +97 -0
  525. data/sig/herb/engine/runtime/session.rbs +233 -0
  526. data/sig/herb/engine/runtime.rbs +14 -0
  527. data/sig/herb/engine/scoped_style/channel.rbs +45 -0
  528. data/sig/herb/engine/scoped_style/collector.rbs +45 -0
  529. data/sig/herb/engine/scoped_style/visitor.rbs +220 -0
  530. data/sig/herb/engine/slots/annotation.rbs +72 -0
  531. data/sig/herb/engine/slots/bindings.rbs +34 -0
  532. data/sig/herb/engine/slots/callee.rbs +62 -0
  533. data/sig/herb/engine/slots/component_definitions.rbs +19 -0
  534. data/sig/herb/engine/slots/components/async.rbs +20 -0
  535. data/sig/herb/engine/slots/components/base.rbs +60 -0
  536. data/sig/herb/engine/slots/components/deferred.rbs +29 -0
  537. data/sig/herb/engine/slots/components/fallback.rbs +21 -0
  538. data/sig/herb/engine/slots/components/fragment.rbs +34 -0
  539. data/sig/herb/engine/slots/components/lazy.rbs +20 -0
  540. data/sig/herb/engine/slots/components.rbs +30 -0
  541. data/sig/herb/engine/slots/dependencies/channel.rbs +51 -0
  542. data/sig/herb/engine/slots/dependencies.rbs +94 -0
  543. data/sig/herb/engine/slots/dynamics_compiler.rbs +349 -0
  544. data/sig/herb/engine/slots/identifier.rbs +19 -0
  545. data/sig/herb/engine/slots/manifest/channel.rbs +49 -0
  546. data/sig/herb/engine/slots/manifest/collector.rbs +45 -0
  547. data/sig/herb/engine/slots/markers.rbs +85 -0
  548. data/sig/herb/engine/slots/render_bindings.rbs +69 -0
  549. data/sig/herb/engine/slots/schema_compiler.rbs +62 -0
  550. data/sig/herb/engine/slots/state_anchor.rbs +41 -0
  551. data/sig/herb/engine/slots/state_compiler.rbs +258 -0
  552. data/sig/herb/engine/slots/state_directives.rbs +278 -0
  553. data/sig/herb/engine/slots/state_kinds.rbs +24 -0
  554. data/sig/herb/engine/slots/state_operators.rbs +19 -0
  555. data/sig/herb/engine/slots/state_overrides.rbs +33 -0
  556. data/sig/herb/engine/slots/state_predicates.rbs +16 -0
  557. data/sig/herb/engine/slots/state_transforms.rbs +15 -0
  558. data/sig/herb/engine/slots/statics.rbs +67 -0
  559. data/sig/herb/engine/slots/subtree.rbs +49 -0
  560. data/sig/herb/engine/slots/subtree_compiler.rbs +130 -0
  561. data/sig/herb/engine/slots/types.rbs +46 -0
  562. data/sig/herb/engine/slots/visitor.rbs +599 -0
  563. data/sig/herb/engine/validators/accessibility_validator.rbs +1 -1
  564. data/sig/herb/engine/validators/base.rbs +28 -0
  565. data/sig/herb/engine/validators/generator_template_validator.rbs +19 -0
  566. data/sig/herb/engine/validators/nesting_validator.rbs +1 -1
  567. data/sig/herb/engine/validators/render_validator.rbs +2 -6
  568. data/sig/herb/engine/validators/security_validator.rbs +1 -3
  569. data/sig/herb/engine/validators.rbs +21 -0
  570. data/sig/herb/engine/visitors/auto_close_omitted_tags_visitor.rbs +26 -0
  571. data/sig/herb/engine/visitors/content_for_visitor.rbs +52 -0
  572. data/sig/herb/engine/{debug_visitor.rbs → visitors/debug_visitor.rbs} +26 -15
  573. data/sig/herb/engine/visitors/html_safe_assertions_visitor.rbs +100 -0
  574. data/sig/herb/engine/visitors/instrumentation_visitor.rbs +111 -0
  575. data/sig/herb/engine/visitors/optimize_visitor.rbs +246 -0
  576. data/sig/herb/engine/visitors/remove_comments_visitor.rbs +66 -0
  577. data/sig/herb/engine/visitors/source_attribution_visitor.rbs +90 -0
  578. data/sig/herb/engine.rbs +47 -41
  579. data/sig/herb/ensure_installed.rbs +9 -0
  580. data/sig/herb/errors.rbs +293 -0
  581. data/sig/herb/fingerprint.rbs +37 -0
  582. data/sig/herb/html/elements.rbs +19 -0
  583. data/sig/herb/html/util.rbs +15 -1
  584. data/sig/herb/lex_result.rbs +0 -6
  585. data/sig/herb/locate.rbs +89 -0
  586. data/sig/herb/location.rbs +12 -0
  587. data/sig/herb/parse_result.rbs +10 -8
  588. data/sig/herb/parser_options.rbs +47 -21
  589. data/sig/herb/position.rbs +11 -0
  590. data/sig/herb/range.rbs +3 -0
  591. data/sig/herb/ruby_program.rbs +51 -0
  592. data/sig/herb/source_path.rbs +132 -0
  593. data/sig/herb/token.rbs +5 -2
  594. data/sig/herb/visitor/context/origin.rbs +51 -0
  595. data/sig/herb/visitor/context/replacements.rbs +39 -0
  596. data/sig/herb/visitor/context.rbs +83 -0
  597. data/sig/herb/visitor/context_aware.rbs +32 -0
  598. data/sig/herb/visitor/diagnostics.rbs +82 -0
  599. data/sig/herb/visitor/experimental.rbs +23 -0
  600. data/sig/herb/visitor/parser_option_requirements.rbs +76 -0
  601. data/sig/herb/visitor/stack.rbs +91 -0
  602. data/sig/herb/visitor.rbs +22 -0
  603. data/sig/herb/warnings.rbs +10 -0
  604. data/sig/herb.rbs +27 -10
  605. data/sig/serialized_ast_errors.rbs +58 -1
  606. data/sig/serialized_ast_nodes.rbs +58 -2
  607. data/src/analyze/action_view/attribute_extraction_helpers.c +73 -36
  608. data/src/analyze/action_view/generated_handlers.c +37 -1
  609. data/src/analyze/action_view/generated_handlers.h +2 -1
  610. data/src/analyze/action_view/helper_registry.c +1353 -58
  611. data/src/analyze/action_view/registry.c +10 -17
  612. data/src/analyze/action_view/stylesheet_link_tag.c +40 -0
  613. data/src/analyze/action_view/tag_helper_node_builders.c +57 -0
  614. data/src/analyze/action_view/tag_helpers.c +423 -93
  615. data/src/analyze/analyze.c +301 -64
  616. data/src/analyze/analyze_helpers.c +420 -23
  617. data/src/analyze/builders.c +79 -51
  618. data/src/analyze/conditional_elements.c +13 -8
  619. data/src/analyze/conditional_open_tags.c +11 -5
  620. data/src/analyze/control_type.c +16 -1
  621. data/src/analyze/herb_directives.c +701 -0
  622. data/src/analyze/invalid_structures.c +11 -7
  623. data/src/analyze/iteration_nodes.c +306 -0
  624. data/src/analyze/missing_end.c +116 -32
  625. data/src/analyze/parse_errors.c +8 -3
  626. data/src/analyze/postfix_conditionals.c +98 -63
  627. data/src/analyze/prism_annotate.c +13 -4
  628. data/src/analyze/render_nodes.c +345 -123
  629. data/src/analyze/strict_locals.c +30 -26
  630. data/src/analyze/ternary_conditionals.c +95 -70
  631. data/src/analyze/transform.c +43 -1
  632. data/src/ast/ast_node.c +3 -13
  633. data/src/ast/ast_nodes.c +911 -112
  634. data/src/ast/ast_pretty_print.c +161 -2
  635. data/src/diff/herb_diff.c +8 -0
  636. data/src/diff/herb_diff_attributes.c +1 -0
  637. data/src/diff/herb_diff_children.c +4 -3
  638. data/src/diff/herb_diff_helpers.c +7 -1
  639. data/src/diff/herb_diff_nodes.c +186 -71
  640. data/src/diff/herb_hash_tree.c +99 -1
  641. data/src/errors.c +1096 -128
  642. data/src/extract.c +30 -8
  643. data/src/herb.c +30 -11
  644. data/src/include/analyze/action_view/attribute_extraction_helpers.h +1 -1
  645. data/src/include/analyze/action_view/helper_registry.h +28 -4
  646. data/src/include/analyze/action_view/tag_helper_handler.h +1 -1
  647. data/src/include/analyze/action_view/tag_helper_node_builders.h +7 -0
  648. data/src/include/analyze/analyze.h +11 -0
  649. data/src/include/analyze/builders.h +16 -0
  650. data/src/include/analyze/helpers.h +23 -2
  651. data/src/include/analyze/herb_directive_kinds.h +41 -0
  652. data/src/include/analyze/herb_directives.h +14 -0
  653. data/src/include/analyze/iteration_nodes.h +11 -0
  654. data/src/include/analyze/prism_annotate.h +3 -3
  655. data/src/include/analyze/ternary_conditionals.h +2 -0
  656. data/src/include/ast/ast_node.h +1 -5
  657. data/src/include/ast/ast_nodes.h +76 -2
  658. data/src/include/ast/ast_pretty_print.h +1 -1
  659. data/src/include/diff/herb_diff.h +11 -0
  660. data/src/include/errors.h +156 -39
  661. data/src/include/extract.h +11 -0
  662. data/src/include/herb.h +6 -0
  663. data/src/include/lexer/erb_openers.h +29 -0
  664. data/src/include/lexer/lexer_peek_helpers.h +8 -1
  665. data/src/include/lexer/lexer_struct.h +4 -0
  666. data/src/include/lexer/token.h +3 -0
  667. data/src/include/lexer/token_struct.h +8 -6
  668. data/src/include/lib/hb_allocator.h +2 -1
  669. data/src/include/lib/hb_array.h +2 -0
  670. data/src/include/lib/hb_foreach.h +1 -1
  671. data/src/include/lib/hb_string.h +7 -0
  672. data/src/include/parser/dot_notation.h +1 -1
  673. data/src/include/parser/foreign_content_elements.h +32 -0
  674. data/src/include/parser/parser.h +16 -30
  675. data/src/include/parser/parser_helpers.h +13 -11
  676. data/src/include/parser/parser_options.h +41 -0
  677. data/src/include/prism/ruby_parser.h +6 -0
  678. data/src/include/util/html_elements.h +85 -0
  679. data/src/include/util/html_util.h +1 -0
  680. data/src/include/version.h +1 -1
  681. data/src/lexer/lexer_peek_helpers.c +15 -1
  682. data/src/lexer/token.c +83 -1
  683. data/src/lexer.c +196 -12
  684. data/src/lib/hb_allocator.c +2 -0
  685. data/src/lib/hb_array.c +26 -0
  686. data/src/lib/hb_string.c +26 -0
  687. data/src/main.c +1 -1
  688. data/src/parser/dot_notation.c +4 -3
  689. data/src/parser/match_tags.c +66 -1
  690. data/src/parser/parser_helpers.c +69 -37
  691. data/src/parser.c +606 -383
  692. data/src/parser_options_defaults.c +30 -0
  693. data/src/prism/prism_helpers.c +3 -0
  694. data/src/prism/ruby_parser.c +49 -0
  695. data/src/util/html_util.c +11 -58
  696. data/src/visitor.c +77 -1
  697. data/templates/ext/herb/error_helpers.c.erb +1 -1
  698. data/templates/ext/herb/nodes.c.erb +18 -13
  699. data/templates/ext/herb/nodes.h.erb +2 -1
  700. data/templates/ext/herb/parser_options_helpers.c.erb +69 -0
  701. data/templates/ext/herb/parser_options_helpers.h.erb +11 -0
  702. data/templates/java/nodes.c.erb +20 -16
  703. data/templates/java/nodes.h.erb +3 -2
  704. data/templates/java/org/herb/ParserOptions.java.erb +24 -0
  705. data/templates/java/org/herb/ast/HelperRegistry.java.erb +67 -31
  706. data/templates/java/org/herb/ast/HelperType.java.erb +29 -0
  707. data/templates/java/org/herb/ast/Nodes.java.erb +11 -7
  708. data/templates/java/parser_options_helpers.c.erb +45 -0
  709. data/templates/java/parser_options_helpers.h.erb +10 -0
  710. data/templates/javascript/packages/client/src/state-kinds.ts.erb +49 -0
  711. data/templates/javascript/packages/client/src/state-operators.ts.erb +15 -0
  712. data/templates/javascript/packages/client/src/state-predicates.ts.erb +27 -0
  713. data/templates/javascript/packages/client/src/state-transforms.ts.erb +19 -0
  714. data/templates/javascript/packages/core/src/action-view-helpers.ts.erb +47 -0
  715. data/templates/javascript/packages/core/src/built-in-components.ts.erb +67 -0
  716. data/templates/javascript/packages/core/src/errors.ts.erb +9 -3
  717. data/templates/javascript/packages/core/src/foreign-content-elements.ts.erb +18 -0
  718. data/templates/javascript/packages/core/src/html-constants.ts.erb +32 -0
  719. data/templates/javascript/packages/core/src/html-elements.ts.erb +41 -0
  720. data/templates/javascript/packages/core/src/node-type-guards.ts.erb +11 -7
  721. data/templates/javascript/packages/core/src/nodes.ts.erb +82 -19
  722. data/templates/javascript/packages/core/src/parser-options.ts.erb +41 -0
  723. data/templates/javascript/packages/core/src/visitor.ts.erb +1 -1
  724. data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +3 -3
  725. data/templates/javascript/packages/node/extension/nodes.cpp.erb +17 -12
  726. data/templates/javascript/packages/node/extension/nodes.h.erb +3 -3
  727. data/templates/javascript/packages/node/extension/parser_options_helpers.cpp.erb +41 -0
  728. data/templates/javascript/packages/node/extension/parser_options_helpers.h.erb +12 -0
  729. data/templates/lib/herb/action_view/helper_registry.rb.erb +77 -3
  730. data/templates/lib/herb/ast/nodes.rb.erb +16 -6
  731. data/templates/lib/herb/engine/slots/component_definitions.rb.erb +38 -0
  732. data/templates/lib/herb/engine/slots/state_kinds.rb.erb +37 -0
  733. data/templates/lib/herb/engine/slots/state_operators.rb.erb +26 -0
  734. data/templates/lib/herb/engine/slots/state_predicates.rb.erb +39 -0
  735. data/templates/lib/herb/engine/slots/state_transforms.rb.erb +27 -0
  736. data/templates/lib/herb/errors.rb.erb +34 -6
  737. data/templates/lib/herb/html/elements.rb.erb +12 -0
  738. data/templates/lib/herb/parser_options.rb.erb +32 -0
  739. data/templates/lib/herb/visitor.rb.erb +7 -1
  740. data/templates/rust/herb-printer/src/printer_visitor.rs.erb +14 -0
  741. data/templates/rust/src/action_view_helpers.rs.erb +38 -0
  742. data/templates/rust/src/ast/nodes.rs.erb +24 -31
  743. data/templates/rust/src/errors.rs.erb +1 -1
  744. data/templates/rust/src/nodes.rs.erb +58 -26
  745. data/templates/rust/src/parser_options.rs.erb +16 -0
  746. data/templates/rust/src/prism/generated_deserialize.rs.erb +109 -0
  747. data/templates/rust/src/prism/generated_prettyprint.rs.erb +153 -0
  748. data/templates/rust/src/union_types.rs.erb +7 -1
  749. data/templates/rust/src/visitor.rs.erb +1 -1
  750. data/templates/src/analyze/action_view/helper_registry.c.erb +22 -0
  751. data/templates/src/analyze/missing_end.c.erb +13 -5
  752. data/templates/src/ast/ast_nodes.c.erb +41 -2
  753. data/templates/src/diff/herb_diff_nodes.c.erb +44 -8
  754. data/templates/src/errors.c.erb +8 -3
  755. data/templates/src/include/analyze/action_view/helper_registry.h.erb +19 -0
  756. data/templates/src/include/analyze/herb_directive_kinds.h.erb +25 -0
  757. data/templates/src/include/errors.h.erb +3 -1
  758. data/templates/src/include/parser/foreign_content_elements.h.erb +23 -0
  759. data/templates/src/include/parser/parser_options.h.erb +21 -0
  760. data/templates/src/include/util/html_elements.h.erb +28 -0
  761. data/templates/src/parser_options_defaults.c.erb +9 -0
  762. data/templates/template.rb +564 -9
  763. data/templates/wasm/error_helpers.cpp.erb +4 -4
  764. data/templates/wasm/nodes.cpp.erb +12 -12
  765. data/templates/wasm/nodes.h.erb +3 -3
  766. data/templates/wasm/parser_options_helpers.cpp.erb +25 -0
  767. data/templates/wasm/parser_options_helpers.h.erb +12 -0
  768. metadata +306 -27
  769. data/config/action_view_helpers/actionview/form_helper/button.yml +0 -38
  770. data/config/action_view_helpers/actionview/form_helper/submit.yml +0 -35
  771. data/lib/herb/ast.rb +0 -7
  772. data/lib/herb/diff_operation.rb +0 -34
  773. data/lib/herb/diff_result.rb +0 -59
  774. data/lib/herb/engine/error_formatter.rb +0 -432
  775. data/lib/herb/engine/parser_error_overlay.rb +0 -773
  776. data/lib/herb/engine/validation_error_overlay.rb +0 -182
  777. data/lib/herb/engine/validation_errors.rb +0 -65
  778. data/lib/herb/engine/validator.rb +0 -80
  779. data/sig/herb/ast.rbs +0 -6
  780. data/sig/herb/diff_operation.rbs +0 -34
  781. data/sig/herb/diff_result.rbs +0 -34
  782. data/sig/herb/engine/debug.rbs +0 -38
  783. data/sig/herb/engine/error_formatter.rbs +0 -47
  784. data/sig/herb/engine/parser_error_overlay.rbs +0 -41
  785. data/sig/herb/engine/validation_error_overlay.rbs +0 -35
  786. data/sig/herb/engine/validation_errors.rbs +0 -45
  787. data/sig/herb/engine/validator.rbs +0 -41
  788. data/sig/herb_c_extension.rbs +0 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 324a784d4d391abeca0b60cd659b9af661827b66e9a36d23f2373293dde181de
4
- data.tar.gz: 33aa8128732ad902900f7a607b4ab20ba9c74b6d0b4797624c7b7b581a8138b3
3
+ metadata.gz: a76c23491d714f7670178192406464a9dd5435a4f227f8b4d3f9f6e0738513c4
4
+ data.tar.gz: 0da055fc45751f85ded8ea807a7e3516dcf59bc830eedab8d17437f135844008
5
5
  SHA512:
6
- metadata.gz: 2f34c7109dfaa3a056ffb1ce20b88ff4a721cf8442a32e20d8602aacffa0189ff3bb60488b8ce840afc2194362fc4e7abe719f9ea1cc992623578f9e8c7df5aa
7
- data.tar.gz: cf5911519352315f85061855f5499c432e44f65ba09e976be72740b52f634cbcb4ff6d972df2a383619a1c1b74e473dc83da30788b2a028a453d577a95a859be
6
+ metadata.gz: 481a5d260bfe5fa13dfd57c5e8115c0a0555cf4e162bc3296157e515b2c3ed8f6da957e1f7b018e7bafe640316339a62a8c27965cde50669745f714589b0df2e
7
+ data.tar.gz: f2d91e8a8b9a80743d5d58d0c067a53e817ed67c49553af41af1a9b916f7300d3829816b99b2e442868753efaea7bacb83e21287353b8d7f8316d7778eb83de1
data/Makefile CHANGED
@@ -3,7 +3,7 @@ test_exec = run_herb_tests
3
3
 
4
4
  sources = $(shell find src -name '*.c')
5
5
  headers = $(shell find src -name '*.h')
6
- objects = $(sources:.c=.o)
6
+ objects = $(sources:%.c=$(obj_dir)/%.o)
7
7
 
8
8
  extension_sources = $(wildcard ext/**/*.c)
9
9
  extension_headers = $(wildcard ext/**/*.h)
@@ -17,8 +17,8 @@ nodejs_extension_files = $(wildcard node/**/*.cpp) $(wildcard node/**/*.h) $(wil
17
17
  project_and_extension_files = $(project_files) $(extension_files) $(nodejs_extension_files)
18
18
 
19
19
  test_sources = $(wildcard test/**/*.c)
20
- test_objects = $(test_sources:.c=.o)
21
- non_main_objects = $(filter-out src/main.o, $(objects))
20
+ test_objects = $(test_sources:%.c=$(obj_dir)/%.o)
21
+ non_main_objects = $(filter-out $(obj_dir)/src/main.o, $(objects))
22
22
 
23
23
  bench_allocs_exec = bench_allocs
24
24
  bench_allocs_source = bench/bench_allocs.c
@@ -29,6 +29,7 @@ static_lib_name = $(build_dir)/lib$(exec).a
29
29
  ruby_extension = ext/herb/$(lib_name)
30
30
 
31
31
  build_dir = build
32
+ obj_dir = $(build_dir)/obj
32
33
  $(shell mkdir -p $(build_dir))
33
34
 
34
35
  os := $(shell uname -s)
@@ -95,10 +96,18 @@ $(lib_name): $(objects)
95
96
  $(static_lib_name): $(objects)
96
97
  ar rcs $(static_lib_name) $(objects)
97
98
 
98
- src/%.o: src/%.c templates
99
+ # Objects live outside src/ and test/ so they cannot shadow the flat object names
100
+ # ext/herb/extconf.rb resolves through $VPATH; the find clears ones older builds left
101
+ $(obj_dir):
102
+ @mkdir -p $(obj_dir)
103
+ @find src test -name '*.o' -delete
104
+
105
+ $(obj_dir)/src/%.o: src/%.c templates | $(obj_dir)
106
+ @mkdir -p $(dir $@)
99
107
  $(cc) -c $(flags) -fPIC $< -o $@
100
108
 
101
- test/%.o: test/%.c templates prism
109
+ $(obj_dir)/test/%.o: test/%.c templates prism | $(obj_dir)
110
+ @mkdir -p $(dir $@)
102
111
  $(cc) -c $(test_cflags) $(test_flags) $(prism_flags) $< -o $@
103
112
 
104
113
  .PHONY: test
@@ -113,7 +122,8 @@ bench_allocs: $(non_main_objects)
113
122
  .PHONY: clean
114
123
  clean:
115
124
  rm -f $(exec) $(test_exec) $(bench_allocs_exec) $(lib_name) $(shared_lib_name) $(ruby_extension)
116
- rm -rf $(objects) $(test_objects) $(extension_objects) lib/herb/*.bundle tmp
125
+ rm -rf $(obj_dir) $(extension_objects) lib/herb/*.bundle tmp
126
+ find src test -name '*.o' -delete
117
127
  rm -rf $(prism_path)
118
128
  rake prism:clean
119
129
 
data/README.md CHANGED
@@ -4,9 +4,11 @@
4
4
 
5
5
  <h2 align="center">Herb</h2>
6
6
 
7
- <h4 align="center">The modern HTML+ERB Toolchain</h4>
7
+ <h4 align="center">A modern templating language for the HTML+ERB you already have.</h4>
8
8
 
9
- <div align="center">An ecosystem of powerful and seamless developer tools for HTML+ERB (HTML + Embedded Ruby) templates.</div><br/>
9
+ <div align="center">One language and toolchain that understands your HTML and Ruby together.</div><br/>
10
+
11
+ <div align="center">Lint · Format · Analyze · Render · Tooling</div><br/>
10
12
 
11
13
  <p align="center">
12
14
  <a href="https://rubygems.org/gems/herb"><img alt="Gem Version" src="https://img.shields.io/gem/v/herb"></a>
@@ -21,153 +23,68 @@
21
23
  <a href="https://github.com/marcoroth/herb/issues"><img alt="Issues" src="https://img.shields.io/github/issues/marcoroth/herb"></a>
22
24
  </p>
23
25
 
24
- <br/><br/><br/>
25
-
26
- ## What is Herb?
27
-
28
- **Herb** is a powerful and seamless HTML-aware ERB toolchain and an ecosystem of developer tools built specifically for **HTML+ERB** (`.html.erb`) files. It is designed to simplify and enhance the experience of working with HTML+ERB templates through precise, accurate tooling.
29
-
30
- **Parser**
31
-
32
- At the core of the Herb ecosystem is the **Herb Parser**, a fast, portable, and HTML-aware ERB parser written in C. The parser generates a detailed, accurate syntax tree that serves as the foundation for reliable code analysis, transformations, and developer tooling.
33
-
34
- **Toolchain**
35
-
36
- The Herb toolchain includes **developer tools** (CLI, language server, formatter, linter, browser dev tools), **language bindings** (for Ruby, Node.js, Java, Rust, and the Browser using WebAssembly), and **utility libraries** (language service, highlighter, minifier, printer).
37
-
38
- All these components leverage the Herb Parser's syntax tree to provide consistent, accurate, and helpful tooling experiences.
39
-
40
- **Engine**
41
-
42
- `Herb::Engine` is a new, HTML-aware ERB rendering engine built on the Herb Parser. It is designed to be API-compatible with [`Erubi::Engine`](https://github.com/jeremyevans/erubi) while adding structural awareness of HTML+ERB content, enabling features like HTML validation, security checks, and precise error reporting.
43
-
44
- The Engine powers **ReActionView** and lays the foundation for a modern view layer for Rails and other Ruby web frameworks.
45
-
46
- | **[ReActionView](https://reactionview.dev)** <br> 🌱 A new ActionView-compatible ERB engine with modern DX, re-imagined with `Herb::Engine`. |
47
- | --- |
48
- | [GitHub](https://github.com/marcoroth/reactionview) · [Website](https://reactionview.dev) · [Documentation](https://reactionview.dev/overview) |
49
-
50
- ## Ecosystem
51
-
52
- The Herb ecosystem offers multiple tools that integrate seamlessly into editors, developer environments, and CI pipelines:
53
-
54
- | Tool | Description |
55
- | --- | --- |
56
- | [Herb Parser](https://herb-tools.dev/projects/parser) | Fast, portable, HTML-aware ERB parser written in C. |
57
- | [Herb Linter](https://herb-tools.dev/projects/linter) | Static analysis to enforce best practices and identify common mistakes. |
58
- | [Herb Formatter](https://herb-tools.dev/projects/formatter) | Automatic, consistent formatting for HTML+ERB files. *(experimental)* |
59
- | [Herb Language Service](https://herb-tools.dev/projects/language-service) | HTML+ERB language service with ActionView tag helper support. |
60
- | [Herb Language Server](https://herb-tools.dev/projects/language-server) | Rich editor integration for VS Code, Zed, Neovim, and more. |
61
- | [Herb Engine](https://herb-tools.dev/projects/engine) | HTML-aware ERB rendering engine, API-compatible with Erubi. |
62
- | [Herb Dev Server](https://herb-tools.dev/projects/dev-server) | File-watching dev server with live DOM patching for templates. *(experimental)* |
63
- | [Herb Dev Tools](https://herb-tools.dev/projects/dev-tools) | In-browser dev tools for inspecting and debugging templates, shipped with ReActionView. |
64
- | [ReActionView](https://reactionview.dev) | ActionView-compatible ERB engine with modern DX for Rails. |
65
-
66
- You can use the Herb Parser programmatically in **Ruby**, **Java**, **Rust**, as well as in **JavaScript** via Node.js, WebAssembly, or directly in browsers.
26
+ <br/>
67
27
 
68
- For a complete overview of all available tools, libraries, and integrations, visit the [**Projects page**](https://herb-tools.dev/projects) on our documentation site.
28
+ **Herb is a modern templating language for the HTML+ERB you already have.**
69
29
 
70
- ## Motivation
30
+ Your `.html.erb` files are already HTML+ERB. Herb reads the HTML and the Ruby in them as one document, so it can tell you about an unclosed tag, a mismatched element or a missing `%>` with the file, the line and what to change, before the page renders. The same understanding drives a linter, a formatter, a language server for your editor and `Herb::Engine`, which renders your templates the way Erubi does and escapes each value for where it sits.
71
31
 
72
- HTML+ERB templates never really had good, accurate, and reliable tooling. While developer tooling for Ruby code improved significantly in the last few years (especially with the introduction of the new [Prism parser](https://github.com/ruby/prism)), HTML+ERB files remained underserved, lacking fundamental support like syntax checking, auto-formatting, linting, and structural understanding.
32
+ With the Rails 8.2 framework defaults, Rails renders HTML templates with `Herb::Engine`. [ReActionView](https://reactionview.dev) makes those templates reactive, and brings the error overlays, the dev tools and per-tag instrumentation to the page.
73
33
 
74
- At the same time, with the rise of tools like [Hotwire](https://hotwired.dev), [Stimulus](https://stimulus.hotwired.dev), [Turbo](https://turbo.hotwired.dev), [HTMX](https://htmx.org), [Unpoly](https://unpoly.com), and [Alpine.js](https://alpinejs.dev), advanced HTML templating became increasingly relevant (again). Developers expect modern, reliable, and precise tooling, especially given the robust ecosystem available to JavaScript frameworks and libraries.
34
+ ## Documentation
75
35
 
76
- Herb was built to close this tooling gap with an HTML-aware approach, understanding both HTML structure and ERB as first-class citizens, to provide the kind of tooling modern developers expect in the age of language servers, LLMs, and AI-driven workflows.
36
+ [herb-tools.dev](https://herb-tools.dev/overview)
77
37
 
78
- ## Command-Line Usage
38
+ ## Installation
79
39
 
80
- Install the Herb gem via RubyGems:
40
+ Check your templates without adding anything to your project:
81
41
 
82
42
  ```sh
83
- gem install herb
43
+ gem exec herb analyze
84
44
  ```
85
45
 
86
- ### Installing from a Git branch
87
-
88
- To test a branch before it's released (e.g. from a fork), add both `prism` and `herb` to your Gemfile:
89
-
90
- ```ruby
91
- gem "prism", github: "ruby/prism", tag: "v1.9.0"
92
- gem "herb", github: "fork/herb", branch: "my-branch"
93
- ```
94
-
95
- The `prism` gem is required because Herb's native C extension compiles against
96
- Prism's C source, which is vendored automatically during installation.
97
-
98
- For detailed information, like how you can use Herb programmatically in Ruby and JavaScript, visit the [documentation site](https://herb-tools.dev/bindings/ruby/reference).
99
-
100
- Basic usage to analyze all HTML+ERB files in your project:
46
+ Add the gem:
101
47
 
102
48
  ```sh
103
- herb analyze .
104
- ```
105
-
106
- This will give you an overview of how the Herb Parser sees your project:
107
- ```
108
- --- SUMMARY --------------------------------------------------------------------
109
- Total files: 145
110
- ✅ Successful: 143 (98.6%)
111
- ❌ Failed: 0 (0.0%)
112
- ⚠️ Parse errors: 2 (1.4%)
113
- ⏱️ Timed out: 0 (0.0%)
114
-
115
- Files with parse errors:
116
- - app/views/contributions/index.html.erb
117
- - index.html.erb
118
-
119
- Results saved to 2025-06-29_12-16-23_erb_parsing_result_rubyevents.log
49
+ bundle add herb
120
50
  ```
121
51
 
122
- Lint your HTML+ERB templates:
52
+ Run the linter and the formatter:
123
53
 
124
54
  ```sh
125
55
  npx @herb-tools/linter
126
- ```
127
-
128
- Format your HTML+ERB templates:
129
-
130
- ```sh
131
56
  npx @herb-tools/formatter
132
57
  ```
133
58
 
59
+ [Installation](https://herb-tools.dev/installation) covers editors, CI and installing from a Git branch.
134
60
 
61
+ ## Ecosystem
62
+
63
+ ### Tools
135
64
 
136
- ## Background and Talks
65
+ | Project | Description |
66
+ | --- | --- |
67
+ | [Herb Linter](https://herb-tools.dev/projects/linter) | Finds mistakes and enforces conventions in HTML+ERB templates. |
68
+ | [Herb Formatter](https://herb-tools.dev/projects/formatter) | Formats HTML+ERB templates consistently. *(experimental)* |
69
+ | [Herb Language Server](https://herb-tools.dev/projects/language-server) | Diagnostics, hovers and formatting in VS Code, Zed, Neovim and other editors. |
70
+ | [Herb Dev Server](https://herb-tools.dev/projects/dev-server) | Watches your templates and patches the open page as you save. *(experimental)* |
71
+ | [Herb Dev Tools](https://herb-tools.dev/projects/dev-tools) | In-browser tools for inspecting and debugging rendered templates. |
137
72
 
138
- The **Herb Parser** was first introduced at [**RubyKaigi 2025**](https://rubykaigi.org/2025/presentations/marcoroth.html) in April 2025 with the talk [*Empowering Developers with HTML-Aware ERB Tooling*](https://www.rubyevents.org/talks/empowering-developers-with-html-aware-erb-tooling-rubykaigi-2025).
73
+ ### Rendering
139
74
 
140
- At [**RailsConf 2025**](https://www.rubyevents.org/events/railsconf-2025) in July 2025, the Herb ecosystem was expanded with the talk [*The Modern View Layer Rails Deserves: A Vision for 2025 and Beyond*](https://www.rubyevents.org/talks/the-modern-view-layer-rails-deserves-a-vision-for-2025-and-beyond), introducing the linter, formatter, language server, and the vision for ReActionView.
75
+ | Project | Description |
76
+ | --- | --- |
77
+ | [`Herb::Engine`](https://herb-tools.dev/projects/engine) | HTML-aware ERB rendering engine, API-compatible with Erubi. |
78
+ | [Herb Client Runtime](https://herb-tools.dev/projects/client) | Updates the parts of a rendered page that changed, in place. *(experimental)* |
79
+ | [ReActionView](https://reactionview.dev) | Reactive templates, error overlays and dev tools for Rails. |
141
80
 
142
- At [**Rails World 2025**](https://www.rubyevents.org/events/rails-world-2025) in September 2025, `Herb::Engine`, ReActionView, and the visual dev tools were launched with the talk [*Introducing ReActionView: An ActionView-Compatible ERB Engine*](https://www.rubyevents.org/talks/introducing-reactionview-an-actionview-compatible-erb-engine).
81
+ ### Building on Herb
143
82
 
144
- At [**San Francisco Ruby Conference 2025**](https://www.rubyevents.org/events/sfruby-2025) in November 2025, the keynote [*Herb to ReActionView: A New Foundation for the View Layer*](https://www.rubyevents.org/talks/keynote-herb-to-reactionview-a-new-foundation-for-the-view-layer) gave an overview of how Herb came to be, what Herb can do for you today, and how it could enable the next generation of the Rails view layer with ReActionView.
83
+ The Herb Parser is a fast, portable, HTML-aware ERB parser written in C, with bindings for Ruby, JavaScript, Java, Rust and WebAssembly. The [Projects page](https://herb-tools.dev/projects) lists it together with the libraries for building your own tools on the Herb syntax tree.
145
84
 
146
85
  ## Contributing
147
86
 
148
- Bug reports and pull requests are welcome on [GitHub](https://github.com/marcoroth/herb). Please see the [CONTRIBUTING.md](https://github.com/marcoroth/herb/blob/main/CONTRIBUTING.md) document for guidelines on how to set up Herb for local development and how to contribute to **Herb**.
149
-
150
- ## Prior Art & Inspiration
151
-
152
- While Herb brings a fresh approach to HTML+ERB tooling, it builds upon and learns from several existing tools and approaches in the ecosystem:
153
-
154
- - [**Tree-sitter**](https://tree-sitter.github.io/tree-sitter/)
155
- - [**tree-sitter-embedded-template**](https://github.com/tree-sitter/tree-sitter-embedded-template)
156
- - [**Prism Ruby Parser**](https://github.com/ruby/prism)
157
- - [**Ruby LSP**](https://github.com/Shopify/ruby-lsp)
158
- - [**better-html**](https://github.com/Shopify/better-html)
159
- - [**erb_lint**](https://github.com/Shopify/erb_lint)
160
- - [**erb-formatter**](https://github.com/nebulab/erb-formatter)
161
- - [**erb-formatter-vscode**](https://github.com/nebulab/erb-formatter-vscode)
162
- - [**erblint-github**](https://github.com/github/erblint-github)
163
- - [**deface**](https://github.com/spree/deface)
164
- - [**html_press**](https://github.com/stereobooster/html_press)
165
- - [**htmlbeautifier**](https://github.com/threedaymonk/htmlbeautifier)
166
- - [**vscode-erb-beautify**](https://github.com/aliariff/vscode-erb-beautify)
167
- - [**vscode-erb-linter**](https://github.com/manuelpuyol/vscode-erb-linter)
168
- - [**syntax_tree-erb**](https://github.com/davidwessman/syntax_tree-erb)
169
-
170
- Herb differentiates itself by being HTML-aware from the ground up, providing a unified parsing approach that understands both HTML and ERB as first-class citizens, rather than treating one as embedded within the other.
87
+ Bug reports and pull requests are welcome on [GitHub](https://github.com/marcoroth/herb). [CONTRIBUTING.md](https://github.com/marcoroth/herb/blob/main/CONTRIBUTING.md) explains how to set up Herb for local development.
171
88
 
172
89
  ## License
173
90
 
data/Rakefile CHANGED
@@ -7,19 +7,9 @@ require "rake/testtask"
7
7
  Rake::TestTask.new(:test) do |t|
8
8
  t.libs << "test"
9
9
  t.libs << "lib"
10
- t.test_files = FileList["test/**/*_test.rb"].exclude("test/engine/**/*_test.rb", "test/integration/**/*_test.rb")
11
- end
12
-
13
- task :test_tip do
14
- puts "TIP: This only runs core tests. Other test tasks available:"
15
- puts " rake test:all"
16
- puts " rake test:engine"
17
- puts " rake test:integration"
18
- puts
10
+ t.test_files = FileList["test/**/*_test.rb"]
19
11
  end
20
12
 
21
- Rake::Task[:test].enhance([:test_tip])
22
-
23
13
  Rake::TestTask.new("test:engine") do |t|
24
14
  t.libs << "test"
25
15
  t.libs << "lib"
@@ -236,6 +226,7 @@ namespace :parse do
236
226
  desc "Parse ERB files in a project directory"
237
227
  task :project, [:path, :output_file] do |_t, args|
238
228
  require_relative "lib/herb"
229
+ require_relative "lib/herb/project"
239
230
 
240
231
  Herb::Project.new(args[:path], output_file: args[:output_file]).parse!
241
232
  end
@@ -1,20 +1,24 @@
1
1
  ---
2
- name: action_cable_meta_tag
2
+ name: "action_cable_meta_tag"
3
3
  source: "ActionCable::Helpers::ActionCableHelper#action_cable_meta_tag"
4
- gem: actioncable
5
- output: html
6
- visibility: public
4
+ gem: "actioncable"
5
+ output: "html"
6
+ visibility: "public"
7
7
  supported: false
8
8
  supports_block: false
9
- description: |-
10
- Returns an `"action-cable-url"` `<meta>` tag with the value of the URL specified in your configuration. Ensure this is above your JavaScript tag. Used by Action Cable to determine the URL of your WebSocket server.
11
9
  signature: "action_cable_meta_tag"
12
10
  documentation_url: "https://api.rubyonrails.org/classes/ActionCable/Helpers/ActionCableHelper.html#method-i-action_cable_meta_tag"
11
+
12
+ description: |-
13
+ Returns an `"action-cable-url"` `<meta>` tag with the value of the URL specified in your configuration. Ensure this is above your JavaScript tag. Used by Action Cable to determine the URL of your WebSocket server.
14
+
13
15
  tag:
14
- name: meta
16
+ name: "meta"
15
17
  is_void: true
16
18
  preferred: false
17
- detect_style: call_name
19
+ detect_style: "call_name"
20
+
18
21
  arguments: []
19
22
  options: []
23
+ block_arguments: []
20
24
  special_behaviors: []
@@ -1,16 +1,19 @@
1
1
  ---
2
- name: content_security_policy?
2
+ name: "content_security_policy?"
3
3
  source: "ActionController::ContentSecurityPolicy#content_security_policy?"
4
- gem: actionpack
5
- output: boolean
6
- visibility: public
4
+ gem: "actionpack"
5
+ output: "boolean"
6
+ visibility: "public"
7
7
  supported: false
8
8
  supports_block: false
9
- description: |-
10
- Returns whether a Content-Security-Policy is present for the current request.
11
9
  signature: "content_security_policy?"
12
10
  documentation_url: ""
11
+
12
+ description: |-
13
+ Returns whether a Content-Security-Policy is present for the current request.
14
+
13
15
  tag: null
14
16
  arguments: []
15
17
  options: []
18
+ block_arguments: []
16
19
  special_behaviors: []
@@ -1,16 +1,19 @@
1
1
  ---
2
- name: content_security_policy_nonce
2
+ name: "content_security_policy_nonce"
3
3
  source: "ActionController::ContentSecurityPolicy#content_security_policy_nonce"
4
- gem: actionpack
5
- output: text
6
- visibility: public
4
+ gem: "actionpack"
5
+ output: "text"
6
+ visibility: "public"
7
7
  supported: false
8
8
  supports_block: false
9
- description: |-
10
- Returns the Content-Security-Policy nonce for the current request. This nonce value is used in `<script>` and `<style>` tags to allow inline content when a CSP is configured with a nonce source.
11
9
  signature: "content_security_policy_nonce"
12
10
  documentation_url: ""
11
+
12
+ description: |-
13
+ Returns the Content-Security-Policy nonce for the current request. This nonce value is used in `<script>` and `<style>` tags to allow inline content when a CSP is configured with a nonce source.
14
+
13
15
  tag: null
14
16
  arguments: []
15
17
  options: []
18
+ block_arguments: []
16
19
  special_behaviors: []
@@ -1,27 +1,35 @@
1
1
  ---
2
- name: polymorphic_path
2
+ name: "polymorphic_path"
3
3
  source: "ActionDispatch::Routing::PolymorphicRoutes#polymorphic_path"
4
- gem: actionpack
5
- output: url
6
- visibility: public
4
+ gem: "actionpack"
5
+ output: "url"
6
+ visibility: "public"
7
7
  supported: false
8
8
  supports_block: false
9
- description: |-
10
- Returns the path component of a URL for the given record. Like `polymorphic_url` but returns a path instead of a full URL.
11
9
  signature: "polymorphic_path(record_or_hash_or_array, options = {})"
12
10
  documentation_url: "https://api.rubyonrails.org/classes/ActionDispatch/Routing/PolymorphicRoutes.html#method-i-polymorphic_path"
11
+
12
+ description: |-
13
+ Returns the path component of a URL for the given record. Like `polymorphic_url` but returns a path instead of a full URL.
14
+
13
15
  tag: null
16
+
14
17
  arguments:
15
- - name: record_or_hash_or_array
18
+ - name: "record_or_hash_or_array"
16
19
  position: 1
17
- type: object
20
+ type: "object"
18
21
  optional: false
19
- description: "An Active Record instance, class, array, or hash."
20
- - name: options
22
+ description: |-
23
+ An Active Record instance, class, array, or hash.
24
+
25
+ - name: "options"
21
26
  position: 2
22
- type: hash
27
+ type: "hash"
23
28
  optional: true
24
29
  default: "{}"
25
- description: "URL options hash."
30
+ description: |-
31
+ URL options hash.
32
+
26
33
  options: []
34
+ block_arguments: []
27
35
  special_behaviors: []
@@ -1,33 +1,45 @@
1
1
  ---
2
- name: polymorphic_url
2
+ name: "polymorphic_url"
3
3
  source: "ActionDispatch::Routing::PolymorphicRoutes#polymorphic_url"
4
- gem: actionpack
5
- output: url
6
- visibility: public
4
+ gem: "actionpack"
5
+ output: "url"
6
+ visibility: "public"
7
7
  supported: false
8
8
  supports_block: false
9
- description: |-
10
- Returns the URL for the given record or array of records. Automatically resolves to the named route based on the class of the record.
11
9
  signature: "polymorphic_url(record_or_hash_or_array, options = {})"
12
10
  documentation_url: "https://api.rubyonrails.org/classes/ActionDispatch/Routing/PolymorphicRoutes.html#method-i-polymorphic_url"
11
+
12
+ description: |-
13
+ Returns the URL for the given record or array of records. Automatically resolves to the named route based on the class of the record.
14
+
13
15
  tag: null
16
+
14
17
  arguments:
15
- - name: record_or_hash_or_array
18
+ - name: "record_or_hash_or_array"
16
19
  position: 1
17
- type: object
20
+ type: "object"
18
21
  optional: false
19
- description: "An Active Record instance, class, array, or hash."
20
- - name: options
22
+ description: |-
23
+ An Active Record instance, class, array, or hash.
24
+
25
+ - name: "options"
21
26
  position: 2
22
- type: hash
27
+ type: "hash"
23
28
  optional: true
24
29
  default: "{}"
25
- description: "URL options hash."
30
+ description: |-
31
+ URL options hash.
32
+
26
33
  options:
27
- - name: action
28
- type: symbol
29
- description: "Route action (e.g. `:edit`, `:new`)."
30
- - name: routing_type
31
- type: symbol
32
- description: "Whether to generate `:url` or `:path`. Defaults to `:url`."
34
+ - name: "action"
35
+ type: "symbol"
36
+ description: |-
37
+ Route action (e.g. `:edit`, `:new`).
38
+
39
+ - name: "routing_type"
40
+ type: "symbol"
41
+ description: |-
42
+ Whether to generate `:url` or `:path`. Defaults to `:url`.
43
+
44
+ block_arguments: []
33
45
  special_behaviors: []
@@ -1,19 +1,25 @@
1
1
  ---
2
- name: form_authenticity_token
2
+ name: "form_authenticity_token"
3
3
  source: "ActionController::RequestForgeryProtection#form_authenticity_token"
4
- gem: actionpack
5
- output: text
6
- visibility: public
4
+ gem: "actionpack"
5
+ output: "text"
6
+ visibility: "public"
7
7
  supported: false
8
8
  supports_block: false
9
- description: |-
10
- Creates the authenticity token for the current request. Returns the masked CSRF token string used for protecting forms against cross-site request forgery.
11
9
  signature: "form_authenticity_token(form_options: {})"
12
10
  documentation_url: "https://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html#method-i-form_authenticity_token"
11
+
12
+ description: |-
13
+ Creates the authenticity token for the current request. Returns the masked CSRF token string used for protecting forms against cross-site request forgery.
14
+
13
15
  tag: null
14
16
  arguments: []
17
+
15
18
  options:
16
- - name: form_options
17
- type: hash
18
- description: "A hash that may contain `:action` and `:method` keys for per-form CSRF tokens."
19
+ - name: "form_options"
20
+ type: "hash"
21
+ description: |-
22
+ A hash that may contain `:action` and `:method` keys for per-form CSRF tokens.
23
+
24
+ block_arguments: []
19
25
  special_behaviors: []
@@ -1,16 +1,19 @@
1
1
  ---
2
- name: protect_against_forgery?
2
+ name: "protect_against_forgery?"
3
3
  source: "ActionController::RequestForgeryProtection#protect_against_forgery?"
4
- gem: actionpack
5
- output: boolean
6
- visibility: public
4
+ gem: "actionpack"
5
+ output: "boolean"
6
+ visibility: "public"
7
7
  supported: false
8
8
  supports_block: false
9
- description: |-
10
- Checks if the controller allows forgery protection. Returns `true` if forgery protection is enabled and the session is active.
11
9
  signature: "protect_against_forgery?"
12
10
  documentation_url: "https://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html#method-i-protect_against_forgery-3F"
11
+
12
+ description: |-
13
+ Checks if the controller allows forgery protection. Returns `true` if forgery protection is enabled and the session is active.
14
+
13
15
  tag: null
14
16
  arguments: []
15
17
  options: []
18
+ block_arguments: []
16
19
  special_behaviors: []
@@ -1,21 +1,27 @@
1
1
  ---
2
- name: render_action_text_content
2
+ name: "render_action_text_content"
3
3
  source: "ActionText::ContentHelper#render_action_text_content"
4
- gem: actiontext
5
- output: html
6
- visibility: public
4
+ gem: "actiontext"
5
+ output: "html"
6
+ visibility: "public"
7
7
  supported: false
8
8
  supports_block: false
9
- description: |-
10
- Renders Action Text content by processing attachments and sanitizing the resulting HTML. Sets `prefix_partial_path_with_controller_namespace` to `false`, renders attachments, and then sanitizes the content.
11
9
  signature: "render_action_text_content(content)"
12
10
  documentation_url: "https://api.rubyonrails.org/classes/ActionText/ContentHelper.html#method-i-render_action_text_content"
11
+
12
+ description: |-
13
+ Renders Action Text content by processing attachments and sanitizing the resulting HTML. Sets `prefix_partial_path_with_controller_namespace` to `false`, renders attachments, and then sanitizes the content.
14
+
13
15
  tag: null
16
+
14
17
  arguments:
15
- - name: content
18
+ - name: "content"
16
19
  position: 1
17
- type: object
20
+ type: "object"
18
21
  optional: false
19
- description: "The Action Text content object to render."
22
+ description: |-
23
+ The Action Text content object to render.
24
+
20
25
  options: []
26
+ block_arguments: []
21
27
  special_behaviors: []
@@ -1,21 +1,27 @@
1
1
  ---
2
- name: sanitize_action_text_content
2
+ name: "sanitize_action_text_content"
3
3
  source: "ActionText::ContentHelper#sanitize_action_text_content"
4
- gem: actiontext
5
- output: html
6
- visibility: public
4
+ gem: "actiontext"
5
+ output: "html"
6
+ visibility: "public"
7
7
  supported: false
8
8
  supports_block: false
9
- description: |-
10
- Sanitizes Action Text content HTML using the configured sanitizer, allowed tags, allowed attributes, and scrubber. Returns the sanitized HTML as an `html_safe` string.
11
9
  signature: "sanitize_action_text_content(content)"
12
10
  documentation_url: "https://api.rubyonrails.org/classes/ActionText/ContentHelper.html#method-i-sanitize_action_text_content"
11
+
12
+ description: |-
13
+ Sanitizes Action Text content HTML using the configured sanitizer, allowed tags, allowed attributes, and scrubber. Returns the sanitized HTML as an `html_safe` string.
14
+
13
15
  tag: null
16
+
14
17
  arguments:
15
- - name: content
18
+ - name: "content"
16
19
  position: 1
17
- type: object
20
+ type: "object"
18
21
  optional: false
19
- description: "The Action Text content object to sanitize."
22
+ description: |-
23
+ The Action Text content object to sanitize.
24
+
20
25
  options: []
26
+ block_arguments: []
21
27
  special_behaviors: []