def unbold_pipes (wikibold_string)
wikibold_string.
split('|').
join("'''|'''").
split(/(.*\[\[.+?)'''\|'''(.+?\]\].*)/).
delete_if {|x| x == "" }.
join("|")
end
Refactorings
No refactoring yet !
Ben Marini
September 19, 2009, September 19, 2009 16:58, permalink
This code is a little more readable.
def unbold_pipes(str)
stack = 0
str.each_char.inject('') do |memo, char|
case char
when '[' : stack += 1
when ']' : stack -= 1
when '|' : char = "'''|'''" if stack.zero?
end
memo + char
end
end
Muke Tever
September 20, 2009, September 20, 2009 21:15, permalink
Doesn't apply to the immediate problem (of _un_bolding the pipes), but taken a level up does obviate the need for what I was doing, so that's even better. :x)
But your code doesn't handle the case which complicated my original, where there's more than one pipe between the brackets (in other words, I still needed [[one|two'''|'''three]] to happen). I modified your code a bit and came up with this, which seems (so far) to work exactly right:
def bold_around_pipes (str)
stack, functional = 0, false
"'''#{str}'''".each_char.inject('') do |memo, char|
case char
when '[' then stack, functional = stack + 1, true
when ']' then stack, functional = stack - 1, !stack.zero?
when '|' then stack.zero? || !functional ? char = "'''|'''" : functional = false
end
memo + char
end
end
Ben Marini
September 21, 2009, September 21, 2009 00:52, permalink
Ah, I think I understand it now. I rewrote it with some tests. Not sure if it's any clearer than your last post but figured I'd throw it up here anyways.
require "test/unit"
class TestUnboldPipes < Test::Unit::TestCase
def unbold_pipes(str)
stack, pipe_count = 0, 0
"'''#{str}'''".each_char.inject do |memo, char|
case char
when '[' : stack += 1
when ']'
stack -= 1
pipe_count = 0 if stack.zero?
when '|'
char = "'''|'''" unless ( stack == 2 && pipe_count == 0 )
pipe_count += 1
end
memo + char
end
end
def test_unbold_pipes
assert_equal "'''one'''|'''two'''|'''three'''", unbold_pipes("one|two|three")
assert_equal "'''[one'''|'''two'''|'''three]'''", unbold_pipes("[one|two|three]")
assert_equal "'''[[one|two'''|'''three]]'''", unbold_pipes("[[one|two|three]]")
end
end
This is supposed to be taking a string in 'wiki bold' (i.e. where "'''" represents begin bold and end bold) and unbolding the "|" signs. (I suppose you could also use it to bold "|" signs in non-wikibold text...)
The first split-join would do this in most cases, but... if there are pipes between pairs of square brackets in the input string, then the first pipe between each pair of square brackets serves a different function and shouldn't be replaced, so the last few lines are the kludge to do this.
Been trying to find a better way but it's been eluding me. I would have liked to do it in one split/join but can't seem to find a regexp to handle the condition. I'm sure there's something simple I'm overlooking.