brakeman 7.0.0 → 7.0.1

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 (244) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +9 -0
  3. data/README.md +1 -1
  4. data/bundle/load.rb +8 -7
  5. data/bundle/ruby/3.1.0/gems/{csv-3.3.2 → csv-3.3.3}/NEWS.md +25 -0
  6. data/bundle/ruby/3.1.0/gems/{csv-3.3.2 → csv-3.3.3}/lib/csv/parser.rb +15 -5
  7. data/bundle/ruby/3.1.0/gems/{csv-3.3.2 → csv-3.3.3}/lib/csv/version.rb +1 -1
  8. data/bundle/ruby/3.1.0/gems/{csv-3.3.2 → csv-3.3.3}/lib/csv.rb +1 -1
  9. data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/Changelog.md +4 -0
  10. data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/Gemfile +1 -0
  11. data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/list_renderer.rb +2 -2
  12. data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/menu.rb +7 -5
  13. data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/version.rb +1 -1
  14. data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline.rb +17 -12
  15. data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/NEWS.md +24 -0
  16. data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/parsers/baseparser.rb +29 -8
  17. data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/rexml.rb +1 -1
  18. data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/source.rb +16 -2
  19. data/bundle/ruby/3.1.0/gems/{ruby2ruby-2.5.1 → ruby2ruby-2.5.2}/History.rdoc +6 -0
  20. data/bundle/ruby/3.1.0/gems/{ruby2ruby-2.5.1 → ruby2ruby-2.5.2}/lib/ruby2ruby.rb +7 -4
  21. data/bundle/ruby/3.1.0/gems/{terminal-table-3.0.2 → terminal-table-4.0.0}/History.rdoc +7 -0
  22. data/bundle/ruby/3.1.0/gems/{terminal-table-3.0.2 → terminal-table-4.0.0}/lib/terminal-table/cell.rb +1 -1
  23. data/bundle/ruby/3.1.0/gems/{terminal-table-3.0.2 → terminal-table-4.0.0}/lib/terminal-table/table.rb +2 -0
  24. data/bundle/ruby/3.1.0/gems/{terminal-table-3.0.2 → terminal-table-4.0.0}/lib/terminal-table/version.rb +1 -1
  25. data/bundle/ruby/3.1.0/gems/{terminal-table-3.0.2 → terminal-table-4.0.0}/terminal-table.gemspec +1 -2
  26. data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/template.rb +151 -24
  27. data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt.rb +9 -1
  28. data/bundle/ruby/3.1.0/gems/{unicode-display_width-2.6.0 → unicode-display_width-3.1.4}/CHANGELOG.md +93 -2
  29. data/bundle/ruby/3.1.0/gems/unicode-display_width-3.1.4/README.md +194 -0
  30. data/bundle/ruby/3.1.0/gems/unicode-display_width-3.1.4/data/display_width.marshal.gz +0 -0
  31. data/bundle/ruby/3.1.0/gems/{unicode-display_width-2.6.0 → unicode-display_width-3.1.4}/lib/unicode/display_width/constants.rb +1 -1
  32. data/bundle/ruby/3.1.0/gems/unicode-display_width-3.1.4/lib/unicode/display_width/emoji_support.rb +52 -0
  33. data/bundle/ruby/3.1.0/gems/unicode-display_width-3.1.4/lib/unicode/display_width/reline_ext.rb +14 -0
  34. data/bundle/ruby/3.1.0/gems/unicode-display_width-3.1.4/lib/unicode/display_width/string_ext.rb +9 -0
  35. data/bundle/ruby/3.1.0/gems/unicode-display_width-3.1.4/lib/unicode/display_width.rb +247 -0
  36. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/CHANGELOG.md +191 -0
  37. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/CODE_OF_CONDUCT.md +74 -0
  38. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/Gemfile +7 -0
  39. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/Gemfile.lock +33 -0
  40. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/MIT-LICENSE.txt +20 -0
  41. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/README.md +205 -0
  42. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/data/emoji.marshal.gz +0 -0
  43. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/data/generate_constants.rb +344 -0
  44. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/constants.rb +49 -0
  45. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex.rb +8 -0
  46. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_basic.rb +8 -0
  47. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_emoji_keycap.rb +8 -0
  48. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_include_mqe.rb +8 -0
  49. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_include_mqe_uqe.rb +8 -0
  50. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_include_text.rb +8 -0
  51. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_picto.rb +8 -0
  52. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_picto_no_emoji.rb +8 -0
  53. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_possible.rb +8 -0
  54. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_prop_component.rb +8 -0
  55. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_prop_emoji.rb +8 -0
  56. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_prop_modifier.rb +8 -0
  57. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_prop_modifier_base.rb +8 -0
  58. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_prop_presentation.rb +8 -0
  59. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_text.rb +8 -0
  60. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_text_presentation.rb +8 -0
  61. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_valid.rb +8 -0
  62. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_valid_include_text.rb +8 -0
  63. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_well_formed.rb +8 -0
  64. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated/regex_well_formed_include_text.rb +8 -0
  65. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex.rb +8 -0
  66. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_basic.rb +8 -0
  67. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_emoji_keycap.rb +8 -0
  68. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_include_mqe.rb +8 -0
  69. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_include_mqe_uqe.rb +8 -0
  70. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_include_text.rb +8 -0
  71. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_picto.rb +8 -0
  72. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_picto_no_emoji.rb +8 -0
  73. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_possible.rb +8 -0
  74. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_prop_component.rb +8 -0
  75. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_prop_emoji.rb +8 -0
  76. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_prop_modifier.rb +8 -0
  77. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_prop_modifier_base.rb +8 -0
  78. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_prop_presentation.rb +8 -0
  79. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_text.rb +8 -0
  80. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_text_presentation.rb +8 -0
  81. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_valid.rb +8 -0
  82. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_valid_include_text.rb +8 -0
  83. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_well_formed.rb +8 -0
  84. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/generated_native/regex_well_formed_include_text.rb +8 -0
  85. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/index.rb +14 -0
  86. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/lazy_constants.rb +56 -0
  87. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji/list.rb +13 -0
  88. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/lib/unicode/emoji.rb +111 -0
  89. data/bundle/ruby/3.1.0/gems/unicode-emoji-4.0.4/unicode-emoji.gemspec +22 -0
  90. data/lib/brakeman/app_tree.rb +6 -1
  91. data/lib/brakeman/checks/check_evaluation.rb +39 -20
  92. data/lib/brakeman/checks/check_weak_rsa_key.rb +1 -1
  93. data/lib/brakeman/options.rb +4 -0
  94. data/lib/brakeman/processors/alias_processor.rb +3 -2
  95. data/lib/brakeman/scanner.rb +22 -13
  96. data/lib/brakeman/version.rb +1 -1
  97. data/lib/brakeman.rb +7 -0
  98. metadata +229 -173
  99. data/bundle/ruby/3.1.0/gems/unicode-display_width-2.6.0/README.md +0 -171
  100. data/bundle/ruby/3.1.0/gems/unicode-display_width-2.6.0/data/display_width.marshal.gz +0 -0
  101. data/bundle/ruby/3.1.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width/string_ext.rb +0 -9
  102. data/bundle/ruby/3.1.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width.rb +0 -123
  103. /data/bundle/ruby/3.1.0/gems/{csv-3.3.2 → csv-3.3.3}/LICENSE.txt +0 -0
  104. /data/bundle/ruby/3.1.0/gems/{csv-3.3.2 → csv-3.3.3}/README.md +0 -0
  105. /data/bundle/ruby/3.1.0/gems/{csv-3.3.2 → csv-3.3.3}/lib/csv/core_ext/array.rb +0 -0
  106. /data/bundle/ruby/3.1.0/gems/{csv-3.3.2 → csv-3.3.3}/lib/csv/core_ext/string.rb +0 -0
  107. /data/bundle/ruby/3.1.0/gems/{csv-3.3.2 → csv-3.3.3}/lib/csv/fields_converter.rb +0 -0
  108. /data/bundle/ruby/3.1.0/gems/{csv-3.3.2 → csv-3.3.3}/lib/csv/input_record_separator.rb +0 -0
  109. /data/bundle/ruby/3.1.0/gems/{csv-3.3.2 → csv-3.3.3}/lib/csv/row.rb +0 -0
  110. /data/bundle/ruby/3.1.0/gems/{csv-3.3.2 → csv-3.3.3}/lib/csv/table.rb +0 -0
  111. /data/bundle/ruby/3.1.0/gems/{csv-3.3.2 → csv-3.3.3}/lib/csv/writer.rb +0 -0
  112. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/AUTHORS +0 -0
  113. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/COPYING +0 -0
  114. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/LICENSE +0 -0
  115. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/README.md +0 -0
  116. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/TODO +0 -0
  117. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/highline.gemspec +0 -0
  118. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/builtin_styles.rb +0 -0
  119. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/color_scheme.rb +0 -0
  120. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/compatibility.rb +0 -0
  121. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/custom_errors.rb +0 -0
  122. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/import.rb +0 -0
  123. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/io_console_compatible.rb +0 -0
  124. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/list.rb +0 -0
  125. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/menu/item.rb +0 -0
  126. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/paginator.rb +0 -0
  127. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/question/answer_converter.rb +0 -0
  128. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/question.rb +0 -0
  129. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/question_asker.rb +0 -0
  130. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/simulate.rb +0 -0
  131. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/statement.rb +0 -0
  132. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/string.rb +0 -0
  133. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/string_extensions.rb +0 -0
  134. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/style.rb +0 -0
  135. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/template_renderer.rb +0 -0
  136. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/terminal/io_console.rb +0 -0
  137. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/terminal/ncurses.rb +0 -0
  138. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/terminal/unix_stty.rb +0 -0
  139. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/terminal.rb +0 -0
  140. /data/bundle/ruby/3.1.0/gems/{highline-3.1.1 → highline-3.1.2}/lib/highline/wrapper.rb +0 -0
  141. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/LICENSE.txt +0 -0
  142. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/README.md +0 -0
  143. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/attlistdecl.rb +0 -0
  144. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/attribute.rb +0 -0
  145. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/cdata.rb +0 -0
  146. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/child.rb +0 -0
  147. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/comment.rb +0 -0
  148. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/doctype.rb +0 -0
  149. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/document.rb +0 -0
  150. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/dtd/attlistdecl.rb +0 -0
  151. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/dtd/dtd.rb +0 -0
  152. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/dtd/elementdecl.rb +0 -0
  153. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/dtd/entitydecl.rb +0 -0
  154. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/dtd/notationdecl.rb +0 -0
  155. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/element.rb +0 -0
  156. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/encoding.rb +0 -0
  157. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/entity.rb +0 -0
  158. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/formatters/default.rb +0 -0
  159. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/formatters/pretty.rb +0 -0
  160. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/formatters/transitive.rb +0 -0
  161. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/functions.rb +0 -0
  162. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/instruction.rb +0 -0
  163. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/light/node.rb +0 -0
  164. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/namespace.rb +0 -0
  165. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/node.rb +0 -0
  166. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/output.rb +0 -0
  167. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/parent.rb +0 -0
  168. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/parseexception.rb +0 -0
  169. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/parsers/lightparser.rb +0 -0
  170. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/parsers/pullparser.rb +0 -0
  171. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/parsers/sax2parser.rb +0 -0
  172. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/parsers/streamparser.rb +0 -0
  173. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/parsers/treeparser.rb +0 -0
  174. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/parsers/ultralightparser.rb +0 -0
  175. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/parsers/xpathparser.rb +0 -0
  176. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/quickpath.rb +0 -0
  177. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/sax2listener.rb +0 -0
  178. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/security.rb +0 -0
  179. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/streamlistener.rb +0 -0
  180. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/text.rb +0 -0
  181. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/undefinednamespaceexception.rb +0 -0
  182. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/validation/relaxng.rb +0 -0
  183. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/validation/validation.rb +0 -0
  184. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/validation/validationexception.rb +0 -0
  185. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/xmldecl.rb +0 -0
  186. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/xmltokens.rb +0 -0
  187. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/xpath.rb +0 -0
  188. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml/xpath_parser.rb +0 -0
  189. /data/bundle/ruby/3.1.0/gems/{rexml-3.4.0 → rexml-3.4.1}/lib/rexml.rb +0 -0
  190. /data/bundle/ruby/3.1.0/gems/{ruby2ruby-2.5.1 → ruby2ruby-2.5.2}/Manifest.txt +0 -0
  191. /data/bundle/ruby/3.1.0/gems/{ruby2ruby-2.5.1 → ruby2ruby-2.5.2}/README.rdoc +0 -0
  192. /data/bundle/ruby/3.1.0/gems/{terminal-table-3.0.2 → terminal-table-4.0.0}/Gemfile +0 -0
  193. /data/bundle/ruby/3.1.0/gems/{terminal-table-3.0.2 → terminal-table-4.0.0}/LICENSE.txt +0 -0
  194. /data/bundle/ruby/3.1.0/gems/{terminal-table-3.0.2 → terminal-table-4.0.0}/Manifest +0 -0
  195. /data/bundle/ruby/3.1.0/gems/{terminal-table-3.0.2 → terminal-table-4.0.0}/README.md +0 -0
  196. /data/bundle/ruby/3.1.0/gems/{terminal-table-3.0.2 → terminal-table-4.0.0}/Todo.rdoc +0 -0
  197. /data/bundle/ruby/3.1.0/gems/{terminal-table-3.0.2 → terminal-table-4.0.0}/lib/terminal-table/import.rb +0 -0
  198. /data/bundle/ruby/3.1.0/gems/{terminal-table-3.0.2 → terminal-table-4.0.0}/lib/terminal-table/row.rb +0 -0
  199. /data/bundle/ruby/3.1.0/gems/{terminal-table-3.0.2 → terminal-table-4.0.0}/lib/terminal-table/separator.rb +0 -0
  200. /data/bundle/ruby/3.1.0/gems/{terminal-table-3.0.2 → terminal-table-4.0.0}/lib/terminal-table/style.rb +0 -0
  201. /data/bundle/ruby/3.1.0/gems/{terminal-table-3.0.2 → terminal-table-4.0.0}/lib/terminal-table/table_helper.rb +0 -0
  202. /data/bundle/ruby/3.1.0/gems/{terminal-table-3.0.2 → terminal-table-4.0.0}/lib/terminal-table/util.rb +0 -0
  203. /data/bundle/ruby/3.1.0/gems/{terminal-table-3.0.2 → terminal-table-4.0.0}/lib/terminal-table.rb +0 -0
  204. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/COPYING +0 -0
  205. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/_emacs_org.rb +0 -0
  206. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/_handlebars.rb +0 -0
  207. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/_jbuilder.rb +0 -0
  208. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/_org.rb +0 -0
  209. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/asciidoc.rb +0 -0
  210. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/babel.rb +0 -0
  211. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/builder.rb +0 -0
  212. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/cli.rb +0 -0
  213. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/coffee.rb +0 -0
  214. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/commonmarker.rb +0 -0
  215. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/creole.rb +0 -0
  216. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/csv.rb +0 -0
  217. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/erb.rb +0 -0
  218. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/erubi.rb +0 -0
  219. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/etanni.rb +0 -0
  220. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/haml.rb +0 -0
  221. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/kramdown.rb +0 -0
  222. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/liquid.rb +0 -0
  223. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/livescript.rb +0 -0
  224. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/mapping.rb +0 -0
  225. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/markaby.rb +0 -0
  226. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/nokogiri.rb +0 -0
  227. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/pandoc.rb +0 -0
  228. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/pipeline.rb +0 -0
  229. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/plain.rb +0 -0
  230. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/prawn.rb +0 -0
  231. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/radius.rb +0 -0
  232. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/rdiscount.rb +0 -0
  233. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/rdoc.rb +0 -0
  234. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/redcarpet.rb +0 -0
  235. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/redcloth.rb +0 -0
  236. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/rst-pandoc.rb +0 -0
  237. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/sass.rb +0 -0
  238. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/slim.rb +0 -0
  239. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/string.rb +0 -0
  240. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/typescript.rb +0 -0
  241. /data/bundle/ruby/3.1.0/gems/{tilt-2.5.0 → tilt-2.6.0}/lib/tilt/yajl.rb +0 -0
  242. /data/bundle/ruby/3.1.0/gems/{unicode-display_width-2.6.0 → unicode-display_width-3.1.4}/MIT-LICENSE.txt +0 -0
  243. /data/bundle/ruby/3.1.0/gems/{unicode-display_width-2.6.0 → unicode-display_width-3.1.4}/lib/unicode/display_width/index.rb +0 -0
  244. /data/bundle/ruby/3.1.0/gems/{unicode-display_width-2.6.0 → unicode-display_width-3.1.4}/lib/unicode/display_width/no_string_ext.rb +0 -0
@@ -57,7 +57,28 @@ module Tilt
57
57
  # it should read template data and return as a String. When file is nil,
58
58
  # a block is required.
59
59
  #
60
- # All arguments are optional.
60
+ # All arguments are optional. The following options are respected and
61
+ # are used by Tilt::Template itself and not the underlying template
62
+ # libraries:
63
+ #
64
+ # :default_encoding :: Force the encoding of the template to the given
65
+ # encoding.
66
+ # :skip_compiled_encoding_detection :: Do not scan template code for
67
+ # an encoding magic comment.
68
+ # :fixed_locals :: Force a specific method parameter signature, and call
69
+ # the method with a splat of locals, instead of passing
70
+ # the locals hash as a positional argument, and
71
+ # extracting locals from that. Should be a string
72
+ # containing the parameters for the compiled method,
73
+ # surrounded by parentheses. Can be set to false to
74
+ # disable the scan for embedded fixed locals.
75
+ # :extract_fixed_locals :: Whether embedded fixed locals should be scanned for
76
+ # and extracted from the template code.
77
+ # :default_fixed_locals :: Similar to fixed_locals, but lowest priority,
78
+ # only used if :fixed_locals is not provided
79
+ # and no embedded locals are found (or scanned for).
80
+ # :scope_class :: Force the scope class used for the method. By default,
81
+ # uses the class of the scope provided to render.
61
82
  def initialize(file=nil, line=nil, options=nil)
