console | Dmytro Shteflyuk's Home https://kpumuk.info In my blog I'll try to describe about interesting technologies, my discovery in IT and some useful things about programming. Tue, 08 Sep 2015 00:15:31 +0000 en-US hourly 1 https://wordpress.org/?v=6.7.1 Generating permalink from string in Ruby https://kpumuk.info/ruby-on-rails/generating-permalink-from-string-in-ruby/ https://kpumuk.info/ruby-on-rails/generating-permalink-from-string-in-ruby/#comments Mon, 14 May 2007 15:27:39 +0000 http://kpumuk.info/ruby-on-rails/generating-permalink-from-string-in-ruby/ If you are creating Ruby on Rails application like a blog, you most probably want to generate URLs using post titles. It’s good practice, because search engines like keywords in URL, and it looks more human-readable. Just compare: http://example.com/posts/10 and http://example.com/posts/generating-permalinks-from-string (yeah, it’s long, but self-descriptive). Anyways, this is small post about converting a title […]

The post Generating permalink from string in Ruby first appeared on Dmytro Shteflyuk's Home.]]>
If you are creating Ruby on Rails application like a blog, you most probably want to generate URLs using post titles. It’s good practice, because search engines like keywords in URL, and it looks more human-readable. Just compare: http://example.com/posts/10 and http://example.com/posts/generating-permalinks-from-string (yeah, it’s long, but self-descriptive). Anyways, this is small post about converting a title to a permalink.

First thing I love in Ruby is an ability to extend classes with my own methods. I could just add method to_permalink to any string and then everywhere I could write something like @post.title.to_permalink. It’s amazing!

Here is my version of to_permalink method:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class String
  def to_permalink
    result = strip_tags
    # Preserve escaped octets.
    result.gsub!(/-+/, '-')
    result.gsub!(/%([a-f0-9]{2})/i, '--\1--')
    # Remove percent signs that are not part of an octet.
    result.gsub!('%', '-')
    # Restore octets.
    result.gsub!(/--([a-f0-9]{2})--/i, '%\1')

    result.gsub!(/&.+?;/, '-') # kill entities
    result.gsub!(/[^%a-z0-9_-]+/i, '-')
    result.gsub!(/-+/, '-')
    result.gsub!(/(^-+|-+$)/, '')
    return result.downcase
  end

  private
 
    def strip_tags
      return clone if blank?
      if index('<')
        text = ''
        tokenizer = HTML::Tokenizer.new(self)

        while token = tokenizer.next
          node = HTML::Node.parse(nil, 0, 0, token, false)
          # result is only the content of any Text nodes
          text << node.to_s if node.class == HTML::Text
        end
        # strip any comments, and if they have a newline at the end (ie. line with
        # only a comment) strip that too
        text.gsub(/<!--(.*?)-->[\n]?/m, '')
      else
        clone # already plain text
      end
    end
end

How it’s working? First thing you would see is a private method strip_tags. Yes, I know about ActionView::Helpers::TextHelper::strip_tags, and this is almost 100% copy of Rails version (the only difference is that my version always returns clone of the original string). I just don’t want to rely on the Rails library.

Then my method replaces all special characters with dashes (only octets like %A0 would be kept), and trims dashed from the beginning and the end of the string. Finally full string will be lowercased.

Of course, in your application you should check collisions (several posts which have the same title should have unique permalinks, for example you could append numbers starting from 1: hello, hello-1, hello-2, etc). This is not my goal to cover all difficulties you could face, it’s small post, do you remember?

Just for your pleasure, here are the RSpec tests for this method:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
describe 'String.to_permalink from extensions.rb' do
  it 'should replace all punctuation marks and spaces with dashes' do
    "!.@#$\%^&*()Test case\n\t".to_permalink.should == 'test-case'
  end

  it 'should preserve _ symbol' do
    "Test_case".to_permalink.should == 'test_case'
  end
 
  it 'should preserve escaped octets and remove redundant %' do
    'Test%%20case'.to_permalink.should == 'test-%20case'
  end

  it 'should strip HTML tags' do
    '<a href="http://example.com">Test</a> <b>case</b>'.to_permalink.should == 'test-case'
  end

  it 'should strip HTML entities and insert dashes' do
    'Test&nbsp;case'.to_permalink.should == 'test-case'
  end

  it 'should trim beginning and ending dashes' do
    '-. Test case .-'.to_permalink.should == 'test-case'
  end

  it 'should not use ---aa--- as octet' do
    'b---aa---b'.to_permalink.should == 'b-aa-b'
  end
 
  it 'should replace % with -' do
    'Hello%world'.to_permalink.should == 'hello-world'
  end

  it 'should not modify original string' do
    s = 'Hello,&nbsp;<b>world</b>%20'
    s.to_permalink.should == 'hello-world%20'
    s.should == 'Hello,&nbsp;<b>world</b>%20'

    s = 'Hello'
    s.to_permalink.should == 'hello'
    s.should == 'Hello'
  end
