中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [讨论]vbs网页编辑器效率有点低,请高手帮忙看一下.
作者:
标题: [讨论]vbs网页编辑器效率有点低,请高手帮忙看一下. 上一主题 | 下一主题
sonicandy
中级用户





积分 273
发帖 91
注册 2007-5-7
状态 离线
『楼 主』:  [讨论]vbs网页编辑器效率有点低,请高手帮忙看一下.

两个主要的问题:
1 是否可以将选择内容扩展到段落?也许这样可以提高效率.
2 编辑键捕获及过滤: 编辑操作有问题,选中一段后,按退格键应该是全部删除的,可是现在却只删除了一个字符.

div.hta
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<hta:application>
<HEAD>
<TITLE> Editor </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="sonic_andy">
<META NAME="Keywords" CONTENT="editor">
<META NAME="Description" CONTENT="a vbscript editor">
  
<style>
        p {padding:0 0 0 0; margin:0 0 0 0;}
        .editor {border:double; width:100%; height:60%; overflow:scroll;}
        .SCRIPTS {color:red}
        .QUOTATION {color:#800080}
        .COMMENT {color:green}
        .KEYWORD1 {color:blue}
        .KEYWORD2 {color:red}
        .KEYWORD3 {color:blue}
        .KEYWORD4 {color:blue}
        .KEYWORD5 {color:blue}
        .PREFIX_KEYWORD {color:brown}
        .SUFFIX_KEYWORD {color:brown}
        .DIGIT {color:brown}
</style>
<script language="vbscript" src="syntax.vbs"></script>
<script language="vbscript">
Set oSC = New SyntaxColor
Set reg = new regexp
reg.ignorecase = True
reg.global = True
Set fso = CreateObject("scripting.filesystemobject")

Sub writedebugfile(str2write)
        Set file = fso.opentextfile("debug.txt",2,true)
        Call file.write(str2write)
        Call file.close()
        Set file = Nothing
End Sub

Sub edit()
        If Not isValidKey() Then Exit Sub
       
        ' 得到并保存当前选中的位置
        Set range = Document.selection.createrange()
        x = range.offsetleft
        y = range.offsettop
        l = Len(range.text)

        ' 过滤操作
        str = Document.all.editor.innerhtml

        reg.pattern="<br>"
        str = reg.Replace(str,"<br>" & vbcrlf)

        reg.pattern="</?span[^>]*>"
        str = reg.Replace(str,"")

'        Document.all.status.value = str
'        MsgBox "wait"

'        oSC.infpath = "D:\CHDOC\vbstxclass"
'        osc.stxpath = "D:\CHDOC\vbstxclass\stx"
        Call osc.get_syntax("vbs")
        str = osc.analyze_syntax(str)

'        reg.pattern = vbcr
'        str = reg.Replace(str,"<br>" & vbcrlf)

        Document.all.editor.innerhtml = str

        ' 恢复当前位置
        Call range.movetoelementtext(Document.all.editor)
        Call range.movetopoint(x,y)
        Call range.moveend("character",l)

'        Call range.collapse(false)
'        Call range.expand("word")
        Call range.Select()

        Document.all.status.value = Document.all.editor.innerhtml
End Sub

Function isValidKey()
        Select Case Window.event.keycode
        Case 37,38,39,40        ' Left,Up,Right,Down
                isValidKey = False
                Exit Function
        Case 33,34,35,36        ' Home,End,PgUp,PgDn
                isValidKey = False
                Exit Function
        Case 16,17                ' Shift,Ctrl
                isValidKey = False
                Exit Function
        End Select
        If Window.event.altkey Then ' 按下Alt
                isValidKey = False
                Exit Function
        End If
        If Window.event.ctrlkey Then ' 按下Ctrl
                isValidKey = False
                Exit Function
        End If
        isValidKey = True
End Function

Sub filterkey()
        If Not isValidKey() Then Exit Sub

        Set range = Document.selection.createrange()

        ' 处理tab键
        If Window.event.keycode=Asc(vbtab) Then
                Window.event.returnvalue = False
                range.text = vbtab
        End If

        Call range.collapse(false)
        Call range.Select()
End Sub

Sub syc()
        Document.all.status.value = Document.all.editor.innerhtml
End Sub
</script>
</HEAD>

<BODY>
<div id="editor" contenteditable class="editor" onkeydown="filterkey" onkeyup="edit"></div>
<br>
<textarea id="status" cols="120" rows="10"></textarea>
<br>
<input type="button" value="同步" onclick="syc">
</BODY>
</hta:application>
</HTML>
syntax.vbs
Option Explicit

' 语法着色类 sonic_andy
'Set test = New SyntaxColor
'Call test.get_syntax("vbs")
'msgbox test.analyze_syntax("asdfasdf")

class SyntaxColor
        Private quotation_span      '引用标记
        Private comment_span        '注释标记
        Private script_span         '脚本标记
        Private keyword_span        '关键字标记
        Private prefix_keyword_span '前缀关键字标记
        Private suffix_keyword_span '后缀关键字标记
        Private digit_span          '数字标记
        Private span_end            '结束标记

        Private setting             '当前
        Private keyword()           '关键字字符串
        Private prefix              '前缀
        Private suffix              '后缀
        Private html_instance       'a html instance
        Private mtabwidth           'tab宽度
        Public infpath              'inf文件路径
        Public stxpath              'stx文件路径

        Private fso                 '文件系统对象
        Private reg                 '正则表达式对象

        Private Sub Class_Initialize()
                quotation_span = "<SPAN CLASS=QUOTATION>"
                comment_span = "<SPAN CLASS=COMMENT>"
                script_span = "<SPAN CLASS=SCRIPTS>"
                prefix_keyword_span = "<SPAN CLASS=PREFIX_KEYWORD>"
                suffix_keyword_span = "<SPAN CLASS=SUFFIX_KEYWORD>"
                digit_span = "<SPAN CLASS=DIGIT>"
                keyword_span = Array( _
                        "<SPAN CLASS=KEYWORD1>", _
                        "<SPAN CLASS=KEYWORD2>", _
                        "<SPAN CLASS=KEYWORD3>", _
                        "<SPAN CLASS=KEYWORD4>", _
                        "<SPAN CLASS=KEYWORD5>")
                span_end = "</SPAN>"
               
                Set setting = CreateObject("scripting.dictionary")
                setting.CompareMode = vbTextCompare
                ReDim keyword(0)
                Set fso = CreateObject("scripting.filesystemobject")
                Set reg = New RegExp
                reg.IgnoreCase = True
                reg.Global = True
                infpath = ".\"
                stxpath = ".\stx\"
                mtabwidth = 4
        End Sub

        ' 从"ext.inf"文件中读取扩展名和分析信息文件的对应关系,
        ' 并且调用get_info函数得到语法相关信息数组.
        '
        ' @param string ext 需要分析内容的扩展名
        Public Function get_syntax(ext)
                Dim file        ' 文件流对象
                Dim configure   ' 文件内容
                Dim lines       ' 被换行分隔的内容数组
                Dim arr         ' 每一行中,被等号分隔的内容
                Dim i
               
                '得到扩展名和相关文件名配置文件的内容
                Set file = fso.OpenTextFile(fso.BuildPath(infpath, "ext.inf"), 1) 'vbide
                configure = file.ReadAll
                Call file.Close

                '将内容分割到数组
                lines = Split(configure, vbCrLf)
                For i = LBound(lines) To UBound(lines)
                        '先用等号分割将字符串转换为数组array
                        arr = Split(lines(i), "=")
                        '查找"扩展名;"是否在字符串array[1]中
                        If InStr(arr(1), ext & ";") > 0 Then
                                Call get_info(arr(0))
                                get_syntax = True
                        End If
                Next
                get_syntax = False
        End Function

        ' 从语法文件中读取语法信息,并且将它存贮到信息数组中
        '
        ' @param string filename 语法信息文件名
        Private Function get_info(filename)
                Dim file        ' 文件流对象
                Dim sfile       ' 文件内容
                Dim arr         ' 被\n#分隔的内容
                Dim i
               
                '读取语法文件内容
                Set file = fso.OpenTextFile(fso.BuildPath(stxpath, filename), 1) ' vbide
                sfile = file.ReadAll
                Call file.Close
                '清除行首的注释
                reg.Pattern = "(\n[^=]*;[^\n]*\n)"
                sfile = reg.Replace(sfile, vbCrLf)
                '清除多余的空行
                reg.Pattern = "([\n]+)"
                sfile = reg.Replace(sfile, vbCrLf)
                '用井号将内容分割为数组
                arr = Split(sfile, vbCrLf & "#")
                For i = LBound(arr) To UBound(arr)
                        If arr(i) <> "" Then
                                Dim pos     ' 等号的位置
                                Dim name    ' 等号前的名称
                                Dim value   ' 等号后的值
                               
                                pos = InStr(arr(i), "=")
                                name = Mid(arr(i), 1, pos - 1)
                                name = Replace(name, "#", "")
                                value = Mid(arr(i), pos + 1)
                               
                                If InStr(name, "KEYWORD") = 1 Then '名称是关键字(keyword)
                                        Dim temp ' 临时字符串
                                       
                                        temp = Mid(value, InStr(value, vbCrLf)) & vbCrLf
                                        keyword(UBound(keyword)) = temp
                                        ReDim Preserve keyword(UBound(keyword) + 1)
                                Else
                                        value = Replace(value, vbCr, "")
                                        value = Replace(value, vbLf, "")

                                        If name = "PREFIX" Then
                                                prefix = prefix & value
                                        ElseIf name = "SUFFIX" Then
                                                suffix = suffix & value
                                        ElseIf name = "DELIMITER" Then
                                                setting(name) = value & vbCrLf & vbTab & " "
                                        ElseIf name <> "" And value <> "" Then '若名称不为空,去掉回车加入数组
                                                setting(name) = Replace(value, vbCrLf, "")
                                        End If
                                End If
                        End If
                Next
                '创建并设置本类的html实例
                If ((isOptionEnable("HTML_EMBEDDED")) And setting("HTML_EMBEDDED") = "y") Then
                        Set html_instance = New SyntaxColor
                        html_instance.get_syntax ("html")
                        html_instance.set_tabwidth (mtabwidth)
                 End If
        End Function

        ' 将字符串中的tab键转换为空格,并且将结果字符串作为html编码返回
        ' 该函数作为引用、注释等特殊情况的处理函数被analyze_syntax函数调用。
        '
        ' @param string str 源字符串
        ' @param int linepos 当前行的位置
        ' @param int mtabwidth tab键的宽度
        ' @return 结果字符串
        Private Function converttab(str, linepos)
                Dim dest    ' 目标字符串
                Dim i
                Dim ch      ' 第i个字符
                Dim offset  ' 小于于设定tab宽度的行偏移量
               
                dest = ""
                For i = 1 To Len(str)
                        ch = Mid(str, i, 1)
                        If (ch = "\t") Then
                                offset = mtabwidth - linepos Mod mtabwidth
                                dest = dest & Space(offset)
                                linepos = linepos + offset
                        Else
                                dest = dest & ch
                                linepos = linepos + 1
                        End If
                        If (ch = "\n") Then
                                linepos = 0
                        End If
                Next
                converttab = txt2htm(dest)
        End Function

        Private Function txt2htm(str)
                txt2htm = str
                txt2htm = Replace(txt2htm, "", "")
        End Function

        ' 设置tab宽度
        '
        ' @param int mtabwidth
        Public Property Let tabwidth(ntab)
                mtabwidth = ntab
                If ((isOptionEnable("HTML_EMBEDDED")) And setting("HTML_EMBEDDED") = "y") Then
                        html_instance.set_tabwidth (mtabwidth)
                End If
        End Property

        Public Property Get tabwidth()
                tabwidth = mtabwidth
        End Property


        ' 外部使用,语法着色功能函数
        '
        ' @param string source
        Public Function analyze_syntax(source)
                Dim dest    ' 目标字符串
                Dim i
               
               
                dest = ""
                If ((isOptionEnable("HTML_EMBEDDED")) And setting("HTML_EMBEDDED") = "y") Then
                        i = 0
                        While (True)
                                Dim slen    ' 作用域长度
                               
                                slen = InStr(i, source, setting("SCRIPT_BEGIN")) - i
                                If (slen >= 0) Then
                                        dest = dest & html_instance.private_analyze(Mid(source, i, slen))
                                        i = i + slen
                                        slen = InStr(i, source, setting("SCRIPT_END")) - i + Len(setting("SCRIPT_END"))
                                        If (slen > 0) Then
                                                dest = dest & private_analyze(Mid(source, i, slen))
                                                i = i + slen
                                        End If
                                Else
                                        dest = dest & html_instance.private_analyze(Mid(source, i))
                                        analyze_syntax = dest
                                        Exit Function
                                End If
                        Wend
                Else
                        analyze_syntax = private_analyze(source)
                End If
        End Function

        Private Function isOptionEnable(name)
                If setting.Exists(name) Then
                        If setting(name) <> "" Then
                                isOptionEnable = True
                                Exit Function
                        End If
                End If
                isOptionEnable = False
        End Function

        ' 分析词法,并着色(内部使用).
        '
        ' @param string source 源字符串
        ' @param int mtabwidth tab的宽度
        ' @return string 着色后的字符串
        Private Function private_analyze(source)
                Dim dest: dest = "" ' 目标字符串
                Dim ch: ch = ""     ' 当前字符
                Dim buffer: buffer = "" ' 缓冲区
                Dim linepos: linepos = 0 '行计数
                Dim offset
                Dim slen
                Dim i
               
                Dim CompareMode
                If isOptionEnable("CASE") And setting("CASE") = "y" Then
                        reg.IgnoreCase = False
                Else
                        reg.IgnoreCase = True
                End If
               
                '去掉源字符串的反斜杠
                'source = stripslashes(source)
                For i = 1 To Len(source)
                        ch = Mid(source, i, 1)
                        If (InStr(setting("DELIMITER"), ch) > 0) Then
                                '将缓冲区中字符串的长度计算加入行位置变量
                                linepos = linepos + Len(buffer)
                                '缓冲区不为空的话就分析缓冲区内容是否是关键字
                                If (buffer <> "") Then
                                        Dim j
                                        For j = 0 To UBound(keyword)
                                                reg.Pattern = "\b" & buffer & "\b"
                                                If (reg.Test(keyword(j))) Then
                                                        dest = dest & keyword_span(j) & txt2htm(buffer) & span_end
                                                        buffer = ""
                                                        Exit For
                                                End If
                                        Next
                                End If
                                '缓冲区不为空的话就分析缓冲区内容是否是前缀关键字/后缀关键字,并检查是否是数字
                                If buffer <> "" Then
                                        If (Not IsEmpty(prefix) And InStr(prefix, Mid(buffer, 1, 1)) > 0) Then
                                                dest = dest & prefix_keyword_span & txt2htm(buffer) & span_end
                                                buffer = ""
                                        ElseIf (Not IsEmpty(suffix) And InStr(suffix, Mid(buffer, Len(buffer), 1)) > 0) Then
                                                dest = dest & suffix_keyword_span & txt2htm(buffer) & span_end
                                                buffer = ""
                                        ElseIf ((isOptionEnable("NUMBER_PATTERN")) And _
                                                                setting("NUMBER_PATTERN") = "cpp" And IsNumeric(buffer)) Then
                                                dest = dest & digit_span & txt2htm(buffer) & span_end
                                                buffer = ""
                                        End If
                                End If
                                '如果缓冲区还不为空,就输出缓冲区
                                If buffer <> "" Then
                                        dest = dest & txt2htm(buffer)
                                        buffer = ""
                                End If
                               
                                '开始判断分隔符是否是有意义的字符
                                If ch = vbLf Then
                                        offset = mtabwidth - linepos Mod mtabwidth
                                        dest = dest & txt2htm(Space(offset))
                                        linepos = linepos + offset
                                ElseIf isEqual("LINECOMMENT", source, i) Then
                                        dest = dest & comment_span
                                        slen = InStr(i, source, vbCrLf) - i
                                        If slen > 0 Then
                                                dest = dest & converttab(Mid(source, i, slen), linepos)
                                                i = i + slen - 1
                                        Else
                                                dest = dest & converttab(Mid(source, i, Len(source) - i), linepos)
                                                i = Len(source)
                                        End If
                                        dest = dest & span_end
                                ElseIf isEqual("LINECOMMENT2", source, i) Then
                                        dest = dest & comment_span
                                        slen = InStr(i, source, vbCrLf) - i
                                        If (slen > 0) Then
                                                dest = dest & converttab(Mid(source, i, slen), linepos)
                                                i = i + slen - 1
                                        Else
                                                dest = dest & converttab(Mid(source, i, Len(source) - i), linepos)
                                                i = Len(source)
                                        End If
                                        dest = dest & span_end
                                ElseIf isEqual("COMMENTON", source, i) Then
                                        dest = dest & comment_span
                                        slen = InStr(i + 1, source, setting("COMMENTOFF")) - i + Len(setting("COMMENTOFF"))
                                        If slen > 0 Then
                                                dest = dest & converttab(Mid(source, i, slen), linepos)
                                                i = i + slen - 1
                                        Else
                                                dest = dest & converttab(Mid(source, i, Len(source) - i), linepos)
                                                i = Len(source)
                                        End If
                                        dest = dest & span_end
                                ElseIf isEqual("COMMENTON2", source, i) Then
                                        dest = dest & comment_span
                                        slen = InStr(i + 1, source, setting("COMMENTOFF2")) - i + Len(setting("COMMENTOFF2"))
                                        If slen > 0 Then
                                                dest = dest & converttab(Mid(source, i, slen), linepos)
                                                i = i + slen - 1
                                        Else
                                                dest = dest & converttab(Mid(source, i, Len(source) - i), linepos)
                                                i = Len(source)
                                        End If
                                        dest = dest & span_end
                                ElseIf isEqual("QUOTATION1", source, i) Then
                                        dest = dest & quotation_span
                                        slen = InStr(i + 1, source, setting("QUOTATION1")) - i + Len(setting("QUOTATION1"))
                                        If slen > 0 Then
                                                dest = dest & converttab(Mid(source, i, slen), linepos)
                                                i = i + slen - 1
                                        Else
                                                dest = dest & converttab(Mid(source, i, Len(source) - i), linepos)
                                                i = Len(source)
                                        End If
                                        dest = dest & span_end
                                ElseIf isEqual("QUOTATION2", source, i) Then
                                        dest = dest & quotation_span
                                        slen = InStr(i + 1, source, setting("QUOTATION2")) - i + Len(setting("QUOTATION2"))
                                        If slen > 0 Then
                                                dest = dest & converttab(Mid(source, i, slen), linepos)
                                                i = i + slen - 1
                                        Else
                                                dest = dest & converttab(Mid(source, i, Len(source) - i), linepos)
                                                i = Len(source)
                                        End If
                                        dest = dest & span_end
                                Else
                                        '没有特殊意义,直接输出
                                        dest = dest & txt2htm(ch)
                                        linepos = linepos + 1
                                End If
                                '如果是换行符,就将行计数清零
                                If (ch = vbLf) Then
                                        linepos = 0
                                End If
                        Else
                                '不是分隔符,则将字符加入缓冲区
                                buffer = buffer & ch
                        End If
                Next
                private_analyze = dest & buffer
        End Function

        Private Function isEqual(name, source, offset)
                isEqual = isOptionEnable(name)
                isEqual = isEqual And InStr(offset, source, setting(name)) = offset
        End Function
End Class
下载地址

[ Last edited by sonicandy on 2007-10-28 at 08:51 AM ]

2007-10-28 08:48
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
sonicandy
中级用户





积分 273
发帖 91
注册 2007-5-7
状态 离线
『第 2 楼』:  

改成ActiveX了,效果还可以,机制改为F5刷新.如果有兴趣可以去http://myvbscript.googlecode.com

2007-11-26 21:07
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: