Show only first couple of paragraphs. Ruby on Rails - ruby-on-rails

I am using simple_format(#company.description) to make a text into a number of paragraphs. On one page I only want to show, lets say, the first three paragraphs. Is there any nifty ruby method that can help out here or should I read up on my regular expression skills, which are very out of date.
Cheers Carl

The truncate helper method takes an optional :separator. Since simple_format uses <br /> tags to indicate paragraphs, you should be able to do something like this:
truncate(simple_format(#company.description), length: 3, separator: '<br />')

Personally, I'd round the text before putting it into a formatter. I'd assume you have a \r\n or \n in your text. Why format 1000 paragraphs if all you need is the first 3.
def get_first_paragraphs(text, desired = 3)
text.each_with_index do |character, index|
if(character == "\n")
desiredParCount -= 1
return text[0..index] if(desiredParCount <= 0)
end
end
return text;
end
It's a function sure, but it's the fastest method.. if speed is important. (it always is, ALWAYS!) :)

Related

Isolating/removing Characters from string using rails

I am using ruby on rails
I have
article.id = 509969989168Q000475601
I would like the output to be
article.id = 68Q000475601
basically want to get rid of all before it gets to 68Q
the numbers in front of the 68Q can be various length
is there a way to remove up to "68Q"
it will always be 68Q and Q is always the only Letter
is there a way to say remove all characters from 2 digits before "Q"
I'd use:
article.id[/68Q.*/]
Which will return everything from 68Q to the end of the string.
article.id.match(/68Q.+\z/)[0]
You can do this easily with the split method:
'68Q' + article.id.split('68Q')[1]
This splits the string into an array based on the delimiter you give it, then takes the second element of that array. For what it's worth though, #theTinMan's solution is far more elegant.

Ruby on Rails: How can i take/cut first 300 words or characters from a string?

I need to take/cut first 300 words or characters from a string.
That means, I need a limited number of characters from a string, from the beginning.
Something like truncating.
Is there a function to do this?
str = "many words here words words words ..."
first_500_words = str.split(" ").first(500).join(" ")
first_500_chars = str[0..500]
Depending on the size of your text and performance needs, one option is #text.split(/\s+/).slice(0,300).join(' ')
If you actually want to truncate on character level, which is advisable because different words differ in display length quite a bit, use:
def truncate_words(text, length = 300, end_string = ' …')
words = text.split()
words[0..(length-1)].join(' ') + (words.length > length ? end_string : '')
end
which I found here: http://snippets.dzone.com/posts/show/804
If you're using Rails, you can also use string.truncate but it does not take into account word boundries.
str = "this is really long string which I want to truncate..."
str.truncate 300, separator: " "
or if you prefer to youse brackets
str.truncate(300, separator: " ")
It's the most elegant solution of all above. As you mentioned in the topic, you use Rails so it will work. If you code in raw Ruby, you should write something like this:
str.split.first(300).join " "
The split method no need to take argument if you need to split the text by spaces.

counting line numbers of a poem with nokogiri / ruby

I've struggling to try to do this with a simple regex but it's never been very accurate. It doesn't have to be perfect.
Source has a combination of and tags. I don't want to count blank lines.
Old way:
self.words = rendered.gsub(/<p> <\/p>/,'').gsub(/<p><br\s?\/?>|(?:<br\s?\/?>){2,}/,'<br>').scan(/<br>|<br \/>|<p/).size+1
New way (not working:
Tries to turn all the + into paragraphs, then throw it into nokogiri to count paragraph tags with more than 3 chars in them (I have no idea how? Counting 1 letter lines would be nice too, but this worked ok in javascript)
h = rendered
h.gsub!(/<br>\s*<br>/gi,"<p>")
h.gsub!(/<br>/gi,"<p>") if h =~ /<br>\s*<br>/
h.prepend "<p>" if !h =~ /^\s*<p[^>]*>/i
h.replace(/<p>\s*<p>/g,"<p> </p><p>")
Nokogiri::HTML(rendered)
# find+count p tags with at least 1-3 chars?
# this is javascript not ruby, but you get the idea
$('p', c).each(function(i) { // had to trim it to remove whitespaces from start/end.
if ($(this).children('img').length) return; // skip if it's just an image.
if ($.trim($(this).text()).length > 3)
$(this).append("<div class='num'>"+ (n += 1) +"</div>");
})
Other methods are welcome!
Example poem ( http://allpoetry.com/poem/7429983-the_many_endings-by-Kevin )
<p>
from the other side of silence<br>
you met me with change and a pocket<br>
of unhappy apples.</p>
<p>
</p>
<p>
<br>
we bled together to black<br>
and chose the path carefully to<br>
france.<br><br>
sometimes when you smile<br>
your radiant footsteps fall<br>
and all around us is silence:<br>
each dream step is<br>
false but full of such glory</p>
<p>
</p>
<p>
<br>
unhappiness never made a student of you:<br>
just two by two by two. now three<br>
this great we that overflows our<br>
heart-cave<br><br>
each jewel-like addition to the delicate<br>
crown. but flowers fall and dreams,<br>
all dreams, come to and end with death.</p>
Thank you!
For posterity, here's what I'm using now and it seems to be quite accurate. Non latin chars cause some problems sometimes from ckeditor, so I'm stripping them out for now.
html = Nokogiri::HTML(rendered)
text = html.at('body').inner_text rescue nil
return self.words = rendered.gsub(/<p> <\/p>/,'').gsub(/<p><br\s?\/?>|(?:<br\s?\/?>){2,}/,'<br>').scan(/<br>|<br \/>|<p/).size+1 if !text
#bonus points to strip lines entirely non-letter. idk
#d "text is", text.gsub!(/([\x09|\x0D|\t])|(\xc2\xa0){1,}|[^A-z]/u,'')
text.gsub!(/[^A-z\n]/u,'')
#d "text is", text
self.words = text.strip.scan(/(\s*\n\s*)+/).size+1

Interpret newlines as <br>s in markdown (Github Markdown-style) in Ruby

I'm using markdown for comments on my site and I want users to be able to create line breaks by pressing enter instead of space space enter (see this meta question for more details on this idea)
How can I do this in Ruby? You'd think Github Flavored Markdown would be exactly what I need, but (surprisingly), it's quite buggy.
Here's their implementation:
# in very clear cases, let newlines become <br /> tags
text.gsub!(/^[\w\<][^\n]*\n+/) do |x|
x =~ /\n{2}/ ? x : (x.strip!; x << " \n")
end
This logic requires that the line start with a \w for a linebreak at the end to create a <br>. The reason for this requirement is that you don't to mess with lists: (But see the edit below; I'm not even sure this makes sense)
* we don't want a <br>
* between these two list items
However, the logic breaks in these cases:
[some](http://google.com)
[links](http://google.com)
*this line is in italics*
another line
> the start of a blockquote!
another line
I.e., in all of these cases there should be a <br> at the end of the first line, and yet GFM doesn't add one
Oddly, this works correctly in the javascript version of GFM.
Does anyone have a working implementation of "new lines to <br>s" in Ruby?
Edit: It gets even more confusing!
If you check out Github's official Github Flavored Markdown repository, you'll find yet another newline to <br> regex!:
# in very clear cases, let newlines become <br /> tags
text.gsub!(/(\A|^$\n)(^\w[^\n]*\n)(^\w[^\n]*$)+/m) do |x|
x.gsub(/^(.+)$/, "\\1 ")
end
I have no clue what this regex means, but it doesn't do any better on the above test cases.
Also, it doesn't look like the "don't mess with lists" justification for requiring that lines start with word characters is valid to begin with. I.e., standard markdown list semantics don't change regardless of whether you add 2 trailing spaces. Here:
item 1
item 2
item 3
In the source of this question there are 2 trailing spaces after "item 1", and yet if you look at the HTML, there is no superfluous <br>
This leads me to think the best regex for converting newlines to <br>s is just:
text.gsub!(/^[^\n]+\n+/) do |x|
x =~ /\n{2}/ ? x : (x.strip!; x << " \n")
end
Thoughts?
I'm not sure if this will help, but I just use simple_format()
from ActionView::Helpers::TextHelper
ActionView simple_format
my_text = "Here is some basic text...\n...with a line break."
simple_format(my_text)
output => "<p>Here is some basic text...\n<br />...with a line break.</p>"
Even if it doesn't meet your specs, looking at the simple_format() source code .gsub! methods might help you out writing your own version of required markdown.
A little too late, but perhaps useful for other people. I've gotten it to work (but not thoroughly tested) by preprocessing the text using regular expressions, like so. It's hideous as a result of the lack of zero-width lookbehinds, but oh well.
# Append two spaces to a simple line, if it ends in newline, to render the
# markdown properly. Note: do not do this for lists, instead insert two newlines. Also, leave double newlines
# alone.
text.gsub! /^ ([\*\+\-]\s+|\d+\s+)? (.+?) (\ \ )? \r?\n (\r?\n|[\*\+\-]\s+|\d+\s+)? /xi do
full, pre, line, spaces, post = $~.to_a
if post != "\n" && pre.blank? && post.blank? && spaces.blank?
"#{pre}#{line} \n#{post}"
elsif pre.present? || post.present?
"#{pre}#{line}\n\n#{post}"
else
full
end
end

Want to show the first 50 or 60 words of a text field in ruby?

I have a stories text field and want to show the first few lines – say the first 50 words of that field – in a snapshot page. How can I do that in Ruby (on Rails)?
Assuming your words are delimited by a space, you can do something like this.
stories.split(' ').slice(0,50).join(' ')
Mostly the same as Aaron Hinni's answer, but will try and keep 3 full sentences (then truncate to 50 words, if it's the sentences were too long)
def truncate(text, max_sentences = 3, max_words = 50)
# Take first 3 setences (blah. blah. blah)
three_sentences = text.split('. ').slice(0, max_sentences).join('. ')
# Take first 50 words of the above
shortened = three_sentences.split(' ').slice(0, max_words).join(' ')
return shortened # bah, explicit return is evil
end
Also, if this text has any HTML, my answer on "Truncate Markdown?" might be of use
In use something very similar in a Rails application to extend ("monkey patch") the base String class.
I created lib/core_extensions.rb which contains:
class String
def to_blurb(word_count = 30)
self.split(" ").slice(0, word_count).join(" ")
end
end
I then created config/initializers/load_extensions.rb which contains:
require 'core_extensions'
Now I have the to_blurb() method on all my String objects in the Rails application.

Resources