1

I have a blog in Rails in which I want to formalize the external links in the content part, for example to keep track of clicks, broken links etc.

I have started creating my own type of markup in which I use the following:

block_code = [[LINK_A##URL:http://www.exampleA.com##ANCHOR:A]]
block_code = [[LINK_B##URL:http://www.exampleB.com##ANCHOR:B]]

The interpretation of these strings/markups are quite easy (since I have specified them myself) in order to extract info about whether it is LINK_A or LINK_B and the URL-value. I do this with a function:

render_markup(block_code) #=> "<a href='http://www.exampleA.com'>A</a>"

What I need to do now is to have a function that iteratest through a text and when it finds my block_codes, replaces them with the result of render_markup().

example_content = "Today was a really nice day when I went to the [[LINK_A##URL:http://www.thepark.com##ANCHOR:The park]] where I had a [[LINK_B##URL:http://www.swim.com##ANCHOR:swim]] and this was very nice"

so that when I do:

scan_and_replace(example_content)

it creates:

"Today was a really nice day when I went to the <a href='http://www.thepark.com'>the park</a> where I had a <a href='http://swim.com'>swim</a> and this was very nice."

whenever it encounters my codes blocks in the text.

So, what I need help with is finding and replacing these code blocks, i.e. creating scan_and_replace() function. I do NOT need help in rendering my code block into HTML, that is already working.

If this proves too difficult or if you find this method really bad (and know a better method that solves the same problem), let me know!

Christoffer
  • 2,271
  • 3
  • 26
  • 57

1 Answers1

1

You can simply use gsub to replace the markup with the link as follows. The only difficult part here is the regular expression /\[\[.*?##URL:(.*?)##ANCHOR:(.*?)\]\]/ which means 'search for the characters [[ and assign everything found between the group delimiter () to $1, everything in the second group to $2 and call the render function with each match.

def render_markup url, anchor
  "<a href='#{url}'>#{anchor}</a>"
end

def scan_and_replace content
  content.gsub(/\[\[.*?##URL:(.*?)##ANCHOR:(.*?)\]\]/){|m| render_markup($1, $2) }
end

example_content = "Today was a really nice day when I went to the [[LINK_A##URL:http://www.thepark.com##ANCHOR:The park]] where I had a [[LINK_B##URL:http://www.swim.com##ANCHOR:swim]] and this was very nice"
puts scan_and_replace example_content

#=>Today was a really nice day when I went to the <a href='http://www.thepark.com'>The park</a> where I had a <a href='http://www.swim.com'>swim</a> and this was very nice
peter
  • 41,770
  • 5
  • 64
  • 108
  • Actually, it didn't really work. It was only your example that worked (try returning "block_code" and you will see). In render_markup the attribute block_code is nil. Basically, render_markup($1) does not send anything as $1. Do you have any ideas how to make that work... – Christoffer May 14 '14 at 15:25
  • sorry, i should use the block form of gsub, see http://stackoverflow.com/questions/288573/1-and-1-in-ruby for an explanation, i adapted my answer, i also implemented your render function to be sure – peter May 14 '14 at 19:22
  • This is correct. In the end I adapted your answer into using content.scan, a bit uglier but fitted my purposes a bit more. Thanks! – Christoffer May 15 '14 at 06:55