F4192eeb4b26e96deab8b5c68926105d

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.

def unbold_pipes (wikibold_string)
     wikibold_string.
      split('|').
      join("'''|'''").
      split(/(.*\[\[.+?)'''\|'''(.+?\]\].*)/). 
      delete_if {|x| x == "" }.
      join("|")
end

Refactorings

No refactoring yet !

D85d44a0eca045f40e5a31449277c26c

Ben Marini

September 19, 2009, September 19, 2009 16:58, permalink

1 rating. Login to rate!

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
F4192eeb4b26e96deab8b5c68926105d

Muke Tever

September 20, 2009, September 20, 2009 21:15, permalink

No rating. Login to rate!

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
D85d44a0eca045f40e5a31449277c26c

Ben Marini

September 21, 2009, September 21, 2009 00:52, permalink

No rating. Login to rate!

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

Your refactoring





Format Copy from initial code

or Cancel