62
83
  @file, @line, @options = nil, 1, nil
63
84
 
@@ -69,7 +90,9 @@ module Tilt
69
90
 
70
91
  @options ||= {}
71
92
 
72
- set_compiled_method_cache
93
+ # Force a specific scope class, instead of using the class of the provided
94
+ # scope as the scope class.
95
+ @scope_class = @options.delete :scope_class
73
96
 
74
97
  # Force the encoding of the input data
75
98
  @default_encoding = @options.delete :default_encoding
@@ -78,6 +101,13 @@ module Tilt
78
101
  # for compiled templates
79
102
  @skip_compiled_encoding_detection = @options.delete :skip_compiled_encoding_detection
80
103
 
104
+ # Compiled path to use. This must be specified as an option if
105
+ # providing the :scope_class option and using fixed locals,
106
+ # since template compilation occurs during initialization in that case.
107
+ if compiled_path = @options.delete(:compiled_path)
108
+ self.compiled_path = compiled_path
109
+ end
110
+
81
111
  # load template data and prepare (uses binread to avoid encoding issues)
82
112
  @data = block_given? ? yield(self) : read_template_file
83
113
 
@@ -92,7 +122,9 @@ module Tilt
92
122
  end
93
123
  end
94
124
 
125
+ set_fixed_locals
95
126
  prepare