end

It’s funny, right?

The post Generating permalink from string in Ruby first appeared on Dmytro Shteflyuk's Home.]]>
https://kpumuk.info/ruby-on-rails/generating-permalink-from-string-in-ruby/feed/ 5
Colorizing console Ruby-script output https://kpumuk.info/ruby-on-rails/colorizing-console-ruby-script-output/ https://kpumuk.info/ruby-on-rails/colorizing-console-ruby-script-output/#comments Fri, 23 Mar 2007 16:28:06 +0000 http://kpumuk.info/ruby-on-rails/colorizing-console-ruby-script-output/ Very often I have to implement console scripts (because of my laziness, for boring processes optimization). Many of them write some information to the output, show process status or display results of work. Anyway, it’s very wearisome action to read script output, and I want to highlight most important things: errors in red, successfully finished […]

The post Colorizing console Ruby-script output first appeared on Dmytro Shteflyuk's Home.]]>
Very often I have to implement console scripts (because of my laziness, for boring processes optimization). Many of them write some information to the output, show process status or display results of work. Anyway, it’s very wearisome action to read script output, and I want to highlight most important things: errors in red, successfully finished steps in green color, etc. And it is a case when ANSI escape sequences could help. They are supported by the most terminals, including VT100 (btw, Windows NT family console does not support it, but I will back to this issue later).

For the beginning, let’s examine ANSI escape sequence structure. It starts with ESC symbol (ASCII-code 27), following by left square bracket [. There are one or more numbers separated by semicolon ; with a letter at the end appear after it.

I will not describe all possible codes, anybody who wishes could find them in Wikipedia. The sequence with m letter at the end is used to change foreground and background colors. In general situation it looks like: ESC[31m, where 31 sets red color as foreground. Here the table with codes which supported by most terminals:

Code Effect
0 Turn off all attributes
1 Set bright mode
4 Set underline mode
5 Set blink mode
7 Exchange foreground and background colors
8 Hide text (foreground color would be the same as background)
30 Black text
31 Red text
32 Green text
33 Yellow text
34 Blue text
35 Magenta text
36 Cyan text
37 White text
39 Default text color
40 Black background
41 Red background
42 Green background
43 Yellow background
44 Blue background
45 Magenta background
46 Cyan background
47 White background
49 Default background color

As you could see from the table, you are able to set foreground and background colors separately, also you could combine them into one sequence (for example, ESC[1;33;44m – bright yellow text on blue background).

Attention: Don’t forget to turn off all attributes before exit, otherwise all following text would be displayed with your attributes.

That’s enough of the theory, let’s examine example:

1
2
3
4
# Actual work
puts "Importing categories [ e[32mDONEe[0m ]"
# Actual work
puts "Importing tags       [e[31mFAILEDe[0m]"

As the result you will see something like following:

VT100 Example 1

All my life I used codes just like shown in the previous example, but not so long ago I found simple helpers when delving in the RSpec sources:

1
2
3
4
5
6
7
8
9
10
11
def colorize(text, color_code)
  "#{color_code}#{text}e[0m"
end

def red(text); colorize(text, "e[31m"); end
def green(text); colorize(text, "e[32m"); end

# Actual work
puts 'Importing categories [ ' + green('DONE') + ' ]'
# Actual work
puts 'Importing tags       [' + red('FAILED') + ']'

It’s a good idea, and now I’m using it. And recommend it to you :-)

Now about sorrowful things. Windows XP (and as far as I remember, Windows 2000 too) does not support ANSI escape sequences. If you are love perversions, look at the Command Interpreter Ansi Support article. Others could stay here and look, how to solve problem using Ruby facilities.

You should install win32console first:

1
gem install win32console

Now add following lines at the beginning of your script (and again, I found them in RSpec):

1
2
3
4
5
begin
  require 'Win32/Console/ANSI' if RUBY_PLATFORM =~ /win32/
rescue LoadError
  raise 'You must gem install win32console to use color on Windows'
end

Script output will be colorized both on windows and Unix systems.

And in the end I will show full table of different codes, which you could use in your scripts:

VT100 Terminal

It has been obtained using following script:

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/ruby

[0, 1, 4, 5, 7].each do |attr|
  puts '----------------------------------------------------------------'
  puts "ESC[#{attr};Foreground;Background"
  30.upto(37) do |fg|
    40.upto(47) do |bg|
      print "\033[#{attr};#{fg};#{bg}m #{fg};#{bg}  "
    end
  puts "\033[0m"
  end
end

Updated 06/10/2010: Replaced PLATFORM constant with the RUBY_PLATFORM (thanks to Ian Alexander Wood).

The post Colorizing console Ruby-script output first appeared on Dmytro Shteflyuk's Home.]]>
https://kpumuk.info/ruby-on-rails/colorizing-console-ruby-script-output/feed/ 10