Microsoft Small Basic

Program Listing: SHQ268
' XML Parser for Small Basic Help
' Version 0.2
' Copyright © 2018 Nonki Takahashi. The MIT License.

GraphicsWindow.Title = "XML Parser for Small Basic Help"
Init()
target = "GraphicsWindow"
out = out + LT + "p>" + LT + "a href=" + qt
out = out + "http://social.technet.microsoft.com/wiki/contents/articles/23583.small-basic-reference-documentation.aspx"
out = out + qt + ">Small Basic: Reference Documentation"
out = out + LT + "/a>" + AMP + "nbsp;" + AMP + "gt; " + target
out = out + LT + "/p>" + LF
out = out + "[toc]" + LF
out = out + LT + "p>" + AMP + "nbsp;" + LT + "/p>" + LF
p = 1
eob = Text.GetLength(buf)
While p < eob
param = "tag=member;name=Microsoft.SmallBasic.Library." + target
FindTag()
If tag = "" Then
p = eob + 1
Else
GetAttrAndText()
If Text.StartsWith(attr["name"], "T:") Then
obj = Text.GetSubTextToEnd(attr["name"], 32)
lObj = Text.GetLength(obj)
out = out + LT + "p>" + LT + "img alt="
out = out + qt + "object icon" + qt
out = out + " src=" + qt
out = out + "http://smallbasic.com/img/object_32.png"
out = out + qt + ">" + LT + "/p>" + LF
out = out + LT + "h1 style="
out = out + qt + "color: black; line-height: 20px;" + qt
out = out + ">" + obj + LT + "/h1>" + LF
Stack.PushValue("local", buf)
Stack.PushValue("local", p)
buf = tag
p = 1
param = "tag=summary;"
FindTag()
GetAttrAndText()
out = out + LT + "p style="
out = out + qt + "font-size: 14px" + qt + ">"
out = out + txt + LT + "/p>" + LF
p = Stack.PopValue("local")
buf = Stack.PopValue("local")
Controls.SetTextBoxText(tbox, out)
ElseIf Text.StartsWith(attr["name"], "P:") Then
If open["op"] Or open["event"] Then
CloseMembers()
open["op"] = "False"
open["event"] = "False"
EndIf
If Not[open["prop"]] Then
out = out + LT + "h2>Properties"
out = out + LT + "/h2>" + LF
out = out + LT + "div class="
out = out + qt + "membersDiv" + qt
out = out + " style="
out = out + qt + "margin-left: 12px;" + qt + ">" + LF
open["prop"] = "True"
EndIf
prop = Text.GetSubTextToEnd(attr["name"], 33 + lObj)
out = out + LT + "div class="
out = out + qt + "memberInfoDiv" + qt
out = out + " style="
out = out + qt + "margin: 12px 12px 24px; padding: 4px; "
out = out + "border: 1px solid #e0e0e0; "
out = out + "background-color: #f8f8f8;" + qt + ">" + LF
out = out + LT + "h3 style="
out = out + qt + "color: #666666; font-size: 14px; "
out = out + "font-weight: bold; margin-top: 0px; "
out = out + "margin-bottom: 2px;" + qt + ">" + LF
out = out + LT + "a name=" + qt + prop + qt + ">"
out = out + LT + "/a>"
out = out + LT + "img alt=" + qt + "operation icon" + qt
out = out + " src=" + qt
out = out + "http://smallbasic.com/img/property_16.png"
out = out + qt + ">" + AMP + "nbsp;" + prop + LF
Stack.PushValue("local", buf)
Stack.PushValue("local", p)
buf = tag
p = 1
param = "tag=summary;"
FindTag()
GetAttrAndText()
If Not[Text.IsSubText(txt, "Gets or sets")] And Not[Text.IsSubText(txt, "Specifies")] Then
out = out + LT + "span class=" + qt
out = out + "noteSpan" + qt + " style=" + qt
out = out + "margin-left:12px;font-size:10px;" + qt
out = out + ">(This property is read-only.)"
out = out + LT + "/span>" + LF
EndIf
out = out + LT + "/h3>" + LF
out = out + LT + "div class="
out = out + qt + "noteSpan" + qt
out = out + " style=" + qt
out = out + "color: #333333; font-size: 10px; "
out = out + "font-weight: bold;" + qt
out = out + ">" + obj + "." + prop
out = out + LT + "/div>"
out = out + LT + "!-- noteSpan -->" + LF
out = out + LT + "p style="
out = out + qt + "font-size: 14px" + qt
out = out + ">" + txt + LT + "/p>" + LF
out = out + LT + "/div>"
out = out + LT + "!-- membersInfoDiv -->" + LF
Controls.SetTextBoxText(tbox, out)
p = Stack.PopValue("local")
buf = Stack.PopValue("local")
ElseIf Text.StartsWith(attr["name"], "M:") Then
If open["prop"] Or open["event"] Then
CloseMembers()
open["prop"] = "False"
open["event"] = "False"
EndIf
If Not[open["op"]] Then
out = out + LT + "h2>Operations"
out = out + LT + "/h2>" + LF
out = out + LT + "div class="
out = out + qt + "membersDiv" + qt
out = out + " style="
out = out + qt + "margin-left: 12px;" + qt + ">" + LF
open["op"] = "True"
EndIf
op = Text.GetSubTextToEnd(attr["name"], 33 + lObj)
pParam = Text.GetIndexOf(op, "(")
If 0 < pParam Then
op = Text.GetSubText(op, 1, pParam - 1)
EndIf
out = out + LT + "div class="
out = out + qt + "memberInfoDiv" + qt
out = out + " style="
out = out + qt + "margin: 12px 12px 24px; padding: 4px; "
out = out + "border: 1px solid #e0e0e0; "
out = out + "background-color: #f8f8f8;" + qt + ">" + LF
out = out + LT + "h3 style="
out = out + qt + "color: #666666; font-size: 14px; "
out = out + "font-weight: bold; margin-top: 0px; "
out = out + "margin-bottom: 2px;" + qt + ">" + LF
out = out + LT + "a name=" + qt + op + qt + ">"
out = out + LT + "/a>"
out = out + LT + "img alt=" + qt + "operation icon" + qt
out = out + " src=" + qt
out = out + "http://smallbasic.com/img/method_16.png"
out = out + qt + ">" + AMP + "nbsp;" + op
out = out + LT + "/h3>" + LF
out = out + LT + "div class="
out = out + qt + "noteSpan" + qt
out = out + " style=" + qt
out = out + "color: #333333; font-size: 10px; "
out = out + "font-weight: bold;" + qt
out = out + ">" + obj + "." + op + "("
Stack.PushValue("local", buf)
Stack.PushValue("local", p)
buf = tag
p = 1
param = "tag=summary;"
FindTag()
GetAttrAndText()
desc[0] = txt
param = "tag=param;"
FindTag()
nArg = 0
While tag <> ""
nArg = nArg + 1
GetAttrAndText()
arg[nArg] = attr["name"]
desc[nArg] = txt
param = "tag=param;"
FindTag()
EndWhile
For iArg = 1 To nArg
If 1 < iArg Then
out = out + ", "
EndIf
out = out + arg[iArg]
EndFor
out = out + ")" + LT + "/div>"
out = out + LT + "!-- noteSpan -->" + LF
out = out + LT + "p style="
out = out + qt + "font-size: 14px" + qt
out = out + ">" + desc[0] + LT + "/p>" + LF
out = out + LT + "div class="
out = out + qt + "argumentsDiv" + qt
out = out + " style=" + qt
out = out + "font-size: 11px; margin-left: 12px;" + qt + ">" + LF
For iArg = 1 To nArg
out = out + LT + "h4 style="
out = out + qt + "color: #666666; font-size: 12px; "
out = out + "font-weight: bold; margin-top: 4px; "
out = out + "margin-bottom: 0px;" + qt + ">" + arg[iArg]
out = out + LT + "/h4>" + LF
out = out + txt + LF
EndFor
param = "tag=returns;"
FindTag()
GetAttrAndText()
out = out + LT + "h4 style="
out = out + qt + "color: #666666; font-size: 12px; "
out = out + "font-weight: bold; margin-top: 4px; "
out = out + "margin-bottom: 0px;" + qt + ">Returns"
out = out + LT + "/h4>" + LF
out = out + txt + LF
p = Stack.PopValue("local")
buf = Stack.PopValue("local")
out = out + LT + "/div>"
out = out + LT + "!-- argumentsDiv -->" + LF
out = out + LT + "/div>"
out = out + LT + "!-- membersInfoDiv -->" + LF
Controls.SetTextBoxText(tbox, out)
ElseIf Text.StartsWith(attr["name"], "E:") Then
If open["prop"] Or open["op"] Then
CloseMembers()
open["prop"] = "False"
open["op"] = "False"
EndIf
If Not[open["event"]] Then
out = out + LT + "h2>Events"
out = out + LT + "/h2>" + LF
out = out + LT + "div class="
out = out + qt + "membersDiv" + qt
out = out + " style="
out = out + qt + "margin-left: 12px;" + qt + ">" + LF
open["event"] = "True"
EndIf
event = Text.GetSubTextToEnd(attr["name"], 33 + lObj)
out = out + LT + "div class="
out = out + qt + "memberInfoDiv" + qt
out = out + " style="
out = out + qt + "margin: 12px 12px 24px; padding: 4px; "
out = out + "border: 1px solid #e0e0e0; "
out = out + "background-color: #f8f8f8;" + qt + ">" + LF
out = out + LT + "h3 style="
out = out + qt + "color: #666666; font-size: 14px; "
out = out + "font-weight: bold; margin-top: 0px; "
out = out + "margin-bottom: 2px;" + qt + ">" + LF
out = out + LT + "a name=" + qt + event + qt + ">"
out = out + LT + "/a>"
out = out + LT + "img alt=" + qt + "operation icon" + qt
out = out + " src=" + qt
out = out + "http://smallbasic.com/img/event_16.png"
out = out + qt + ">" + AMP + "nbsp;" + event
out = out + LT + "/h3>" + LF
out = out + LT + "div class="
out = out + qt + "noteSpan" + qt
out = out + " style=" + qt
out = out + "color: #333333; font-size: 10px; "
out = out + "font-weight: bold;" + qt
out = out + ">" + obj + "." + event
out = out + LT + "/div>"
out = out + LT + "!-- noteSpan -->" + LF
out = out + LT + "p style="
out = out + qt + "font-size: 14px" + qt
Stack.PushValue("local", buf)
Stack.PushValue("local", p)
buf = tag
p = 1
param = "tag=summary;"
FindTag()
GetAttrAndText()
out = out + ">" + txt + LT + "/p>" + LF
out = out + LT + "/div>"
out = out + LT + "!-- membersInfoDiv -->" + LF
Controls.SetTextBoxText(tbox, out)
p = Stack.PopValue("local")
buf = Stack.PopValue("local")
Controls.SetTextBoxText(tbox, out)
EndIf
EndIf
EndWhile
If open["prop"] Or open["op"] Or open["event"] Then
CloseMembers()
EndIf
out = out + LT + "p> "
out = out + LT + "/p>" + LF
out = out + LT + "h1>See Also"
out = out + LT + "/h1>" + LF
out = out + LT + "ul>" + LF
out = out + LT + "li>"
out = out + LT + "a href=" + qt
out = out + "http://social.technet.microsoft.com/wiki/contents/articles/23583.small-basic-reference-documentation.aspx"
out = out + qt + ">Small Basic: Reference Documentation"
out = out + LT + "/a>"
out = out + LT + "/li>" + LF
out = out + LT + "li>"
out = out + LT + "a href=" + qt
out = out + "http://social.technet.microsoft.com/wiki/contents/articles/16767.the-developers-reference-guide-to-small-basic.aspx"
out = out + qt + ">The Developer’s Reference Guide to Small Basic
out = out + LT + "/a>"
out = out + LT + "/li>" + LF
out = out + LT + "li>"
out = out + LT + "a href=" + qt
out = out + "http://social.technet.microsoft.com/wiki/contents/articles/17553.wiki-small-basic-portal.aspx"
out = out + qt + ">Wiki: Small Basic Portal"
out = out + LT + "/a>"
out = out + LT + "/li>" + LF
out = out + LT + "/ul>" + LF
out = out + LT + "br>" + LF
Controls.SetTextBoxText(tbox, out)