127
+ set_compiled_method_cache
96
128
  end
97
129
 
98
130
  # Render the template in the given scope with the locals specified. If a
@@ -119,6 +151,11 @@ module Tilt
119
151
  @file || '(__TEMPLATE__)'
120
152
  end
121
153
 
154
+ # Whether the template uses fixed locals.
155
+ def fixed_locals?
156
+ @fixed_locals ? true : false
157
+ end
158
+
122
159
  # An empty Hash that the template engine can populate with various
123
160
  # metadata.
124
161
  def metadata
@@ -129,7 +166,14 @@ module Tilt
129
166
  end
130
167
  end
131
168
 
132
- # Set the prefix to use for compiled paths.
169
+ # Set the prefix to use for compiled paths, similar to using the
170
+ # :compiled_path template option. Note that this only
171
+ # has affect for future template compilations. When using the
172
+ # :scope_class template option, and using fixed_locals, calling
173
+ # this after the template is created has no effect, since the
174
+ # template is compiled during initialization in that case. It
175
+ # is recommended to use the :compiled_path template option
176
+ # instead of this method in new code.
133
177
  def compiled_path=(path)
134
178
  if path
135
179
  # Use expanded paths when loading, since that is helpful
@@ -145,7 +189,18 @@ module Tilt
145
189
  # directly on the scope class, which are much faster to call than
146
190
  # Tilt's normal rendering.
147
191
  def compiled_method(locals_keys, scope_class=nil)
148
- key = [scope_class, locals_keys].freeze
192
+ if @fixed_locals
193
+ if @scope_class
194
+ return @compiled_method
195
+ else
196
+ key = scope_class
197
+ end
198
+ elsif @scope_class
199
+ key = locals_keys.dup.freeze
200
+ else
201
+ key = [scope_class, locals_keys].freeze
202
+ end
203
+
149
204
  LOCK.synchronize do
150
205
  if meth = @compiled_method[key]
151
206
  return meth
@@ -181,7 +236,7 @@ module Tilt
181
236
  end
182
237
 
183
238
  CLASS_METHOD = Kernel.instance_method(:class)
184
- USE_BIND_CALL = RUBY_VERSION >= '2.7'
239
+ USE_BIND_CALL = RUBY_VERSION >= '3'
185
240
 
186
241
  # Execute the compiled template and return the result string. Template
187
242
  # evaluation is guaranteed to be performed in the scope object with the
@@ -190,26 +245,25 @@ module Tilt
190
245
  # This method is only used by source generating templates. Subclasses that
191
246
  # override render() may not support all features.
192
247
  def evaluate(scope, locals, &block)
193
- locals_keys = locals.keys
194
- locals_keys.sort!{|x, y| x.to_s <=> y.to_s}
195
-
196
- case scope
197
- when Object
198
- scope_class = Module === scope ? scope : scope.class
248
+ if @fixed_locals
249
+ locals_keys = EMPTY_ARRAY
199
250
  else
200
- # :nocov:
201
- scope_class = USE_BIND_CALL ? CLASS_METHOD.bind_call(scope) : CLASS_METHOD.bind(scope).call
202
- # :nocov:
251
+ locals_keys = locals.keys
252
+ locals_keys.sort!{|x, y| x.to_s <=> y.to_s}
203
253
  end
204
- method = compiled_method(locals_keys, scope_class)
205
254
 
206
- if USE_BIND_CALL
207
- method.bind_call(scope, locals, &block)
208
- # :nocov:
209
- else
210
- method.bind(scope).call(locals, &block)
211
- # :nocov:
255
+ unless scope_class = @scope_class
256
+ scope_class = case scope
257
+ when Object
258
+ Module === scope ? scope : scope.class
259
+ else
260
+ # :nocov:
261
+ USE_BIND_CALL ? CLASS_METHOD.bind_call(scope) : CLASS_METHOD.bind(scope).call
262
+ # :nocov:
263
+ end
212
264
  end
265
+
266
+ evaluate_method(compiled_method(locals_keys, scope_class), scope, locals, &block)
213
267
  end
214
268
 
215
269
  # Generates all template source by combining the preamble, template, and
@@ -303,7 +357,12 @@ module Tilt
303
357
  end
304
358
 
305
359
  def set_compiled_method_cache
306
- @compiled_method = {}
360
+ @compiled_method = if @fixed_locals && @scope_class
361
+ # No hash needed, only a single compiled method per template.
362
+ compile_template_method(EMPTY_ARRAY, @scope_class)
363
+ else
364
+ {}
365
+ end
307
366
  end
308
367
 
309
368
  def local_extraction(local_keys)
@@ -327,9 +386,39 @@ module Tilt
327
386
  assignments.join("\n")
328
387
  end
329
388
 
