Ruby way for piece of code

(Alexandru Popescu) #1

Hi!

I have the following hypothesis: a piece of text containing anywhere a line with the following content:

[code]
tags: tagone tagtwo
[/code]

with any number of tagnames on that line.

Finally I want to modify the above text where every tagname is replaced by [[tagname => tagname]]

This is the code I have done, but I feel it is not the rubyiest:

[code]
  def prepare_content(new_content)
      updated_content = ""
      new_content.each_line do |line|
          if line !~ /^tags: /i
              updated_content += line
              next
    end

          tokens = line.split(%r{\s+})
          depth = 0
          1.upto(tokens.length - 1) do |index|
              if tokens[index][0, 2] == "[["
                   depth += 1
                   next
        end
        if tokens[index][-2, 2] == "]]"
      depth -= 1
      next
        end
                
        if depth == 0
      page.tags << tokens[index]
      regexp = Regexp.new( '\s+(' + tokens[index] + ')\s*')
      line.sub!(regexp, ' [[\1 => \1]] ')
        end
    end
      end

      new_content += line
  end
[/code]

Note: the above code is able also to avoid the case where a tagname was already transformed into [[tagname => tagname]]

many thanks for any ruby ideas,
:alex |.::the_mindstorm::.|

(Jim Menard) #2

The code that replaces
    tag: a b c d b
with
    tag: [[a => a]] [[b => b]] [[c => c]] [[d => d]]
could be written

  new_content << 'tag:'
  line.split[1..-1].uniq.each { | tag | new_content << " [[#{tag} => #{tag}]]" }

Jim

···

--
Jim Menard, jim.menard@gmail.com, jimm@io.com
http://www.io.com/~jimm

(Nikolai Weibull) #3

Alexandru Popescu wrote:

I have the following hypothesis: a piece of text containing anywhere a line
with the following content:

[code]
tags: tagone tagtwo
[/code]

with any number of tagnames on that line.

Finally I want to modify the above text where every tagname is replaced by
[[tagname => tagname]]

  def prepare_content(new_content)
      updated_content = ""
      new_content.each_line do |line|
          if line !~ /^tags: /i
              updated_content += line
              next
    end

          tokens = line.split(%r{\s+})
          depth = 0
          1.upto(tokens.length - 1) do |index|
              if tokens[index][0, 2] == "[["
                   depth += 1
                   next
        end
        if tokens[index][-2, 2] == "]]"
      depth -= 1
      next
        end
                
        if depth == 0
      page.tags << tokens[index]
      regexp = Regexp.new( '\s+(' + tokens[index] + ')\s*')
      line.sub!(regexp, ' [[\1 => \1]] ')
        end
    end
      end

      new_content += line
  end

def prepare_content(new_content)
  updated_content = ""
  new_content.each do |line|
    if line =~ /^tags:\s+/i
      $'.split(/\s+/).each{ |t| updated_content << " [[#{t} => #{t}]]" }
      updated_content << "\n"
    else
      updated_content << line
    end
  end
  updated_content
end

This should do what you want, provided that I understand your
specification. I don't know where you get that page variable from, so I
didn't include code for it; your code is messy,
        nikolai

···

--
Nikolai Weibull: now available free of charge at http://bitwi.se/!
Born in Chicago, IL USA; currently residing in Gothenburg, Sweden.
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}

(Alexandru Popescu) #4

#: Jim Menard changed the world a bit at a time by saying on 8/24/2005 7:41 PM :#

The code that replaces
    tag: a b c d b
with
    tag: [[a => a]] [[b => b]] [[c => c]] [[d => d]]
could be written

  new_content << 'tag:'
  line.split[1..-1].uniq.each { | tag | new_content << " [[#{tag} => #{tag}]]" }

Jim

Nice but it misses the case where one of the tags where already changed.

:alex |.::the_mindstorm::.|

(Alexandru Popescu) #5

#: Nikolai Weibull changed the world a bit at a time by saying on 8/24/2005 8:07 PM :#

Alexandru Popescu wrote:

I have the following hypothesis: a piece of text containing anywhere a line with the following content:

[code]
tags: tagone tagtwo
[/code]

with any number of tagnames on that line.

Finally I want to modify the above text where every tagname is replaced by [[tagname => tagname]]

  def prepare_content(new_content)
      updated_content = ""
      new_content.each_line do |line|
          if line !~ /^tags: /i
              updated_content += line
              next
    end

          tokens = line.split(%r{\s+})
          depth = 0
          1.upto(tokens.length - 1) do |index|
              if tokens[index][0, 2] == "[["
                   depth += 1
                   next
        end
        if tokens[index][-2, 2] == "]]"
      depth -= 1
      next
        end
                
        if depth == 0
      page.tags << tokens[index]
      regexp = Regexp.new( '\s+(' + tokens[index] + ')\s*')
      line.sub!(regexp, ' [[\1 => \1]] ')
        end
    end
      end

      new_content += line
  end

def prepare_content(new_content)
  updated_content = ""
  new_content.each do |line|
    if line =~ /^tags:\s+/i
      $'.split(/\s+/).each{ |t| updated_content << " [[#{t} => #{t}]]" }
      updated_content << "\n"
    else
      updated_content << line
    end
  end
  updated_content
end

your code is messy,

Yes, I know, this is why I am asking to see how should I write it the Ruby way :-).

I have posted again the spec as it seems I haven't succeed to be clear from the beginning. Sorry.

:alex |.::the_mindstorm::.|

(Jim Menard) #6

