How to add line break in rdoc - ruby

I have a code and comments for RDoc like this:
# first line comment
# second line comment
def foo
end
When I output document by rdoc foo.rb, then line break are ignored in HTML file.
To add line break I can write like:
# first line comment<br>
# second line comment
or
# first line comment
#
# second line comment
but I feel both way are not simple enough.
Is there other simple way to add line break in RDoc?

Just add two or more spaces to the end of the line and it will work.
#first comment
#second comment
def foo
end
The first line has 2 spaces after comment.

Add answer regarding add line break in common text:
Make heading with full white space
 "===  " # <= the quoted part
At least this works on github.

Related

how to overwrite part of a line in a txt file with regex and .sub in ruby

I have the following layout in a txt file.
[item] label1: comment1 | label2: foo
I have the code below. The goal is to modify part of an existing line in text
def replace_info(item, bar)
return "please create a file first" unless File.exist?('site_info.txt')
IO.foreach('site_info.txt','a+') do |line|
if line.include?(item)
#regex should find the data from the whitespace after the colon all the way to the end.
#this should be equivalent to foo
foo_string = line.scan(/[^"label2: "]*\z/)
line.sub(foo_string, bar)
end
end
end
Please advise. Perhaps my regrex is off, but .sub is correct, but I cannot overwrite line.
Tiny problem: Your regular expression does not do what you think. /[^"label2: "]*\z/ means: any number of characters at the end of line that are not a, b, e, l, ", space, colon or 2 (see Character classes). And scan returns an array, which sub doesn't work with. But that doesn't really matter, because...
Small problem: line.sub(foo_string, bar) doesn't do anything. It returns a changed string, but you don't assign it to anything and it gets thrown away. line.sub!(foo_string, bar) would change line itself, but that leads us to...
Big problem: You cannot just change the read line and expect it to change in the file itself. It's like reading a book, thinking you could write a line better, and expecting it to change the book. The way to change a line in a text file is to read from one file and copy what you read to another. If you change a line between reading and writing, the newly written copy will be different. At the end, you can rename the new file to the old file (which will delete the old file and replace it atomically with the new one).
EDIT: Here's some code. First, I dislike IO.foreach as I like to control the iteration myself (and IMO, IO.foreach is not readable as IO#each_line). In the regular expression, I used lookbehind to find the label without including it into the match, so I can replace just the value; I changed to \Z for a similar reason, to exclude the newline from the match. You should not be returning error messages from functions, that's what exceptions are for. I changed simple include? to #start_with? because your item might be found elsewhere in the line when we wouldn't want to trigger the change.
class FileNotFoundException < RuntimeError; end
def replace_info(item, bar)
# check if file exists
raise FileNotFoundException unless File.exist?('site_info.txt')
# rewrite the file
File.open('site_info.txt.bak', 'wt') do |w|
File.open('site_info.txt', 'rt') do |r|
r.each_line do |line|
if line.start_with?("[#{item}]")
line.sub!(/(?<=label2: ).*?\Z/, bar)
end
w.write(line)
end
end
end
# replace the old file
File.rename('site_info.txt.bak', 'site_info.txt')
end
replace_info("item", "bar")

Ruby remove blank lines from a file which include spaces

I am trying to remove blank lines from a file.
My current code is:
def remove_blank_lines_from_file(file)
File.write(file, File.read(file).gsub(/^$\n/, ''))
end
The above code removes only the empty lines, but I also want to remove the lines which include spaces.
How could I do it?
Since you nevertheless load the whole file into memory, this might be easier to read:
File.write(file, File.readlines(file).reject { |s| s.strip.empty? }.join)
Just remove those lines, containing the spaces only.

How to determine line ending types in Ruby

I am using CSVLint to run some validation on flat files. The sources for the files can have varied line endings, some are \n, some \r\n. The Validator constructor takes a dialect parameter where I need to specify the line ending type.
Is there a good/quick/easy way to sample the first line of the flat file to determine the line ending type in Ruby?
Update
The answer below is the correct answer to my question. If you need auto line endings in CSVLint, however, try this in the dialect:
"lineTerminator" => :auto
Also, #sawa's answer below pertains to my original question (and typo) of looking for \r and \r\n.
To detect \n and \r\n line endings, simply match the first line against the regular expression /\r?\n$/:
def determine_line_ending(filename)
File.open(filename, 'r') do |file|
return file.readline[/\r?\n$/]
end
end
determine_line_ending('./windows_file.csv')
# => "\r\n"
determine_line_ending('./unix_file.csv')
# => "\n"
This doesn't handle weird edge cases like the Mac OS 9 (discontinued in 2001) \r line ending, but covers everything else. If you want some background on historical line endings, the Wikipedia article is pretty interesting.
Edit The following is an answer to the original question, not the question after it has changed.
When you have the first line line,
line[/[\r\n]+/]
will give you what line ending you have.

Exact specification for block comment

What is the exact specification for block comments? It seems to be true that the first and the last lines have to start exactly with =begin and =end. But besides that, there is a little unclarity. Some descriptions say =begin and =end must be the only thing on the respective lines, but that does not seem to be true. Running Ruby 1.9.3 MRI, I get the following results.
Adding white space characters still seems to work:
=begin \t\t \t
This is not a Ruby command and should raise an exception if read.
=end \t\t\t \t\t\t\t
# => no problem
Furturemore, it seems that I can add an arbitrary string (not including "\n") after one or more space characters, and it is still okay:
=begin \t\t \tblah blah blah
This is not a Ruby command and should raise an exception if read.
=end \t\t\t \t\t\t\tThis is some scribble
# => no problem
I can put a line starting with =begin in the middle of a block comment:
=begin
This is not a Ruby command and should raise an exception if read.
=begin
So as this one.
=end
# => no problem
But not a line that qualifies as the last line of the comment:
=begin
This is not a Ruby command and should raise an exception if read.
=end blah blah
So as this one.
=end
# => error
Is this specification, or an implementation-dependent behavior? For clarity, can someone describe in terms of regex the exact specification of a Ruby block comment syntax?
The Ruby Programming Lanuage, page 26:
"Ruby supports another style of multiline comment known as an embedded document.(...)
Any text that appears after =begin or =end is part of the comment and is also ignored, but that extra text must be separated from the =begin and =end by at least one space.(...)
Embedded documents are usually intended by some postprocessing tool that is run over the Ruby source code, and it's typical to follow =begin with an identifier that indicates which tool the comment is intended for."
Another way of use:
=begin Please fix this!
non working code #this is a comment line
=end non working code
#=begin Please fix this!
non working code #now this line gets run
#=end non working code

ruby each_line reads line break too?

I'm trying to read data from a text file and join it with a post string. When there's only one line in the file, it works fine. But with 2 lines, my request is failed. Is each_line reading the line break? How can I correct it?
File.open('sfzh.txt','r'){|f|
f.each_line{|row|
send(row)
}
I did bypass this issue with split and extra delimiter. But it just looks ugly.
Yes, each_line includes line breaks. But you can strip them easily using chomp:
File.foreach('test1.rb') do |line|
send line.chomp
end
Another way is to map strip onto each line as it is returned. To read a file line-by-line, stripping whitespace and do something with each line you can do the following:
File.open("path to file").readlines.map(&:strip).each do |line|
(do something with line)
end

Resources