389
+ if USE_BIND_CALL
390
+ def evaluate_method(method, scope, locals, &block)
391
+ if @fixed_locals
392
+ method.bind_call(scope, **locals, &block)
393
+ else
394
+ method.bind_call(scope, locals, &block)
395
+ end
396
+ end
397
+ # :nocov:
398
+ else
399
+ def evaluate_method(method, scope, locals, &block)
400
+ if @fixed_locals
401
+ if locals.empty?
402
+ # Empty keyword splat on Ruby 2.0-2.6 passes empty hash
403
+ method.bind(scope).call(&block)
404
+ else
405
+ method.bind(scope).call(**locals, &block)
406
+ end
407
+ else
408
+ method.bind(scope).call(locals, &block)
409
+ end
410
+ end
411
+ end
412
+ # :nocov:
413
+
330
414
  def compile_template_method(local_keys, scope_class=nil)
331
415
  source, offset = precompiled(local_keys)
332
- local_code = local_extraction(local_keys)
416
+ if @fixed_locals
417
+ method_args = @fixed_locals
418
+ else
419
+ method_args = "(locals)"
420
+ local_code = local_extraction(local_keys)
421
+ end
333
422
 
334
423
  method_name = "__tilt_#{Thread.current.object_id.abs}"
335
424
  method_source = String.new
@@ -340,7 +429,7 @@ module Tilt
340
429
  end
341
430
 
342
431
  # Don't indent method source, to avoid indentation warnings when using compiled paths
343
- method_source << "::Tilt::TOPOBJECT.class_eval do\ndef #{method_name}(locals)\n#{local_code}\n"
432
+ method_source << "::Tilt::TOPOBJECT.class_eval do\ndef #{method_name}#{method_args}\n#{local_code}\n"
344
433
 
345
434
  offset += method_source.count("\n")
346
435
  method_source << source
@@ -397,6 +486,40 @@ module Tilt
397
486
  method
398
487
  end
399
488
 