Aah, alreadh changed on any previous line. Got it.

  done = [] # at the beginning, before any lines processed

  new_content << 'tag:'
  tags = line.split[1..-1]..each { | tag |
    unless done.include?(tag)
      new_content << " [[#{tag} => #{tag}]]"
      done << tag
    end
  }

Jim

···

On 8/24/05, Alexandru Popescu <the.mindstorm.mailinglist@gmail.com> wrote:

#: Jim Menard changed the world a bit at a time by saying on 8/24/2005 7:41 PM :#
> The code that replaces
> tag: a b c d b
> with
> tag: [[a => a]] [[b => b]] [[c => c]] [[d => d]]
> could be written
>
> new_content << 'tag:'
> line.split[1..-1].uniq.each { | tag | new_content << " [[#{tag} => #{tag}]]" }
>
> Jim

Nice but it misses the case where one of the tags where already changed.

--
Jim Menard, jim.menard@gmail.com, jimm@io.com
http://www.io.com/~jimm

(Nikolai Weibull) #7

Alexandru Popescu wrote:

> def prepare_content(new_content)
> updated_content = ""
> new_content.each do |line|
> if line =~ /^tags:\s+/i
> $'.split(/\s+/).each{ |t| updated_content << " [[#{t} => #{t}]]" }
> updated_content << "\n"
> else
> updated_content << line
> end
> end
> updated_content
> end
>
> your code is messy,

I have posted again the spec as it seems I haven't succeed to be clear
from the beginning. Sorry.

OK, so how about the following then:

def prepare_content(new_content)
  updated_content = ""
  new_content.each do |line|
    if line =~ /^tags:\s+/i
      $'.split(/\s+/).each do |token|
        if token =~ /\[\[.* => .*\]\]/
          updated_content << " " << token
        else
          updated_content << " [[#{t} => #{t}]]"
        end
      end
      updated_content << "\n"
    else
      updated_content << line
    end
  end
  updated_content
end

(Why, and how?, are you processing the document for tag-expansion
multiple times in this way?),
        nikolai

···

--
Nikolai Weibull: now available free of charge at http://bitwi.se/!
Born in Chicago, IL USA; currently residing in Gothenburg, Sweden.
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}

(Alexandru Popescu) #8

#: Jim Menard changed the world a bit at a time by saying on 8/24/2005 7:59 PM :#

#: Jim Menard changed the world a bit at a time by saying on 8/24/2005 7:41 PM :#
> The code that replaces
> tag: a b c d b
> with
> tag: [[a => a]] [[b => b]] [[c => c]] [[d => d]]
> could be written
>
> new_content << 'tag:'
> line.split[1..-1].uniq.each { | tag | new_content << " [[#{tag} => #{tag}]]" }
>
> Jim

Nice but it misses the case where one of the tags where already changed.

Aah, alreadh changed on any previous line. Got it.

  done = [] # at the beginning, before any lines processed

  new_content << 'tag:'
  tags = line.split[1..-1]..each { | tag |
    unless done.include?(tag)
      new_content << " [[#{tag} => #{tag}]]"
      done << tag
    end
  }

Jim

Damn I hate my english sometimes :-(.

I will try again:

initially:
case 1/
tags: a b c d

case 2/
tags: a [[b => b]] c [[d => d]]

The result should always be the same
tags: [[a => a]] [[b => b]] [[c => c]] [[d => d]]

Clarification:
at a previous step some of them can already be changed from
tags: a b c d
to
tags: a [[b => b]] c d

hope this time my english was good enough to express my stupid problem

:alex |.::the_mindstorm::.|

···

On 8/24/05, Alexandru Popescu <the.mindstorm.mailinglist@gmail.com> wrote:

(Jim Menard) #9

  done = [] # at the beginning, before any lines processed

  new_content << 'tag:'
  tags = line.split[1..-1]..each { | tag |

The "tags = line.split ... " should just read "line.split ... ". No
harm done if it's there

    unless done.include?(tag)
      new_content << " [[#{tag} => #{tag}]]"
      done << tag
    end
  }

Jim

···

On 8/24/05, Jim Menard <jim.menard@gmail.com> wrote:
--
Jim Menard, jim.menard@gmail.com, jimm@io.com
http://www.io.com/~jimm

(Alexandru Popescu) #10

#: Nikolai Weibull changed the world a bit at a time by saying on 8/24/2005 10:09 PM :#

Alexandru Popescu wrote:

> def prepare_content(new_content)
> updated_content = ""
> new_content.each do |line|
> if line =~ /^tags:\s+/i
> $'.split(/\s+/).each{ |t| updated_content << " [[#{t} => #{t}]]" }
> updated_content << "\n"
> else
> updated_content << line
> end
> end
> updated_content
> end
>
> your code is messy,

I have posted again the spec as it seems I haven't succeed to be clear
from the beginning. Sorry.

OK, so how about the following then:

def prepare_content(new_content)
  updated_content = ""
  new_content.each do |line|
    if line =~ /^tags:\s+/i
      $'.split(/\s+/).each do |token|
        if token =~ /\[\[.* => .*\]\]/
          updated_content << " " << token
        else
          updated_content << " [[#{t} => #{t}]]"
        end
      end
      updated_content << "\n"
    else
      updated_content << line
    end
  end
  updated_content
end

(Why, and how?, are you processing the document for tag-expansion
multiple times in this way?),
        nikolai

many thanks! it looks like Ruby now :-).

why and how:
Imagine it is f.e. a wiki page to which you are adding tags when you edit it, so just before saving it you can reach the situation where you have tags: a [[b => b]] c

:alex |.::the_mindstorm::.|