Sub CloseMembers
out = out + LT + "/div>"
out = out + LT + "!-- membersDiv -->" + LF
EndSub

Sub FindTag
' find tag from html buffer
' param["tag"] - tag name
' param["name"] - name substarts with
' param p - pointer for buffer
' param buf - html buffer
' return tag - found tag
' return p - updated pointer
pSave = p
tag = ""
findNext = "True"
While findNext
findNext = "False" ' tag may be not found
pTag = Text.GetIndexOf(Text.GetSubTextToEnd(buf, p), LT + param["tag"])
If 0 < pTag Then
lTag = Text.GetLength(param["tag"]) + 1
pTag = p + pTag - 1
len = Text.GetIndexOf(Text.GetSubTextToEnd(buf, pTag), "/" + param["tag"] + ">")
If param["name"] = "" Then
len = len + lTag
tag = Text.GetSubText(buf, pTag, len)
findNext = "False" ' found the tag
ElseIf 0 < len Then
findNext = "True" ' tag may have different class
len = len + lTag
attr = "name=" + qt
pAttr = pTag + lTag + 1
lAttr = Text.GetLength(attr)
If Text.GetSubText(buf, pAttr, lAttr) = attr Then
pQ = Text.GetIndexOf(Text.GetSubTextToEnd(buf, pAttr + lAttr), qt)
If 0 < pQ Then
nameText = Text.GetSubText(buf, pAttr + lAttr, pQ - 1)
If Text.IsSubText(nameText, param["name"]) Then
tag = Text.GetSubText(buf, pTag, len)
findNext = "False" ' found the tag
EndIf
EndIf
EndIf
EndIf
p = pTag + len
EndIf
EndWhile
If tag = "" Then
p = pSave
EndIf
EndSub

Sub GetAttrAndText
' get attributes and text from given tag
' param tag - given tag
' return attr[] - array of attributes in the tag
' return txt - text in the tag
pTag = Text.GetIndexOf(tag, " ") + 1
pEnd = Text.GetIndexOf(tag, ">")
attr = ""
While pTag <= pEnd
pEq = Text.GetIndexOf(Text.GetSubTextToEnd(tag, pTag), "=")
If 0 < pEq Then
pEq = pTag + pEq - 1
If Text.GetSubText(tag, pEq + 1, 1) = qt Then
pQ = Text.GetIndexOf(Text.GetSubTextToEnd(tag, pEq + 2), qt)
If 0 < pQ Then
pQ = pEq + 2 + pQ - 1
attr[Text.GetSubText(tag, pTag, pEq - pTag)] = Text.GetSubText(tag, pEq + 2, pQ - pEq - 2)
pTag = pQ + 2
EndIf
EndIf
Else
pTag = pEnd + 1
EndIf
EndWhile
If pEnd + 1 < pTag Then
pTag = pEnd + 1
EndIf
len = Text.GetLength(tag)
txt = ""
While pTag <= len
pL = Text.GetIndexOf(Text.GetSubTextToEnd(tag, pTag), LT)
If pL = 0 Then
txt = Text.Append(txt, Text.GetSubTextToEnd(tag, pTag))
pTag = len + 1
Else
pL = pTag + pL - 1
txt = Text.Append(txt, Text.GetSubText(tag, pTag, pL - pTag))
pR = Text.GetIndexOf(Text.GetSubTextToEnd(tag, pTag), ">")
If 0 < pR Then
pTag = pTag + pR
Else
pTag = len + 1
EndIf
EndIf
EndWhile
EndSub

Sub Init
Not = "False=True;True=False;"
AMP = "&"
LF = Text.GetCharacter(10)
LT = "<"
qt = Text.GetCharacter(34)
gw = 598
gh = 428
GraphicsWindow.Width = gw
GraphicsWindow.Height = gh
GraphicsWindow.FontName = "Consolas"
GraphicsWindow.FontBold = "False"
GraphicsWindow.BrushColor = "Black"
tbox = Controls.AddMultiLineTextBox(0, 0)
Controls.SetSize(tbox, gw, gh)
open = "prop=False;op=False;event=False;"
path = Program.Directory + "\SmallBasicLibrary.xml"
out = ""
' The following line could be harmful and has been automatically commented.
' buf = File.ReadContents(path)
EndSub