在制作CHM格式的项目API参考手册的时候,通常是需要将API对应的html文档元素整合,并使用CHM生成工具生成CHM文档。但是在开发过程中,对一些需要说明注释的对象进行描述时,比如描述方法的内容、引用的参数和使用方式等,一般使用txt文档编辑,而不会直接在html文档里编辑。那么从txt文档到html文档这一过程如果能自动转换的话,将为制作API参考手册提高很大效率。
从txt文档转换成html文档的具体思路是:取出txt文档中的字段,填充到html模板中的对应填充字段。为此,需要做以下准备:
1、按照一定的格式编写txt文档;
2、设置html模板,在模板中的待填充字段处定义关键字标记;
PART1
方法名/组件名(注:只能有一个换行符)
返回值类型(注:只能有一个换行符)
概述(注:只能有一个换行符)
PART2
参数或组件属性名(注:只能有一个换行符)
参数或组件属性类型(注:只能有一个换行符)
参数或组件属性描述(注:只能有一个换行符)
参数或组件属性
参数或组件属性类型
参数或组件属性描述
PART3
SEG
代码描述(注:只能有一个换行符)
代码段(注:只能有一个换行符)
SEG
代码描述
代码段
Txt文档分为三个部分,其中用关键字PART1、PART2、PART3标记每一个部分的开始,每部分的文本内容按照上述txt文档格式的定义顺序进行编辑。在PART3部分中,用SEG关键字标记每一个示例代码段的开始。
PART1
getHostIp(ip,[fn])
jQuery(object)
获取本地IP。当机器有多网卡时,需要根据服务器IP地址判断使用哪一张网卡,以便能正确接收到媒体流。
PART2
ip
String
服务器ip。
fn
Function
可选参数,打开接收端口成功之后的回调方法。
PART3
SEG
获取第四个视频面板并获取本地ip。
$.activexP.getActivex(4).getHostIp('121.0.1.25',function(){
alert('成功获取本地可用ip!');
});
<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.1//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml11.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml">
<head>
<metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/>
<title>PART[1]</title>
<linktype="text/css"rel="stylesheet"href="../../style/style.css"/>
</head>
<bodyid="split">
<divid="content">
<divrel="jQuery">
<h2><span>返回值:PART[3]</span>PART[2]</h2>
<h3>概述</h3>
<div>
<p>PART[4]</p>
<div>
<p></p></div></div>
<h3>参数列表</h3>
<div>
<h4><strong>PART[5]</strong><span>PART[6]</span><em></em></h4>
<p><strong></strong>PART[7]</p>
<span></span>
</div>
<div>
<h3>示例</h3>
<spanid="f_ad2"></span>
<h4>描述:</h4>
<p>PART[8]</p>
<h5>代码:</h5>
<pre><code>
PART[9]
</code></pre>
</div>
</div>
</div>
</body>
</html>
当前的方法中,只使用了一个html模板,在模板的每个需要填充的部分,都用关键字PART[n]标记,其中n=1...9,表示待填充的参数顺序。各填充字段的含义为:
PART[1]:生成html页面的标题;
PART[2]:需说明的组件名或方法名;
PART[3]:方法的返回值类型;
PART[4]:组件或方法的概述;
PART[5]:方法的参数名或组件的属性名
PART[6]:方法的参数类型或组件的属性名类型
PART[7]:方法的参数描述或组件的属性描述
PART[8]:示例代码段描述
PART[9]:示例代码段
Txt文档转换到html文档的具体实现技术主要包括:本地文件的上载和下载、字符串处理。
文件上载包括待转换的txt文档上载和html模板文档的上载,两者的处理方式是相似的。
文件的上载使用了flash.net.FileReference,具体过程是:
新建一个FileReference对象,
publicvarChoose:FileReference=newFileReference();
并通过FileReference.browse()方法打开本地文件选择的窗口,选择所需上传的文件。
protectedfunctionchoseTxtBtn_clickHandler(event:MouseEvent):void
{
configuerListeners(Choose);
Choose.browse();
}
在确定选择文件后,FileReference对象会触发一系列事件,
为了在文件上载的各个阶段处理相应事件,定义FileReference对象时,需要添加一个监听,为各状态添加事件处理逻辑。在下载操作期间,文件的name属性在SELECT事件时得到填充,其他所有属性在COMPLETE事件时得到填充,比如文件的类型和文件数据等。
txt文档上传之后,需要对其中的字符串内容进行提取,根据txt文档编辑格式,将其中的字符串分为不同的模块:标题、方法/组件名、返回值类型、概述、参数说明列表、代码示例列表。
设计一个存储txt文本内容的类HtmlContent,包含字符型的标题属性、方法/组件名属性、返回值类型属性、概述属性,还有ArrayCollection类型的参数说明列表属性和代码示例列表属性。
Html文档上传之后,将整个html文档中的数据看作一个字符串。
根据txt文档中设置的关键字标记,提取相应字符串,并存储到类HtmlContent的对象中,之后根据HTML模板中关键字标记的待填充字段,从该对象中依次提取数据进行处理,并逐个替代html模板字符串中的待填充字段(String.replace())。
在html模板字符串中的待填充字段被替换之后,需要将得到的字符串以html格式文件保存到本地,这是通过FileReference对象的FileReference.save()方法实现的:
varfile:FileReference=newFileReference();
file.save(String,filename);
save()方法首先打开一个操作系统对话框,让用户输入文件名并在本地计算机上选择用于保存文件的位置。当用户选择了位置并确认保存操作时(例如通过单击“保存”),保存过程即会开始。侦听器接收事件来表示保存操作的进度、成功或失败。如果需要在调用save()后确定对话框和保存操作的状态,代码必须对cancel、open、progress和complete等事件进行侦听。
FileReference.upload()、FileReference.download()、FileReference.load()和FileReference.save()函数均不分块,这些函数在调用它们之后即返回,而不会等待文件传输完成。此外,如果FileReference对象离开作用域,则该对象中尚未完成的任何事务将在离开作用域时被取消。
之前没有注意到函数参数传递的方式,在实现过程中出现了让我久思不得其解的bug。通过查阅Actionscript3.0的参考手册,才发现了问题的根源――参数传递方式。
AdobeActionscript3.0中的函数参数的传递,当参数为元数据类型(int/string/boolean等)时,以类似于值传递的方式进行;当参数为object对象类型时,以引用传递进行。
因此如果需要在类之间传递参数,不建议将参数以对象类型的形式传递。如果被传递的参数在使用过程中进行了赋值并进一步处理后直接返回结果对象,那么被传递的参数值将被更改为处理后的对象值。
举例如下:
ObjParam参数与全局objVar变量引用相同的对象,对objParam对象的x和y属性所作的更改将反映到objVar对象中。
文件的批量上传和下载需要使用flash.net.FileReferenceList。FileReferenceList类提供了让用户选择一个或多个要上载的文件的方法。通过给FileReferenceList对象注册监听选择文件事件:selectHandler,并执行FileReferenceList.browse()方法打开操作系统窗口,选择多个待上传文件。
FileReferenceList对象将用户磁盘上的一组本地文件(一个或多个文件)表示为FileReference对象的数组fileList。为了获取每个FileReference对象的数据,需要遍历fileList,并对其中的每个FileReference对象执行.load()方法。
//fileReferenceList批量选择txt文件
protectedfunctionchoseTxtBtn_clickHandler(event:MouseEvent):void
{
//fileReferenceList
ChooseList.addEventListener(Event.SELECT,selectHandler);
fileArryCol=newArrayCollection();
ChooseList.browse();
chooseTxtTag=true;
//
}
//fileReferenceList选择并确定txt文件后触发
privatefunctionselectHandler(event:Event):void{
for(varlen:int=0;len<ChooseList.fileList.length;len++){
Choose=ChooseList.fileList[len]asFileReference;
configuerListeners(Choose);
Choose.load();
}
}
//为每个fileReference注册监听事件
privatefunctionconfiguerListeners(dispatcher:IEventDispatcher):void{
dispatcher.addEventListener(Event.COMPLETE,completeHandler);
}
//每个文件上载完成后触发
privatefunctioncompleteHandler(event:Event):void{
varfile:FileReference=FileReference(event.target);
//trace("completeHandler:"+file.data);
fileArryCol.addItem(file);
}
由于FileReference的save方法不会等待文件处理完毕后再处理后续代码,且一次用户事件(比如单击)只能响应一个save方法。那么对于批量文件的保存,就不能直接通过在for循环中添加save方法。
(1)解决的一个方法是,使用for循环遍历文件集合,在每次遍历时使用Alert.show()弹出一个YESorNO的对话框,在对话框事件中添加文件保存处理代码。
(2)另一个方法是,不使用for循环遍历文件集合,而是通过一个按钮单击事件来响应保存事件,每单击一次,取下一个文件集合中的文件对象,并提示剩余待保存文件数,直到所有文件保存完。