之前写过一篇windows下的,现在重新总结一下,主要是可以支持ubuntu了。其实从功能上是比上一篇少了一个win32 api隐藏控制台。
采用的编程语言为ruby,窗体程序为 ruby 的 tk。
最后实现的效果为 用notepad++或其他软件编辑,可以自动编译,实时查看(实时查看需要 sumatrapd (in windows) 或者 okular (in ubuntu))。
@20-2-25 修改,增加检测数据文件,支持定义临时文件目录。
安装ruby 和 tk
ruby 2.4以后应该直接可以gem install tk,非常方便。虽然ubuntu默认的ruby 版本比较低,但是可以通过如下方式提高ruby的版本:
sudo apt-get install software-properties-common
sudo apt-add-repository ppa:brightbox/ruby-ng
sudo apt-get update
sudo apt-get install ruby2.6 ruby2.6-dev
sudo apt-get install ruby-switch
sudo ruby-switch --set ruby2.6
gem install tk
windows上的话直接官网下载,安装的时候注意选择tk,没有的话就gem装。
安装latex
主要我们需要有以下几个文件
pdflatex[.exe]
bibtex[.exe] 如果不需要bib这个自然不会用到,但是安装latex之后都会有这个。
代码
就一个文件,然后包括一个配置文件 config.yaml
程序文件
# -*- coding:utf-8 -*-
FILEPATH=File.expand_path("..",__FILE__);
$LOAD_PATH.unshift FILEPATH if !$LOAD_PATH.include? FILEPATH
Dir::chdir( FILEPATH )
# 长虹剑 2015-11-16 bibtex是后续修改的
=begin
@main_file 这个我先固定了
编译时间,及是否编译可以控制
使用了TK,又让我对窗体编程有所了解,而且对ruby的对象机制有所了解。
root=TkRoot.new 生成一个类
class<<root
写你自己要加入的东西
end
定义各种部件的时候要传入root,一些控制的东西都通过root,所以root这个single类要定义好
Tk.mainloop运行
----------------------------- TK 布局等说明
http://www.tutorialspoint.com/ruby/ruby_tk_button.htm button
=end
require 'yaml'
require 'tk'
require 'Win32API'
root=TkRoot.new{title 'latex即时编译工具-made by CHJ'}
# my_object.instance_eval {}
class <<root #只有在root类中的才可以 ******
attr_accessor :compiler,:thread #不属于自己的不能直接用@
def run_base
@compiler=Latex_runtime_complie.new
@compiler.load_config
@compiler.sleep_time=3
@compiler.listen_control=:run
#隐藏掉控制台 这个API改了
@console_hand=Win32API.new('kernel32', 'GetConsoleWindow', 'i', 'l').call(0)
@show_console=false
trigger_console
end #run
def trigger_console
if @show_console==true
Win32API.new('user32', 'ShowWindow', 'li', 'i').call(@console_hand, 0)
@show_console=false
else
Win32API.new('user32', 'ShowWindow', 'li', 'i').call(@console_hand, 1)
@show_console=true
end
end
class Latex_runtime_complie
attr_accessor :listen_control
attr_accessor :sleep_time
def initialize
@is_bibtex="T"
@config_file=FILEPATH+"/config.yaml"
@latex_file_path=""
@latex_file="LaTeX1"
#多线程控制
@sleep_time=5
@listen_control=:run
# run 正常 pause 暂停 stop 退出
@last_file_mtime=[]
end
def load_config
#p `pwd`
#puts Dir.pwd
data = YAML.load_file(@config_file)
@pdflatex_exe=data['config']['pdflatex_exe']
@bibtex_exe=data['config']['bibtex_exe']
@is_bibtex=data['config']['is_bibtex']
@latex_file_path=data['config']['latex_file_path']
@latex_file=data['config']['latex_file']
edit_files=data['config']['edit_file']
@main_file=@latex_file_path+"/"+@latex_file+".tex"
@edit_file=[ @config_file ]
for e in edit_files
@edit_file.push @latex_file_path+"/"+e #+".tex"
end
@output_directory=data['config']['output_directory']
p @main_file, @edit_file
@argument=%Q[-synctex=-1 -interaction=nonstopmode "#{@main_file}" ]
#puts @argument
@latex_cmd="#{@pdflatex_exe} -output-directory=#{@output_directory} #{@latex_file}"
@bib_cmd="#{@bibtex_exe} #{@output_directory}/#{@latex_file}"
# ***** 这里修改运行目录
@argument = "-output-directory=#{@output_directory} #{@argument}"
Dir.chdir(@latex_file_path)
puts Dir.pwd
end
def compile
#puts @pdflatex_exe+""+@argument
if @is_bibtex=="T"
puts system(@latex_cmd)
puts system(@bib_cmd);
puts system(@latex_cmd);
end
puts system(@pdflatex_exe+" "+@argument);
#system(@pdflatex_exe+" "+@argument);
end
def get_mtime
res=[]
for e in @edit_file
res.push File.mtime(e)
end
return res
end
def is_different(a, b)
a.zip(b).each_with_index do |e, id|
return id+1 if e[0] != e[1]
end
return 0
end
## 核心,通过文件修改时间决定是否重新编译
def listening
compile
bgs=get_mtime
while true
case @listen_control
when :run
eds = get_mtime
rcode = is_different( bgs, eds )
if rcode!=0
load_config if rcode==1
bgs=eds
compile
end
when :pause
when :stop
@last_file_mtime=bgs
return
end
sleep(@sleep_time)
end
end
end #class Latex_runtime_complie
end #添加的类属性
#相当于设置了主窗体
TkLabel.new {
width 15
height 3
#pack
grid('row'=>0, 'column'=>0)
}
BTrun=TkButton.new(root){
text " 运行 "
width 8
#height 1
#pack :padx=>2,:pady=>2,:side=>'bottom'
grid('row'=>0, 'column'=>3,'padx'=>5,'pady'=>5)
command{
root.compiler.listen_control=:run
if root.thread && root.thread.alive?
root.thread.exit
end
root.thread = Thread.new {root.compiler.listening}
BTstop.state="normal"
BTrun.state="disabled"
}
}
BTstop=TkButton.new(root){
text " 停止 "
width 8
state "disabled"
#pack :padx=>3,:pady=>2,:side=>'bottom'
grid('row'=>1, 'column'=>3,'padx'=>5,'pady'=>5)
command{
root.compiler.listen_control=:stop if root.thread
BTrun.state="normal"
BTstop.state="disabled"
}
}
TkButton.new(root){
text "exit"
#pack :padx=>2,:pady=>2,:side=>'bottom'
grid('row'=>0, 'column'=>0,'padx'=>5,'pady'=>5) #,'columnspan'=>2
command{
if root.thread
root.thread.exit if root.thread.alive?
end
exit
}
}
var=TkVariable.new
TkEntry.new(root){
text var #这个变量就会不断被监控
width 5
grid('row'=>1, 'column'=>1)
}
TkButton.new(root){
text "set"
#pack :padx=>2,:pady=>2,:side=>'bottom'
grid('row'=>1, 'column'=>0,'padx'=>5,'pady'=>5)
command{
if var=~/\d+/
var=var.to_i
if var>=1
root.compiler.sleep_time=var
#puts var
end
end
}
}
TkButton.new(root){
text "控制台"
#pack :padx=>2,:pady=>2,:side=>'bottom'
grid('row'=>0, 'column'=>1,'padx'=>5,'pady'=>5)
command{
root.trigger_console
}
}
root.run_base
Tk.mainloop
配置文件为
config:
is_bibtex: T
pdflatex_exe: /usr/bin/pdflatex
bibtex_exe: /usr/bin/bibtex
latex_file_path: /data/tools/tex_file_dir/
latex_file: main_tex_file_name
edit_file: [Tex/chap-02.tex]
output_directory: Tmp
edit_file 这个是程序监听修改的,只要这个改动就会重新编译。(已经改成了数组,可多个问价 [a, b])
latex_file 这是你主 tex 文件。
上面那两个可以不用写.tex后缀
is_bibtex 是否用bibtex [T/F]
output_directory 临时目录,供latex产生
软件介绍
注意控制台还是有必要的,如果语法出现什么问题可能导致编译卡主,这样修改之后需要你手动敲回车。(在ubuntu中由于程序一般就是在控制台中运行的,因此一定会有)
其中set 可以设置每多少秒检查一次文件是否被改动。