Vim Tips Wiki
No edit summary
m (Reverted edits by 2003:E2:BBF0:501:40C5:191B:7072:DCCE (talk) to last version by Hwolfe)
 
(9 intermediate revisions by 8 users not shown)
Line 1: Line 1:
  +
{{review}}
<html>
 
  +
{{TipImported
<head><link href="re/css.css" rel="stylesheet" type="text/css" /></head>
 
  +
|id=18
<title>Online Test</title>
 
  +
|previous=17
<script language="javascript">
 
  +
|next=19
<!--
 
  +
|created=2001
  +
|complexity=advanced
  +
|author=scrott
  +
|version=6.0
  +
|rating=50/29
  +
|category1=HTML
  +
|category2=
  +
}}
  +
If you are working with HTML, you can use Vim to clean up the formating of the HTML code. This tips show how to do it.
   
  +
==Using tidy for cleaning up your code==
var t1
 
  +
You need to install [http://tidy.sourceforge.net/ html tidy] on your system first. Tidy is a tool to fix invalid HTML content and improve the layout of the resulting markup. There is also [http://sourceforge.net/projects/jtidy/ Jtidy], a Java implementation of Tidy available. This can also be used for cleaning up your HTML.
var score_threshold //及格线
 
var t2
 
var t
 
var c=120 //时间限制单位为s
 
var times=1 //超过时间允许重做的次数
 
var final_score=0 //最后分数
 
var score=0
 
var input1="<input type='radio' name='q1' value='1'>"
 
var input2="<input type='radio' name='q1' value='0'>"
 
var myquestions= new Array(20) //定义数组存放试题
 
myquestions[0]=new Array("a",input1+"a1",input2+"a2",input2+"a3") //元素一次分别对应题目,正确答案,其它答案,其它答案
 
myquestions[1]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
myquestions[2]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
myquestions[3]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
myquestions[4]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
myquestions[5]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
myquestions[6]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
myquestions[7]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
myquestions[8]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
myquestions[9]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
myquestions[10]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
myquestions[11]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
myquestions[12]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
myquestions[13]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
myquestions[14]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
myquestions[15]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
myquestions[16]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
myquestions[17]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
myquestions[18]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
myquestions[19]=new Array("a",input1+"a1",input2+"a2",input2+"a3")
 
   
  +
===Using tidy for html files===
var total_question = 5 // 每页显示5道题
 
  +
When you have tidy for your platform installed and it is available from your path, you can simply set up a mapping to filter your content through it.
var msg = ""
 
  +
<pre>
  +
:vmap ,x :!tidy -q -i --show-errors 0<CR>
  +
</pre>
  +
This means, from visual mode, you can simply press <code>,x</code> and Vim will filter your content through tidy. This will call tidy in quiet mode (<code>-q</code>) and instruct it to indent the lines (<code>-i</code>). Errors won't be shown (<code>--show-errors 0</code>), since the lines should not be lost.
   
  +
Alternatively, you can also create a {{help|prefix=no|:command}} that calls tidy:
while(1) //获取随机数,从而得到随机题目while语句保证随机数不同
 
  +
<pre>
{
 
  +
:command Thtml :%!tidy -q -i --show-errors 0
 
  +
:command Txml :%!tidy -q -i --show-errors 0 -xml
 
  +
</pre>
var j1=Math.round(Math.random()*19)
 
 
var j2=Math.round(Math.random()*19)
 
 
var j3=Math.round(Math.random()*19)
 
 
var j4=Math.round(Math.random()*19)
 
 
var j5=Math.round(Math.random()*19)
 
if(j1!=j2&&j1!=j3&&j1!=j4&&j1!=j5&&j2!=j3&&j2!=j4&&j2!=j5&&j3!=j4&&j3!=j5&&j4!=j5){break;}
 
else{continue}
 
 
 
 
}
 
while(1)//使随机数不重复出现,从而使答案不同
 
{
 
var i1=Math.round(Math.random()*3+1)
 
var i2=Math.round(Math.random()*3+1)
 
var i3=Math.round(Math.random()*3+1)
 
if(i1!=i2&&i1!=i3&&i2!=i3)
 
{
 
if(i1<4&&i2<4&&i3<4) //防止答案相同
 
{
 
if(i1==1||i2==1||i3==1) //保证存在正确答案
 
{break;}
 
}
 
}
 
else
 
{continue;}
 
}
 
   
  +
===Automatic formatting of XML files===
// 正确答案
 
  +
You can also use tidy to format xml files
var solution = new Array(total_question)
 
  +
<pre>
solution[0] = myquestions[j1][1]
 
  +
:au FileType xml :%!tidy -i -xml --show-errors 0 2>/dev/null
solution[1] = myquestions[j2][1]
 
  +
</pre>
solution[2] = myquestions[j3][1]
 
solution[3] = myquestions[j4][1]
 
solution[4] = myquestions[j5][1]
 
   
  +
This sets up a FileType autocommand, that will clean up your source using tidy, whenever Vim set's the Filetype to xml.
   
  +
===Using built-in commands===
function getselectedbutton(buttongroup) //获取选中的单选框
 
  +
Using Vim's {{help|prefix=no|'equalprg'}} option, you can use the {{help|prefix=no|id==}} operator to reformat using HTMLTidy. Or, you can use the {{help|prefix=no|'makeprg'}} option to just show the suggestions from HTMLTidy in your {{help|prefix=no|quickfix}} list.
{
 
for (var x=0; x < buttongroup.length; x++)
 
if (buttongroup[x].checked) return x //返回选中的单选框
 
return 3 //未选中时返回3
 
}
 
//按下提交按钮时调用的算分函数
 
   
  +
<pre>
function final_reportscore(correct)
 
  +
:setlocal equalprg=tidy\ -quiet\ --show-errors\ 0
{
 
  +
:setlocal makeprg=tidy\ -quiet\ -e\ %
var musthave1 = "<html><head><title>Final_Result</title></head><body>"
 
  +
</pre>
var percent = "<h2>The Final Scores is: "+Math.round(correct/total_question*100)+ "</h2><hr>"
 
score=Math.round(correct/total_question*100)+score //第一次测试成绩
 
final_score=score/2 //最后成绩
 
if(times==1) //判断是否是第一次测试
 
{
 
if (score == "100") //成绩等于100时
 
{
 
msg = musthave1 +percent + "<font color='red'>All Correct</font><p>" + msg + "<input type='button' value='close' onclick=javascript:window.close()></body></html>"
 
}
 
else
 
{
 
msg = musthave1 +percent + "<font color='red'>The right answers</font><p>" + msg +"<input type='button' value='close' onclick=javascript:window.close()>"
 
 
if(final_score<score_threshold) //判断是否及格
 
{
 
msg=msg+"<h3>I am sorry,you fail in this test</h3></body></html>"
 
}
 
else
 
{
 
msg=msg+"<h3>congratulation,you pass this test</h3></body></html>"
 
}
 
 
 
}
 
}
 
else
 
{
 
var musthave1 = "<html><head><title>Final Result</title></head><body>"
 
var percent = "<h2>Final Scores: "+final_score+"</h2><hr>"
 
msg = musthave1 +percent + "<font color='red'>The correct answers</font><p>" + msg + "<input type='button' value='close' onclick=javascript:window.close()>"
 
if(final_score<score_threshold) //判断是否及格
 
{
 
msg=msg+"<h3>I am sorry,you fail in this test</h3></body></html>"
 
}
 
else
 
{
 
msg=msg+"<h3>congratulation,you pass this test</h3></body></html>"
 
}
 
 
 
 
 
}
 
document.body.innerHTML = " "; //clear screen
 
document.write(msg)
 
msg = "" //clear msg
 
}
 
   
  +
At this point you can use <code>make</code> to clean up the full file or you can use <code>=</code> to clean up sections. Vim also ships with a tidy compiler plugin, that set's the {{help|prefix=no|'makeprg'}} automatically for you and also sets the {{help|prefix=no|'errorformat'}} setting for you. To make this work, simply type: <code>:compiler tidy</code>
   
  +
===Setting up tidy using a filetype plugin===
  +
All those options, mappings and commands can be set up automatically for html/xml files automatically, if you use filetype plugins.
   
  +
To make this work, simply put your settings into a file called html.vim (use xml.vim for the xml filetype and don't forget the -xml switch for tidy) and place it into the directory ~/.vim/ftplugin/ (Unix) or $VIM/vimfiles/ftplugin (windows, where $VIM is the installtion diretory of Vim). See also {{help|prefix=no|filetype-plugin}}
   
  +
If you set up commands and mappings using filetype plugins, you should make those buffer-local (e.g. only available for buffers of that filetype. Use the {{help|prefix=no|<buffer>}} argument for mappings and the <code>-buffer</code> argument for commands ({{help|prefix=no|command-buffer}}).
function timeout(correct) //时间到时调用的算分函数
 
{
 
score=Math.round(correct/total_question*100)+score
 
final_score=score/2
 
var title = "<html><head><title>time out</title></head><body>"
 
if(times==1)
 
{
 
var warnnig = "<h2>time is up,but you can press the button to restart</h2><hr>"
 
msg=title+warnnig+"<input type='button' value='re_start' onclick=question()></body></html>"
 
times=times-1
 
}
 
else
 
{
 
var musthave1 = "<html><head><title>Final Result</title></head><body>"
 
var percent = "<h2>Final Score: "+final_score+"</h2><hr>"
 
msg = musthave1 +percent + "<font color='red'>The correct answers</font><p>" + msg + "<input type='button' value='close' onclick=javascript:window.close()>"
 
if(final_score<score_threshold)
 
{
 
msg=msg+"<h3>I am sorry,you fail in this test</h3></body></html>"
 
}
 
else
 
{
 
msg=msg+"<h3>congratulation,you pass this test!</h3></body></html>"
 
}
 
 
}
 
document.body.innerHTML = " "; //clear screen
 
document.write(msg)
 
msg = "" //clear msg
 
}
 
   
  +
==References==
  +
*{{help|id==}}
  +
*{{help|'equalprg'}}
  +
*{{help|'makeprg'}}
  +
*{{help|'errorformat'}}
   
  +
==Comments==
  +
If you are using tidy under Windows, you need to set your <code>shellpipe=2></code> or else Vim won't see the output from tidy. Apparently these Unix tools write output to stderr instead of stdout and Vim isn't configured by default to handle this situation.
  +
----
  +
vim indents html very well when I put the line
  +
filetype plugin indent on
   
  +
into my personal ~/.vimrc (or ~\_vimrc) file. I also think that html-tidy is not able to indent only parts of a HTML file. Therefore, I do not use it as equalprg.
   
  +
I use html-tidy only in order to check if my HTML document is well formed. Therefore, I create a ~/.vim/after/ftplugin/html.vim (or ~\vimfiles\after\ftplugin\html.vim or an html.vim placed in the directory that appears last when typing :set runtimepath?) and put into it (among other things) the lines:
function grade()
 
{
 
var correct = 0
 
var wrong = 0
 
for (number=0; number < total_question; number++)
 
{
 
var form = document.forms[number]
 
var i = getselectedbutton(form.q1)
 
if(i!=3)
 
{
 
if (form.q1[i].value == "1")
 
{ correct++ }
 
else
 
{
 
wrong++
 
msg += "question "+(number+1)+"."+solution[number]+"<br>"
 
}
 
}
 
else
 
{
 
wrong++
 
msg += "question "+(number+1)+"."+solution[number]+"<br>"
 
}
 
}
 
timeout(correct)
 
}
 
   
  +
setlocal makeprg=tidy\ -quiet\ -errors\ %
  +
setlocal errorformat=line\ %l\ column\ %v\ -\ %m
   
  +
I have found that the errorformat option must be adapted as shown in order to be able jump through the error list by means of :cn and :cp etc.
//时间到时调用改函数,统计答对,答错题数
 
function final_grade()
 
{
 
clearTimeout(t1)
 
clearTimeout(t2)
 
var correct = 0
 
var wrong = 0
 
for (number=0; number < total_question; number++)
 
{
 
var form = document.forms[number] //获取表单document.forms[0]第一个form
 
var i = getselectedbutton(form.q1) //第i个radio
 
if(i!=3)
 
{
 
if (form.q1[i].value == "1") //第i个radio的值为1时,即改radio对应正确答案
 
{ correct++ } //答对题数加1
 
else
 
{
 
wrong++ //答错题数加1
 
msg += "question "+(number+1)+"."+solution[number]+"<br>" //显示答案
 
}
 
}
 
else
 
{
 
wrong++
 
msg += "question "+(number+1)+"."+solution[number]+"<br>"
 
}
 
}
 
final_reportscore(correct)
 
}
 
   
  +
----
  +
Tidy can be used for just a portion of the document by using the --show-body-only flag. For instance, on using vim6 on OSX the above command could be rewritten as:
   
  +
:exe 'setlocal equalprg=tidy\ -quiet\ -i\ --show-body-only\ true\ -f\ '.&errorfile
   
  +
the -i indents, that is optional
   
  +
The rest of the tidy options can be found here:
//随机出五道试题
 
  +
http://tidy.sourceforge.net/docs/quickref.html
function question()
 
{
 
alert("you will have only 20 seconds to finish this test!")
 
t2=setTimeout("grade()",120000) //XX秒后调用函数
 
t1=setTimeout("alert('time is up!')",120000) //XX秒后弹出警告框
 
document.body.innerHTML = " ";
 
var common1= "<html><head><link rel='stylesheet' type='text/css' href='re/css.css'/><title>testing.....</title></head><body bgcolor='#999966'>"
 
var common2="<div class='question'><font color='black'><h1>questions</h1></font><p>"
 
 
var msg1 ="<form><p>(1)" +myquestions[j1][0] +"<br>"+myquestions[j1][i1]+myquestions[j1][i2]+myquestions[j1][i3]+"</p></form>"
 
var msg2 ="<form><p>(2)" +myquestions[j2][0] +"<br>"+myquestions[j2][i2]+myquestions[j2][i1]+myquestions[j2][i3]+"</p></form>"
 
var msg3 ="<form><p>(3)" +myquestions[j3][0] +"<br>"+myquestions[j3][i3]+myquestions[j3][i2]+myquestions[j3][i1]+"</p></form>"
 
var msg4 ="<form><p>(4)" +myquestions[j4][0] +"<br>"+myquestions[j4][i1]+myquestions[j4][i2]+myquestions[j4][i3]+"</p></form>"
 
var msg5 ="<form><p>(5)" +myquestions[j5][0] +"<br>"+myquestions[j5][i2]+myquestions[j5][i3]+myquestions[j5][i1]+"</p></form>"
 
var msg6="<br><br><br><br><input type='button' name='submit' value='Submit' style='height:50;width:100' onclick='final_grade()'></div>"
 
var msg7="<div class='left'><input type='text' style='width=1px;height:37px;font-size:30px' id='txt' class='time'><img class='x' src='re/clock.png' style='height:100px;width=120px'/></div>"
 
var common3="</body></html>"
 
var msg=common1+common2+msg1+msg2+msg3+msg4+msg5+msg6+msg7+common3
 
document.write(msg);
 
c=120
 
timedCount()
 
//timedCount()
 
}
 
   
  +
----
  +
Call a function for tidy - add to your vimrc
  +
<pre>
  +
command Td :call Tidy()
  +
function Tidy()
  +
let filename=expand("%:p") " escapes for bash
  +
let filename=substitute(filename, " ", "\\\\ ", "g")
  +
let filename=substitute(filename, "(", "\\\\(", "g")
  +
let filename=substitute(filename, ")", "\\\\)", "g")
  +
let filename=substitute(filename, "[", "\\\\[", "g")
  +
let filename=substitute(filename, "]", "\\\\]", "g")
  +
let filename=substitute(filename, "&", "\\\\&", "g")
  +
let filename=substitute(filename, "!", "\\\\!", "g")
  +
let filename=substitute(filename, ",", "\\\\,", "g")
  +
let filename=substitute(filename, "'", "?", "g")
  +
let filename2=substitute(filename, ".*", "&.tidy.htm", "")
  +
let filename3=substitute(filename, ".*", "&.errors.tidy.txt", "")
  +
execute "!tidy "."-f ".filename3." ".filename." > ".filename2.""
  +
endfunction
  +
</pre>
   
  +
----
  +
Here is a mapping so Vim calls Tidy when pressing F12. Advantage of this solution: you can undo changes very easily. Put this in your vimrc:
  +
<pre>
  +
map <F12> :%!tidy -q --tidy-mark 0 2>/dev/null<CR>
  +
</pre>
   
  +
----
function timedCount() //计数器
 
  +
I use this:
{
 
  +
<pre>
document.getElementById('txt').value=c
 
  +
command Txml set ft=xml | execute "%!tidy -q -i -xml"
c=c-1
 
  +
command Thtml set ft=html | execute "%!tidy -q -i -html"
if(c>0)
 
  +
</pre>
{t=setTimeout("timedCount()",1000)}
 
  +
You can undo the formatting, but the ft change won't be undone.
}
 
  +
----
 
 
 
function Start_test()
 
{
 
 
score_threshold=prompt("Please set the score threshold ","60") //设置及格线
 
question()
 
}
 
//-->
 
</script>
 
<body bgcolor="#999966">
 
<div align="center"><EMBED src="re/funnyday.mp3" autostart="true" loop="false" width="0" height="0" > </div>
 
 
<div align="center" class="image">
 
<img src="re/1.gif" align=middle>
 
</div>
 
<div align="center" class="button">
 
<input type="button" src="start.gif" name="start" value="Start" onclick="Start_test()" style='width:100; height:30' class="pt9">
 
</div>
 
<div align="center" class="words"> <marquee scrollamount=15 align=bottom><H1>Testing is a terrible thing,but,you have to face it somehow!!!!!what a fucking thing!!!</H1></marquee><h3>Press the following button to start testing</h3>
 
</div>
 
</body>
 
</html>
 

Latest revision as of 06:30, 26 February 2018

Tip 18 Printable Monobook Previous Next

created 2001 · complexity advanced · author scrott · version 6.0


If you are working with HTML, you can use Vim to clean up the formating of the HTML code. This tips show how to do it.

Using tidy for cleaning up your code[]

You need to install html tidy on your system first. Tidy is a tool to fix invalid HTML content and improve the layout of the resulting markup. There is also Jtidy, a Java implementation of Tidy available. This can also be used for cleaning up your HTML.

Using tidy for html files[]

When you have tidy for your platform installed and it is available from your path, you can simply set up a mapping to filter your content through it.

:vmap ,x :!tidy -q -i --show-errors 0<CR>

This means, from visual mode, you can simply press ,x and Vim will filter your content through tidy. This will call tidy in quiet mode (-q) and instruct it to indent the lines (-i). Errors won't be shown (--show-errors 0), since the lines should not be lost.

Alternatively, you can also create a :command that calls tidy:

:command Thtml :%!tidy -q -i --show-errors 0
:command Txml  :%!tidy -q -i --show-errors 0 -xml

Automatic formatting of XML files[]

You can also use tidy to format xml files

:au FileType xml :%!tidy -i -xml --show-errors 0 2>/dev/null

This sets up a FileType autocommand, that will clean up your source using tidy, whenever Vim set's the Filetype to xml.

Using built-in commands[]

Using Vim's 'equalprg' option, you can use the = operator to reformat using HTMLTidy. Or, you can use the 'makeprg' option to just show the suggestions from HTMLTidy in your quickfix list.

:setlocal equalprg=tidy\ -quiet\ --show-errors\ 0
:setlocal  makeprg=tidy\ -quiet\ -e\ %

At this point you can use make to clean up the full file or you can use = to clean up sections. Vim also ships with a tidy compiler plugin, that set's the 'makeprg' automatically for you and also sets the 'errorformat' setting for you. To make this work, simply type: :compiler tidy

Setting up tidy using a filetype plugin[]

All those options, mappings and commands can be set up automatically for html/xml files automatically, if you use filetype plugins.

To make this work, simply put your settings into a file called html.vim (use xml.vim for the xml filetype and don't forget the -xml switch for tidy) and place it into the directory ~/.vim/ftplugin/ (Unix) or $VIM/vimfiles/ftplugin (windows, where $VIM is the installtion diretory of Vim). See also filetype-plugin

If you set up commands and mappings using filetype plugins, you should make those buffer-local (e.g. only available for buffers of that filetype. Use the <buffer> argument for mappings and the -buffer argument for commands (command-buffer).

References[]

Comments[]

If you are using tidy under Windows, you need to set your shellpipe=2> or else Vim won't see the output from tidy. Apparently these Unix tools write output to stderr instead of stdout and Vim isn't configured by default to handle this situation.


vim indents html very well when I put the line

filetype plugin indent on

into my personal ~/.vimrc (or ~\_vimrc) file. I also think that html-tidy is not able to indent only parts of a HTML file. Therefore, I do not use it as equalprg.

I use html-tidy only in order to check if my HTML document is well formed. Therefore, I create a ~/.vim/after/ftplugin/html.vim (or ~\vimfiles\after\ftplugin\html.vim or an html.vim placed in the directory that appears last when typing :set runtimepath?) and put into it (among other things) the lines:

setlocal makeprg=tidy\ -quiet\ -errors\ %
setlocal errorformat=line\ %l\ column\ %v\ -\ %m

I have found that the errorformat option must be adapted as shown in order to be able jump through the error list by means of :cn and :cp etc.


Tidy can be used for just a portion of the document by using the --show-body-only flag. For instance, on using vim6 on OSX the above command could be rewritten as:

:exe 'setlocal equalprg=tidy\ -quiet\ -i\ --show-body-only\ true\ -f\ '.&errorfile

the -i indents, that is optional

The rest of the tidy options can be found here: http://tidy.sourceforge.net/docs/quickref.html


Call a function for tidy - add to your vimrc

command Td :call Tidy()
function Tidy()
  let filename=expand("%:p") " escapes for bash
  let filename=substitute(filename, " ", "\\\\ ", "g")
  let filename=substitute(filename, "(", "\\\\(", "g")
  let filename=substitute(filename, ")", "\\\\)", "g")
  let filename=substitute(filename, "[", "\\\\[", "g")
  let filename=substitute(filename, "]", "\\\\]", "g")
  let filename=substitute(filename, "&", "\\\\&", "g")
  let filename=substitute(filename, "!", "\\\\!", "g")
  let filename=substitute(filename, ",", "\\\\,", "g")
  let filename=substitute(filename, "'", "?", "g")
  let filename2=substitute(filename, ".*", "&.tidy.htm", "")
  let filename3=substitute(filename, ".*", "&.errors.tidy.txt", "")
  execute "!tidy "."-f ".filename3." ".filename." > ".filename2.""
endfunction

Here is a mapping so Vim calls Tidy when pressing F12. Advantage of this solution: you can undo changes very easily. Put this in your vimrc:

map <F12> :%!tidy -q --tidy-mark 0 2>/dev/null<CR>

I use this:

command Txml set ft=xml | execute "%!tidy -q -i -xml"
command Thtml set ft=html | execute "%!tidy -q -i -html"

You can undo the formatting, but the ft change won't be undone.