Gtk4-tutorial/lib/lib_sec_file.rb
2021-01-11 23:32:09 +09:00

158 lines
3.6 KiB
Ruby
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

class Sec_file < String
def initialize path
if path.instance_of?(String) && File.exist?(path)
@name = File.basename path
@dirname = File.dirname path
unless @name =~ /^sec\d+(\.\d+)?\.(src\.md|md|html|tex)$/
raise "Sec_file class initialization error: #{path} is not Sec_file object name."
end
super(path)
else
raise "Sec_file class initialization error: file #{path} is not exist."
end
end
def type
@name.match(/\.(src\.md|md|html|tex)$/)[1]
end
def path
self
end
def name
@name
end
def dirname
@dirname
end
def c_files
if self.type != "src.md"
return []
else
buf = IO.readlines(self)
files = []
buf.each do |line|
if line =~ /^@@@ (\S+)/
files << @dirname+"/"+$1
end
end
files
end
end
def to_srcmd
@name.gsub(/\.(src\.md|md|html|tex)$/, ".src.md")
end
def to_md
@name.gsub(/\.(src\.md|md|html|tex)$/, ".md")
end
def to_html
@name.gsub(/\.(src\.md|md|html|tex)$/, ".html")
end
def to_tex
@name.gsub(/\.(src\.md|md|html|tex)$/, ".tex")
end
def num # the return value is String
@name.match(/\d+(\.\d+)?/)[0]
end
def to_f
self.num.to_f
end
def <=> other
if other.instance_of?(Sec_file)
self.to_f <=> other.to_f
else
nil
end
end
# Note: is_i? indicates the number is integer mathematically. For example, 2.0 is an integer.
# It doesn't mean the class of the number is Integer.
def is_i?
self.to_f == self.to_f.floor
end
def renum n
if n.instance_of?(String)
n = n.to_i if n =~ /^\d+$/
n = n.to_f if n =~ /^\d+\.\d+/
end
if n.instance_of?(Integer) || n.instance_of?(Float)
n = n.to_i if n == n.floor
old = self
new = self.gsub(/\d+(\.\d+)?(\.(src\.md|md|html|tex)$)/, "#{n}\\2")
if old != new
File.rename old, new
self.replace new
@name = File.basename self
@dirname = File.dirname self
end
end
end
end
class Sec_files < Array
def initialize sec_files
if sec_files.instance_of? Array
sec_files.each do |sec_file|
unless sec_file.instance_of? Sec_file
raise "#{sec_file} is not an instance of Sec_file."
end
end
super(sec_files)
else
raise "#{sec_files} is not an array."
end
end
def renum
self.sort!
tbl = []
n = 1
self.each do |sec_file|
tbl << [ sec_file.num, n, sec_file.to_f == n ? true : false ]
n += 1
end
while any_diff?(tbl)
unless try_renum(tbl)
break
end
end
if any_diff?(tbl)
raise "Renumbering failed."
end
end
private
def any_diff? tbl
diff = false
tbl.each do |t|
diff = true if t[2] == false
end
diff
end
def try_renum tbl
changed = false
(self.size - 1).downto 0 do |i|
if tbl[i][2] == false
n = tbl[i][1] # number to substitute
found = false
self.each do |sec_file|
if sec_file != self[i] && sec_file.to_f == n
found = true
break
end
end
unless found # OK to replace
self[i].renum n
tbl[i][2] = true
# tbl[0] (old number (String) is kept in the array 'tbl')
changed = true
self.each do |sec_file|
buf = IO.readlines sec_file
buf.each do |line|
line.gsub!(/((S|s)ection *)#{tbl[0]}/, "\\1#{n}")
           .gsub!(/((S|s)ec *)#{tbl[0]}/, "\\1#{n}")
end
IO.write sec_file buf.join
end
end
end
end
changed
end
end