在Ruby脚本中使用SLIM / HAML等?
我目前正在编写一个脚本,分析一些遗传数据,然后在彩色Word文档上生成输出。 但是,脚本工作正常,脚本中的一个方法编写得很糟糕,即创建Word文档的方法。
创建文档的方法创建一个独立的HTML文件,然后使用’docx’扩展名保存,这允许我为文档的不同部分提供不同的样式。
以下是实现此function的最低要求。 它包括一些示例输入数据,这些数据将在最后一步之前以不同的方法创建并存储在散列中,以及必要的方法。
require 'bio' def make_hash(input_file) input_read = Hash.new biofastafile = Bio::FlatFile.open(Bio::FastaFormat, input_file) biofastafile.each_entry do |entry| input_read[entry.definition] = entry.aaseq end return input_read end def to_doc(hash, output, motif) output_file = File.new(output, "w") output_file.puts " .id{font-weight: bold;} .signalp{color:#000099; font-weight: bold;} .motif{color:#FF3300; font-weight: bold;} h3 {word-wrap: break-word;} p {word-wrap: break-word; font-family:Courier New, Courier, Mono;}" hash.each do |id, seq| sequence = seq.to_s.gsub("\[\"", "").gsub("\"\]", "") id.scan(/(\w+)(.*)/) do |id_start, id_end| output_file.puts " >#{id_start}#{id_end}
" output_file.puts "" sequence.scan(/(\w+)-(\w+)/) do |signalp, seq_end| output_file.puts signalp + "" + seq_end.gsub(/#{motif}/, '\0') output_file.puts "
" end end end output_file.puts "" output_file.close end hash = make_hash("./sample.txt") to_doc = to_doc(hash, "output.docx", "WL|KK|RR|KR|R..R|R....R"
这是一些示例数据。 实际上,在分析物种的遗传数据时,这可以由许多100,000个序列组成:
>isotig00001_f4_14 - Signal P Cleavage Site => 11:12 MMHLLCIVLLL-KWWLLL >isotig00001_f4_15 - Signal P Cleavage Site => 10:11 MHLLCIVLLL-KWWLLL >isotig00003_f6_8 - Signal P Cleavage Site => 11:12 MMHLLCIVLLL-KWWLLL >isotig00003_f6_9 - Signal P Cleavage Site => 10:11 MHLLCIVLLL-KWWLLL >isotig00004_f6_8 - Signal P Cleavage Site => 11:12 MMHLLCIVLLL-KWWLLL >isotig00004_f6_9 - Signal P Cleavage Site => 10:11 MHLLCIVLLL-KWWLLL >isotig00009_f2_3 - Signal P Cleavage Site => 22:23 MLKCFSIIMGLILLLEIGGGCA-IYFYRAQIQAQFQKSLTDVTITDYRENADFQDLIDALQSGLSCCGVNSYEDWDNNIYFNCSGPANNPEALWCAFLLLYTGSSKRSSQHPVRLWSSFPRTTKYFPHKDLHHWLCGYVYNVD >isotig00009_f3_9 - Signal P Cleavage Site => 16:17 MKTGIIIFISTVVVLP-ITLKPCGVPFSCCIPDQASGVANTQCGYGVRSPEQQNTFHTKIYTTGCADMFTMWINRYLYYIAGIAGVIVLVELFGFCFAHSLINDIKRQKARWAHR >isotig00009_f6_13 - Signal P Cleavage Site => 11:12 MMHLLCIVLLL-KWWLLL >isotig00009_f6_14 - Signal P Cleavage Site => 10:11 MHLLCIVLLL-KWWLLL
每次读取由两部分组成:seq id(以>
开头的行)和序列。 这是分开的,并存储在make_hash
方法的散列中。 这个例子:
>isotig00001_f4_14 - Signal P Cleavage Site => 11:12 MMHLLCIVLLL-KWWLLL
由。。。制成由。。。做成:
>isotig00001_f4_14 (the first part of the id - class="id") Signal P Cleavage Site => 11:12 (the second part of the id - normal writing) (new line) MMHLLCIVLLL (first part of the sequence - class="signalp") KW WL LL (the second part of the sequence - the motif KW will be class="motif")
在HTML中它会产生:
>isotig00001_f4_14Signal P Cleavage Site => 11:12
MMHLLCIVLLKWKWLL
基本上,我想使用适当的HTML模板脚本(如SLIM / HAML / NOKOGIRI / ERB)重写to_doc
方法。 我试图完成这件事。
由于某种原因,循环中的循环不起作用,并且创建存储这些变量的全局变量也不起作用。
上面的脚本工作,只是将示例数据保存为“sample.txt”,然后运行脚本。
我将非常感谢任何帮助。
这是一个起点:
require 'haml' haml_doc = <
运行时输出的是:
从那里,您可以使用以下命令轻松写入文件:
File.write(output, engine.render)
而不是使用puts
其输出到控制台。
要使用它,您需要使用额外的Haml haml_doc
以循环输入数据并将其按到一个数组或散列中,您可以干净地迭代,而无需嵌入各种scan
和条件逻辑。 视图应主要用于输出内容,而不是操纵数据。
在engine = Haml...
上方engine = Haml...
行,您需要读取输入数据并按下它,并将其存储在Haml可以迭代的实例变量中。 您在原始代码中有基本的想法,但不是尝试输出HTML,而是创建一个可以传递给Haml的对象或子哈希。
通常这将被分离为模型,视图和控制器的单独文件,如Rails或大型Sinatra应用程序,但这确实不是一个大应用程序,因此您可以将它全部放在一个文件中。 保持你的逻辑清洁,它会没事的。
没有样本输入数据和预期输出就很难做得更多,但这会给你一个起点。
根据数据样本,这里有一些东西可以进入你的球场。 我不会打磨它,因为毕竟你必须做一些,但这是一个合理的开始。 第一部分是模拟一些合理的东西,比如您在代码中引用的Bio,但我从未见过。 您不需要此部分,但可能需要查看它:
module Bio FastaFormat = 1 SAMPLE_DATA = <<-EOT >isotig00001_f4_14 - Signal P Cleavage Site => 11:12 MMHLLCIVLLL-KWWLLL >isotig00001_f4_15 - Signal P Cleavage Site => 10:11 MHLLCIVLLL-KWWLLL >isotig00003_f6_8 - Signal P Cleavage Site => 11:12 MMHLLCIVLLL-KWWLLL >isotig00003_f6_9 - Signal P Cleavage Site => 10:11 MHLLCIVLLL-KWWLLL >isotig00004_f6_8 - Signal P Cleavage Site => 11:12 MMHLLCIVLLL-KWWLLL >isotig00004_f6_9 - Signal P Cleavage Site => 10:11 MHLLCIVLLL-KWWLLL >isotig00009_f2_3 - Signal P Cleavage Site => 22:23 MLKCFSIIMGLILLLEIGGGCA-IYFYRAQIQAQFQKSLTDVTITDYRENADFQDLIDALQSGLSCCGVNSYEDWDNNIYFNCSGPANNPEALWCAFLLLYTGSSKRSSQHPVRLWSSFPRTTKYFPHKDLHHWLCGYVYNVD >isotig00009_f3_9 - Signal P Cleavage Site => 16:17 MKTGIIIFISTVVVLP-ITLKPCGVPFSCCIPDQASGVANTQCGYGVRSPEQQNTFHTKIYTTGCADMFTMWINRYLYYIAGIAGVIVLVELFGFCFAHSLINDIKRQKARWAHR >isotig00009_f6_13 - Signal P Cleavage Site => 11:12 MMHLLCIVLLL-KWWLLL >isotig00009_f6_14 - Signal P Cleavage Site => 10:11 MHLLCIVLLL-KWWLLL EOT class FlatFile class Entry attr_reader :definition, :aaseq def initialize(definition, aaseq) @definition = definition @aaseq = aaseq end end def initialize end def self.open(filetype, filename) SAMPLE_DATA.split("\n").each_slice(2).map{ |seq_id, sequence| Entry.new(seq_id, sequence) } end def each_entry @sample_data.each do |_entry| yield _entry end end end end
这是有趣的开始。 我修改了你的get_hash
例程来解析字符串我是怎么做的。 它不是哈希,而是返回哈希数组。 每个子哈希都可以使用了,换句话说,数据被解析并准备输出:
include Bio def make_array_of_hashes(input_file) Bio::FlatFile.open( Bio::FastaFormat, input_file ).map { |entry| id_start, id_end = entry.definition.split('-').map(&:strip) signalp, seq_end = entry.aaseq.split('-') motif = seq_end.scan(/(?:WL|KK|RR|KR|R..R|R....R)/) { :id_start => id_start, :id_end => id_end, :signalp => signalp, :motif => motif } } end
这是在脚本正文中定义HAML文档的简单方法。 我只输出,除了循环外,模板中没有逻辑。 在处理视图之前处理了所有其他内容:
haml_doc = <
以下是如何使用它:
require 'haml' data = make_array_of_hashes('sample.txt') engine = Haml::Engine.new(haml_doc) puts engine.render(Object.new, :data => data)
哪,运行时输出:
>isotig00001_f4_14 Signal P Cleavage Site => 11:12
MMHLLCIVLLL WL
>isotig00001_f4_15 Signal P Cleavage Site => 10:11
MHLLCIVLLL WL
>isotig00003_f6_8 Signal P Cleavage Site => 11:12
MMHLLCIVLLL WL
>isotig00003_f6_9 Signal P Cleavage Site => 10:11
MHLLCIVLLL WL
>isotig00004_f6_8 Signal P Cleavage Site => 11:12
MMHLLCIVLLL WL
>isotig00004_f6_9 Signal P Cleavage Site => 10:11
MHLLCIVLLL WL
>isotig00009_f2_3 Signal P Cleavage Site => 22:23
MLKCFSIIMGLILLLEIGGGCA KR WL
>isotig00009_f3_9 Signal P Cleavage Site => 16:17
MKTGIIIFISTVVVLP KR
>isotig00009_f6_13 Signal P Cleavage Site => 11:12
MMHLLCIVLLL WL
>isotig00009_f6_14 Signal P Cleavage Site => 10:11
MHLLCIVLLL WL