Module: HunkReviewChanges::Markdown
- Defined in:
- lib/hunk_review_changes/markdown.rb
Overview
Renders the prose fields (what/why/framing/flags) as GitHub-flavored Markdown.
Constant Summary collapse
- SAFE_SCHEMES =
Schemes allowed on rendered links and images. Kramdown does not sanitize URLs, so anything else (javascript:, data:, vbscript:, file:, ...) is neutralized to keep bundle prose from running script in the local app origin.
%w[http https mailto tel].freeze
Class Method Summary collapse
- .html(text) ⇒ Object
-
.inline(text) ⇒ Object
Unwrap a single top-level
so the prose can sit inline after a bold lead-in label ("What it does — ..."); multi-paragraph / list output is returned as-is.
- .safe_url?(url) ⇒ Boolean
-
.sanitize_urls(html) ⇒ Object
Replace the value of any href/src whose scheme is not allowlisted with "#", so a link like x renders inert while safe URLs pass untouched.
-
.url_scheme(url) ⇒ Object
The scheme a browser would act on: it decodes numeric entities and ignores control/whitespace characters before parsing the scheme, so normalize the same way.
Class Method Details
.html(text) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/hunk_review_changes/markdown.rb', line 16 def html(text) return "" if text.nil? || text.to_s.strip.empty? rendered = Kramdown::Document.new( text.to_s, input: "GFM", hard_wrap: true, auto_ids: false, parse_block_html: false, parse_span_html: false ).to_html.strip sanitize_urls(rendered) end |
.inline(text) ⇒ Object
Unwrap a single top-level
so the prose can sit inline after a bold lead-in label ("What it does — ..."); multi-paragraph / list output is returned as-is.
32 33 34 35 36 37 38 39 |
# File 'lib/hunk_review_changes/markdown.rb', line 32 def inline(text) rendered = html(text) if rendered.start_with?("<p>") && rendered.end_with?("</p>") && !rendered[3..-5].include?("<p") rendered[3..-5] else rendered end end |
.safe_url?(url) ⇒ Boolean
52 53 54 55 |
# File 'lib/hunk_review_changes/markdown.rb', line 52 def safe_url?(url) scheme = url_scheme(url) scheme.nil? || SAFE_SCHEMES.include?(scheme) end |
.sanitize_urls(html) ⇒ Object
Replace the value of any href/src whose scheme is not allowlisted with "#", so a link like x renders inert while safe URLs pass untouched.
43 44 45 46 47 48 49 50 |
# File 'lib/hunk_review_changes/markdown.rb', line 43 def sanitize_urls(html) html.gsub(/(\s(?:href|src)=)(["'])(.*?)\2/im) do attr = Regexp.last_match(1) quote = Regexp.last_match(2) url = Regexp.last_match(3) "#{attr}#{quote}#{safe_url?(url) ? url : "#"}#{quote}" end end |
.url_scheme(url) ⇒ Object
The scheme a browser would act on: it decodes numeric entities and ignores control/whitespace characters before parsing the scheme, so normalize the same way. Returns nil for relative/fragment/protocol-relative URLs (which are safe).
60 61 62 63 64 65 66 67 |
# File 'lib/hunk_review_changes/markdown.rb', line 60 def url_scheme(url) candidate = url .gsub(/&#x([0-9a-f]+);/i) { [Regexp.last_match(1).to_i(16)].pack("U") } .gsub(/&#(\d+);/) { [Regexp.last_match(1).to_i].pack("U") } .gsub(/&/i, "&") .gsub(/[[:cntrl:][:space:]]/, "") candidate[/\A([a-z][a-z0-9+.-]*):/i, 1]&.downcase end |