489
+ # Set the fixed locals for the template, which may be nil if no fixed locals can
490
+ # be determined.
491
+ def set_fixed_locals
492
+ fixed_locals = @options.delete(:fixed_locals)
493
+ extract_fixed_locals = @options.delete(:extract_fixed_locals)
494
+ default_fixed_locals = @options.delete(:default_fixed_locals)
495
+
496
+ if fixed_locals.nil?
497
+ if extract_fixed_locals.nil?
498
+ extract_fixed_locals = Tilt.extract_fixed_locals
499
+ end
500
+
501
+ if extract_fixed_locals
502
+ fixed_locals = extract_fixed_locals()
503
+ end
504
+
505
+ if fixed_locals.nil?
506
+ fixed_locals = default_fixed_locals
507
+ end
508
+ end
509
+
510
+ @fixed_locals = fixed_locals
511
+ end
512
+
513
+ # Extract fixed locals from the template code string. Should return nil
514
+ # if there are no fixed locals specified, or a method argument string
515
+ # surrounded by parentheses if there are fixed locals. The method
516
+ # argument string will be used when defining the template method if given.
517
+ def extract_fixed_locals
518
+ if @data.is_a?(String) && (match = /\#\s*locals:\s*(\(.*\))/.match(@data))
519
+ match[1]
520
+ end
521
+ end
522
+
400
523
  def extract_encoding(script, &block)
401
524
  extract_magic_comment(script, &block) || script.encoding
402
525
  end
@@ -475,5 +598,9 @@ module Tilt
475
598
  # Do nothing, since compiled method cache is not used.
476
599
  def set_compiled_method_cache
477
600
  end
601
+
602
+ # Do nothing, since fixed locals are not used.
603
+ def set_fixed_locals
604
+ end
478
605
  end
479
606
  end
@@ -5,12 +5,16 @@ require_relative 'tilt/template'
5
5
  # Namespace for Tilt. This module is not intended to be included anywhere.
6
6
  module Tilt
7
7
  # Current version.
8
- VERSION = '2.5.0'
8
+ VERSION = '2.6.0'
9
+
10
+ EMPTY_ARRAY = [].freeze
11
+ private_constant :EMPTY_ARRAY
9
12
 
10
13
  EMPTY_HASH = {}.freeze
11
14
  private_constant :EMPTY_HASH
12
15
 
13
16
  @default_mapping = Mapping.new
17
+ @extract_fixed_locals = false
14
18
 
15
19
  # Replace the default mapping with a finalized version of the default
16
20
  # mapping. This can be done to improve performance after the template
@@ -86,6 +90,10 @@ module Tilt
86
90
  # @return [Tilt::Mapping] the main mapping object
87
91
  attr_reader :default_mapping
88
92
 
93
+ # Whether to extract fixed locals from templates by scanning the
94
+ # template content.
95
+ attr_accessor :extract_fixed_locals
96
+
89
97
  # Alias register as prefer for Tilt 1.x compatibility.
90
98
  alias prefer register
91
99
  end
@@ -1,5 +1,78 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 3.1.4
4
+
5
+ - Fix that skin tone modifiers were ignored when used in a non-ZWJ sequence
6
+ context (= single emoji char + modifier) #29
7
+ - Add more docs and specs about modifier handling
8
+
9
+ ## 3.1.3
10
+
11
+ Better handling of non-UTF-8 strings, patch by @Earlopain:
12
+
13
+ - Data with *BINARY* encoding is interpreted as UTF-8, if possible
14
+ - Use `invalid: :replace` and `undef: :replace` options when converting to UTF-8
15
+
16
+ ## 3.1.2
17
+
18
+ - Performance improvements
19
+
20
+ ## 3.1.1
21
+
22
+ - Performance improvements
23
+
24
+ ## 3.1.0
25
+
26
+ **Improve Emoji support:**
27
+
28
+ - Emoji modes: Differentiate between well-formed Emoji (`:possible`) and any
29
+ ZWJ/modifier sequence (`:all`). The latter is more common and more efficient
30
+ to implement.
31
+ - Unify `:rgi_{fqe,mqe,uqe}` options to just `:rgi` to keep things simpler (corresponds to
32
+ the former `:rgi_uqe` option). Most terminals that want to support the RGI set
33
+ will probably want to catch Emoji sequences with missing VS16s.
34
+ - Add new `:all_no_vs16` and `:rgi_at` modes to be able to support some terminals
35
+ that needs these quirks
36
+ - Add alias `emoji: :auto` for `emoji: true` and `emoji: :none` for `emoji: false`
37
+ - `:auto` mode: Only consider terminal cells when recommending Emoji support level
38
+ (Emoji themselves might display differently)
39
+ - `:auto` mode: Set default Emoji mode for unknown/unsupported terminals to `:none`
40
+ - Rename `:basic` mode to `:vs16`
41
+
42
+ ## 3.0.1
43
+
44
+
45
+ - Add WezTerm and foot as good Emoji terminals
46
+
47
+ ## 3.0.0
48
+
49
+ **Rework Emoji support:**
50
+
51
+ - Emoji widths are now enabled by default
52
+ - Only reduce Emoji width to 2 when RGI Emoji detected (configurable)
53
+ - VS16 turns Emoji characters of width 1 into full-width
54
+ - Please note that Emoji parsing has a notable impact on performance.
55
+ You can use the `emoji: false` option to disable Emoji adjustments
56
+ - Tries to detect terminal's Emoji support level automatically (from ENV vars)
57
+
58
+ **Index fixes and updates:**
59
+
60
+ - Private-use characters are considered ambiguous (were given width 1 before)
61
+ - Fix that a few zero-width ignorable codepoints from recent Unicode were missing
62
+ - Consider the following separators to be zero-width:
63
+ - U+2028 - LINE SEPARATOR - Zl
64
+ - U+2029 - PARAGRAPH SEPARATOR - Zp
65
+
66
+ **Other:**
67
+
68
+ - Add keyword arguments to `Unicode::DisplayWidth.of`. If you are using a hash
69
+ with overwrite values as third parameter, be sure to put it in curly braces.
70
+ - Using third parameter or explicit hash as fourth parameter is deprecated,
71
+ please migrate to the keyword arguments API
72
+ - Gem raises `ArgumentError` for ambiguous values other than 1 or 2
73
+ - Performance optimizations
74
+ - Require Ruby 2.5
75
+
3
76
  ## 2.6.0
4
77
 
5
78
  - Unicode 16
@@ -40,8 +113,26 @@ More performance improvements:
40
113
 
41
114
  ## 2.0.0
42
115
 
43
- - Release 2.0.0
44
- - Supports Ruby 3.0
116
+ Add Support for Ruby 3.0
117
+
118
+ ### Breaking Changes
119
+
120
+ Some features of this library were marked deprecated for a long time and have been removed with Version 2.0:
121
+
122
+ - Aliases of display\_width (…\_size, …\_length) have been removed
123
+ - Auto-loading of string core extension has been removed:
124
+
125
+ If you are relying on the `String#display_width` string extension to be automatically loaded (old behavior), please load it explicitly now:
126
+
127
+ ```ruby
128
+ require "unicode/display_width/string_ext"
129
+ ```
130
+
131
+ You could also change your `Gemfile` line to achieve this:
132
+
133
+ ```ruby
134
+ gem "unicode-display_width", require: "unicode/display_width/string_ext"
135
+ ```
45
136
 
46
137
  ## 2.0.0.pre2
47
138
 
@@ -0,0 +1,194 @@
1
+ # Unicode::DisplayWidth [![[version]](https://badge.fury.io/rb/unicode-display_width.svg)](https://badge.fury.io/rb/unicode-display_width) [<img src="https://github.com/janlelis/unicode-display_width/workflows/Test/badge.svg" />](https://github.com/janlelis/unicode-display_width/actions?query=workflow%3ATest)
2
+
3
+ Determines the monospace display width of a string in Ruby, which is useful for all kinds of terminal-based applications. The implementation is based on [EastAsianWidth.txt](https://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt), the [Emoji specfication](https://www.unicode.org/reports/tr51/) and other data, 100% in Ruby. It does not rely on the OS vendor ([wcwidth()](https://github.com/janlelis/wcswidth-ruby)) to provide an up-to-date method for measuring string width in terminals.
4
+
5
+ Unicode version: **16.0.0** (September 2024)
6
+
7
+ ## Gem Version 3 — Improved Emoji Support
8
+
9
+ **Emoji support is now enabled by default.** See below for description and configuration possibilities.
10
+
11
+ **Unicode::DisplayWidth.of now takes keyword arguments:** { ambiguous:, emoji:, overwrite: }
12
+
13
+ See [CHANGELOG](/CHANGELOG.md) for details.
14
+
15
+ ## Gem Version 2.4.2 — Performance Updates
16
+
17
+ **If you use this gem, you should really upgrade to 2.4.2 or newer. It's often 100x faster, sometimes even 1000x and more!**
18
+
19
+ This is possible because the gem now detects if you use very basic (and common) characters, like ASCII characters. Furthermore, the character width lookup code has been optimized, so even when the string involves full-width or ambiguous characters, the gem is much faster now.
20
+
21
+ ## Introduction to Character Widths
22
+
23
+ Guessing the correct space a character will consume on terminals is not easy. There is no single standard. Most implementations combine data from [East Asian Width](https://www.unicode.org/reports/tr11/), some [General Categories](https://en.wikipedia.org/wiki/Unicode_character_property#General_Category), and hand-picked adjustments.
24
+
25
+ ### How this Library Handles Widths
26
+
27
+ Further at the top means higher precedence. Please expect changes to this algorithm with every MINOR version update (the X in 1.X.0)!
28
+
29
+ Width | Characters | Comment
30
+ -------|------------------------------|--------------------------------------------------
31
+ ? | (user defined) | Overwrites any other values
32
+ ? | Emoji | See "How this Library Handles Emoji Width" below
33
+ -1 | `"\b"` | Backspace (total width never below 0)
34
+ 0 | `"\0"`, `"\x05"`, `"\a"`, `"\n"`, `"\v"`, `"\f"`, `"\r"`, `"\x0E"`, `"\x0F"` | [C0 control codes](https://en.wikipedia.org/wiki/C0_and_C1_control_codes#C0_.28ASCII_and_derivatives.29) which do not change horizontal width
35
+ 1 | `"\u{00AD}"` | SOFT HYPHEN
36
+ 2 | `"\u{2E3A}"` | TWO-EM DASH
37
+ 3 | `"\u{2E3B}"` | THREE-EM DASH
38
+ 0 | General Categories: Mn, Me, Zl, Zp, Cf (non-arabic)| Excludes ARABIC format characters
39
+ 0 | Derived Property: Default_Ignorable_Code_Point | Ignorable ranges
40
+ 0 | `"\u{1160}".."\u{11FF}"`, `"\u{D7B0}".."\u{D7FF}"` | HANGUL JUNGSEONG
41
+ 2 | East Asian Width: F, W | Full-width characters
42
+ 2 | `"\u{3400}".."\u{4DBF}"`, `"\u{4E00}".."\u{9FFF}"`, `"\u{F900}".."\u{FAFF}"`, `"\u{20000}".."\u{2FFFD}"`, `"\u{30000}".."\u{3FFFD}"` | Full-width ranges
43
+ 1 or 2 | East Asian Width: A | Ambiguous characters, user defined, default: 1
44
+ 1 | All other codepoints | -
45
+
46
+ ## Install
47
+
48
+ Install the gem with:
49
+
50
+ $ gem install unicode-display_width
51
+
52
+ Or add to your Gemfile:
53
+
54
+ gem 'unicode-display_width'
55
+
56
+ ## Usage
57
+
58
+ ```ruby
59
+ require 'unicode/display_width'
60
+
61
+ Unicode::DisplayWidth.of("⚀") # => 1
62
+ Unicode::DisplayWidth.of("一") # => 2
63
+ ```
64
+
65
+ ### Ambiguous Characters
66
+
67
+ The second parameter defines the value returned by characters defined as ambiguous:
68
+
69
+ ```ruby
70
+ Unicode::DisplayWidth.of("·", 1) # => 1
71
+ Unicode::DisplayWidth.of("·", 2) # => 2
72
+ ```
73
+
74
+ ### Encoding Notes
75
+
76
+ - Data with *BINARY* encoding is interpreted as UTF-8, if possible
77
+ - Non-UTF-8 strings are converted to UTF-8 before measuring, using the [`{invalid: :replace, undef: :replace}`) options](https://ruby-doc.org/3.3.5/encodings_rdoc.html#label-Encoding+Options)
78
+
79
+ ### Custom Overwrites
80
+
81
+ You can overwrite how to handle specific code points by passing a hash (or even a proc) as `overwrite:` parameter:
82
+
83
+ ```ruby
84
+ Unicode::DisplayWidth.of("a\tb", 1, overwrite: { "\t".ord => 10 })) # => TAB counted as 10, result is 12
85
+ ```
86
+
87
+ Please note that using overwrites disables some perfomance optimizations of this gem.
88
+
89
+ ### Emoji
90
+
91
+ If your terminal supports it, the gem detects Emoji and Emoji sequences and adjusts the width of the measured string. This can be disabled by passing `emoji: false` as an argument:
92
+
93
+ ```ruby
94
+ Unicode::DisplayWidth.of "🤾🏽‍♀️", emoji: :all # => 2
95
+ Unicode::DisplayWidth.of "🤾🏽‍♀️", emoji: false # => 5
96
+ ```
97
+
98
+ #### How this Library Handles Emoji Width
99
+
100
+ There are many Emoji which get constructed by combining other Emoji in a sequence. This makes measuring the width complicated, since terminals might either display the combined Emoji or the separate parts of the Emoji individually.
101
+
102
+ Another aspect where terminals disagree is whether Emoji characters which have a text presentation by default (width 1) should be turned into full-width (width 2) when combined with Variation Selector 16 (*U+FEOF*).
103
+
104
+ Finally, it varies if Skin Tone Modifiers can be applied to all characters or just to those with the "Emoji Base" property.
105
+
106
+ Emoji Type | Width / Comment
107
+ ------------|----------------
108
+ Basic/Single Emoji character without Variation Selector | No special handling
109
+ Basic/Single Emoji character with VS15 (Text) | No special handling
110
+ Basic/Single Emoji character with VS16 (Emoji) | 2 or East Asian Width (see table below)
111
+ Single Emoji character with Skin Tone Modifier | 2
112
+ Skin Tone Modifier used in isolation or with invalid base | 2 if Emoji mode is configured to `:rgi` / `:rgi_at`
113
+ Emoji Sequence | 2 if Emoji belongs to configured Emoji set (see table below)
114
+
115
+ #### Emoji Modes
116
+
117
+ The `emoji:` option can be used to configure which type of Emoji should be considered to have a width of 2 and if VS16-Emoji should be widened. Other sequences are treated as non-combined Emoji, so the widths of all partial Emoji add up (e.g. width of one basic Emoji + one skin tone modifier + another basic Emoji). The following Emoji settings can be used:
118
+
119
+ `emoji:` Option | VS16-Emoji Width | Emoji Sequences Width / Comment | Example Terminals
120
+ ----------------|------------------|---------------------------------|------------------
121
+ `true` or `:auto` | - | Automatically use recommended Emoji setting for your terminal | -
122
+ `:all` | 2 | 2 for all ZWJ/modifier/keycap sequences, even if they are not well-formed Emoji sequences | iTerm, foot
123
+ `:all_no_vs16` | EAW (1 or 2) | 2 for all ZWJ/modifier/keycap sequences, even if they are not well-formed Emoji sequences | WezTerm
124
+ `:possible`| 2 | 2 for all possible/well-formed Emoji sequences | ?
125
+ `:rgi` | 2 | 2 for all [RGI Emoji](https://www.unicode.org/reports/tr51/#def_rgi_set) sequences | ?
126
+ `:rgi_at` | EAW (1 or 2) | 1 or 2: Like `:rgi`, but Emoji sequences starting with a default-text Emoji have EAW | Apple Terminal
127
+ `:vs16` | 2 | 2 * number of partial Emoji (sequences never considered to represent a combined Emoji) | kitty?
128
+ `false` or `:none` | EAW (1 or 2) | No Emoji adjustments | gnome-terminal, many older terminals
129
+
130
+ - *EAW:* East Asian Width
131
+ - *RGI Emoji:* Emoji Recommended for General Interchange
132
+ - *ZWJ:* Zero-width Joiner: Codepoint `U+200D`,used in many Emoji sequences
133
+
134
+ #### Emoji Support in Terminals
135
+
136
+ Unfortunately, the level of Emoji support varies a lot between terminals. While some of them are able to display (almost) all Emoji sequences correctly, others fall back to displaying sequences of basic Emoji. When `emoji: true` or `emoji: :auto` is used, the gem will attempt to set the best fitting Emoji setting for you (e.g. `:rgi_at` on "Apple_Terminal" or `false` on Gnome's terminal widget).
137
+
138
+ Please note that Emoji display and number of terminal columns used might differs a lot. For example, it might be the case that a terminal does not understand which Emoji to display, but still manages to calculate the proper amount of terminal cells. The automatic Emoji support level per terminal only considers the latter (cursor position), not the actual Emoji image(s) displayed. Please [open an issue](https://github.com/janlelis/unicode-display_width/issues/new) if you notice your terminal application could use a better default value. Also see the [ucs-detect project](https://ucs-detect.readthedocs.io/results.html), which is a great resource that compares various terminal's Unicode/Emoji capabilities. You can visually check how your terminals renders different kind of Emoji types with the [terminal-emoji-width.rb script](https://github.com/janlelis/unicode-display_width/blob/main/misc/terminal-emoji-width.rb).
139
+
140
+ **To terminal implementors reading this:** Although the practice of giving all Emoji/ZWJ sequences a width of 2 (`:all` mode described above) has some advantages, it does not lead to a particularly good developer experience. Since there is always the possibility of well-formed Emoji that are currently not supported (non-RGI / future Unicode) appearing, those sequences will take more cells. Instead of overflowing, cutting off sequences or displaying placeholder-Emoji, could it be worthwile to implement the `:rgi` option (only known Emoji get width 2) and give those unknown Emoji the space they need? This would support the idea that the meaning of an unknown Emoji sequence can still be conveyed (without messing up the terminal at the same time). Just a thought…
141
+
142
+ ### Usage with String Extension
143
+
144
+ ```ruby
145
+ require 'unicode/display_width/string_ext'
146
+
147
+ "⚀".display_width # => 1
148
+ '一'.display_width # => 2
149
+ ```
150
+
151
+ ### Usage with Config Object
152
+
153
+ You can use a config object that allows you to save your configuration for later-reuse. This requires an extra line of code, but has the advantage that you'll need to define your string-width options only once:
154
+
155
+ ```ruby
156
+ require 'unicode/display_width'
157
+
158
+ display_width = Unicode::DisplayWidth.new(
159
+ # ambiguous: 1,
160
+ overwrite: { "A".ord => 100 },
161
+ emoji: :all,
162
+ )
163
+
164
+ display_width.of "⚀" # => 1
165
+ display_width.of "🤠‍🤢" # => 2
166
+ display_width.of "A" # => 100
167
+ ```
168
+
169
+ ### Usage from the Command-Line
170
+
171
+ Use this one-liner to print out display widths for strings from the command-line:
172
+
173
+ ```
174
+ $ gem install unicode-display_width
175
+ $ ruby -r unicode/display_width -e 'puts Unicode::DisplayWidth.of $*[0]' -- "一"
176
+ ```
177
+ Replace "一" with the actual string to measure
178
+
179
+ ## Other Implementations & Discussion
180
+
181
+ - Python: https://github.com/jquast/wcwidth
182
+ - JavaScript: https://github.com/mycoboco/wcwidth.js
183
+ - C: https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
184
+ - C for Julia: https://github.com/JuliaLang/utf8proc/issues/2
185
+ - Golang: https://github.com/rivo/uniseg
186
+
187
+ See [unicode-x](https://github.com/janlelis/unicode-x) for more Unicode related micro libraries.
188
+
189
+ ## Copyright & Info
190
+
191
+ - Copyright (c) 2011, 2015-2024 Jan Lelis, https://janlelis.com, released under the MIT
192
+ license
193
+ - Early versions based on runpaint's unicode-data interface: Copyright (c) 2009 Run Paint Run Run
194
+ - Unicode data: https://www.unicode.org/copyright.html#Exhibit1
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Unicode
4
4
  class DisplayWidth
5
- VERSION = "2.6.0"
5
+ VERSION = "3.1.4"
6
6
  UNICODE_VERSION = "16.0.0"
7
7
  DATA_DIRECTORY = File.expand_path(File.dirname(__FILE__) + "/../../../data/")
8
8
  INDEX_FILENAME = DATA_DIRECTORY + "/display_width.marshal.gz"
@@ -0,0 +1,52 @@
1
+ # require "rbconfig"
2
+ # RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ # windows
3
+
4
+ module Unicode
5
+ class DisplayWidth
6
+ module EmojiSupport
7
+ # Tries to find out which terminal emulator is used to
8
+ # set emoji: config to best suiting value
9
+ #
10
+ # Please also see section in README.md and
11
+ # misc/terminal-emoji-width.rb
12
+ #
13
+ # Please note: Many terminals do not set any ENV vars,
14
+ # maybe CSI queries can help?
15
+ def self.recommended
16
+ if ENV["CI"]
17
+ return :rqi
18
+ end
19
+
20
+ case ENV["TERM_PROGRAM"]
21
+ when "iTerm.app"
22
+ return :all
23
+ when "Apple_Terminal"
24
+ return :rgi_at
25
+ when "WezTerm"
26
+ return :all_no_vs16
27
+ end
28
+
29
+ case ENV["TERM"]
30
+ when "contour","foot"
31
+ # konsole: all, how to detect?
32
+ return :all
33
+ when /kitty/
34
+ return :vs16
35
+ end
36
+
37
+ if ENV["WT_SESSION"] # Windows Terminal
38
+ return :vs16
39
+ end
40
+
41
+ # As of last time checked: gnome-terminal, vscode, alacritty
42
+ :none
43
+ end
44
+
45
+ # Maybe: Implement something like https://github.com/jquast/ucs-detect
46
+ # which uses the terminal cursor to check for best support level
47
+ # at runtime
48
+ # def self.detect!
49
+ # end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,14 @@
1
+ # Experimental
2
+ # Patches Reline's get_mbchar_width to use Unicode::DisplayWidth
3
+
4
+ require "reline"
5
+ require "reline/unicode"
6
+
7
+ require_relative "../display_width"
8
+
9
+ class Reline::Unicode
10
+ def self.get_mbchar_width(mbchar)
11
+ Unicode::DisplayWidth.of(mbchar, Reline.ambiguous_width)
12
+ end
13
+ end
14
+