Microsoft Small Basic

Program Listing: NPB609
''' MSDN Blog Article List
''' Version 0.1
''' Copyright © 2016 Nonki Takahashi. The MIT License.
''' Last update 2016-04-27
'
GraphicsWindow.Title = "MSDN Blog Article List 0.1"
WQ = Text.GetCharacter(34)
SQ = "'"
LT = "<"
Not = "False=True;True=False;"
formName = "Blog.frm.sb"
Form_GetForm()
Form_ShowForm()
site = "https://blogs.msdn.microsoft.com"
While "True"
If buttonClicked Then
GenerateHTML()
buttonClicked = "False"
Else
Program.Delay(200)
EndIf
EndWhile
Sub ConvertTag
''' Convert tag for the MSDN blog
''' param tagB - tag in the blog
''' return tagM - converted tag for the URL
tagM = Text.ConvertToLowerCase(tagB)
len = Text.GetLength(tagM)
For i = 1 To len
If Text.GetSubText(tagM, i, 1) = " " Then
tagM = Text.GetSubText(tagM, 1, i - 1) + "-" + Text.GetSubTextToEnd(tagM, i + 1)
EndIf
EndFor
EndSub
Sub ConvertTitle
''' Convert title
''' param txt - original title in a tag
''' return title - title for HTML
len = Text.GetLength(txt)
title = ""
delim = " " + CR + LF
lastDelim = 0
For i = 1 To len
c = Text.GetSubText(txt, i, 1)
If Not[Text.IsSubText(delim, c)] Then
s = i
i = len ' exit for
EndIf
EndFor
For i = len To 1 Step -1
c = Text.GetSubText(txt, i, 1)
If Not[Text.IsSubText(delim, c)] Then
e = i
i = 1 ' exit for
EndIf
EndFor
title = Text.GetSubText(txt, s, e - s + 1)
EndSub
Sub GenerateHTML
''' Generate HTML
boxbuf = ""
frm = form[id["articles"]]
Shapes.SetText(frm["obj"], "0 articles")
frm = form[id["blog"]]
blog = Controls.GetTextBoxText(frm["obj"])
frm = form[id["tag"]]
tagB = Controls.GetTextBoxText(frm["obj"])
If tagB <> "" Then
ConvertTag()
folder = "/" + blog + "/tag/" + tagM + "/"
Else
folder = "/" + blog + "/"
EndIf
frm = form[id["output"]]
outfile = Program.Directory + "\" + Controls.GetTextBoxText(frm["obj"])
nPosts = 0
maxPage = 1
outbuf = ""
block = ""
nArticle = 0
For page = 1 To maxPage
If page = 1 Then
pg = ""
Else
pg = "page/" + page + "/"
EndIf
url = site + folder + pg + "?orderby=date"
buf = Network.GetWebPageContents(url)
p = 1
eod = "False"
If page = 1 Then
param = "tag=a;class=for-desktop;"
FindTag()
GetAttrAndText()
ConvertTitle()
html = LT + "!DOCTYPE html>" + CR + LF
html = html + LT + "html lang=" + WQ + "en" + WQ + ">" + CR + LF
html = html + LT + "head>" + CR + LF
html = html + LT + "meta charset=" + WQ + "UTF-8" + WQ + ">" + CR + LF
html = html + LT + "title>" + title + LT + "/title>" + CR + LF
html = html + LT + "/head>" + CR + LF
html = html + LT + "body>" + CR + LF
html = html + LT + "h1>" + title + LT + "/h1>" + CR + LF
If tagB <> "" Then
html = html + LT + "p>Tag: " + tagB + LT + "/p>" + CR + LF
EndIf
html = html + LT + "ul>" + CR + LF
EndIf
While Not[eod]
param = "tag=a;rel=bookmark;"
FindTag()
If tag = "" Then
eod = "True"
Else
GetAttrAndText()
ConvertText()
block = "url | " + attr["href"] + CR + LF
block = block + "title | " + txt + CR + LF
html = html + LT + "li>"
html = html + LT + "a href=" + WQ + attr["href"] + WQ + ">" + txt + LT + "/a>"
param = "tag=time;class=entry-date published updated;"
FindTag()
html = html + " ("
If tag = "" Then
html = html + " "
eod = "True"
Else
GetAttrAndText()
block = block + "date | " + txt + CR + LF
html = html + txt
EndIf
block = block + CR + LF
html = html + ")" + CR + LF
nArticle = nArticle + 1
frm = form[id["articles"]]
Shapes.SetText(frm["obj"], nArticle + " articles")
outbuf = outbuf + block
frm = form[id["log"]]
Controls.SetTextBoxText(frm["obj"], outbuf)
EndIf
EndWhile
If page = 1 Then
param = "tag=a;class=page-numbers;"
FindTag()
While tag <> ""
tagSave = tag
FindTag()
EndWhile
tag = tagSave
GetAttrAndText()
maxPage = txt
EndIf
EndFor
block = "Total " + nArticle + " articles"
frm = form[id["articles"]]
Shapes.SetText(frm["obj"], block)
outbuf = outbuf + block + "." + CR + LF
frm = form[id["log"]]
Controls.SetTextBoxText(frm["obj"], outbuf)
html = html + LT + "/ul>" + CR + LF
html = html + LT + "p>" + block + ".

" + CR + LF
html = html + LT + "/html>" + CR + LF
' The following line could be harmful and has been automatically commented.
' File.WriteContents(outfile, html) ' outbuf for text
EndSub
Sub ConvertText
''' Convert &*; to unicode character
''' param txt
''' return txt
While Text.IsSubText(txt, "&")
c = Text.GetIndexOf(txt, "&")
l = Text.GetIndexOf(Text.GetSubTextToEnd(txt, c), ";")
kw = Text.GetSubText(txt, c + 1, l - 2)
If Text.StartsWith(kw, "#") Then
txtMid = Text.GetCharacter(Text.GetSubTextToEnd(kw, 2))
ElseIf kw = "quot" Then
txtMid = Text.GetCharacter(34)
Else
txtMid = ""
EndIf
txtLeft = Text.GetSubText(txt, 1, c - 1)
txtRight = Text.GetSubTextToEnd(txt, c + l)
txt = Text.Append(txtLeft, Text.Append(txtMid, txtRight))
EndWhile
EndSub
Sub FindTag
''' Find tag from html buffer
''' param["tag"] - tag name
''' param["class"] - class name
''' param["rel"] - rel name
''' param p - pointer for buffer
''' param buf - html buffer
''' return tag - found tag
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
pTag = p + pTag - 1
len = Text.GetIndexOf(Text.GetSubTextToEnd(buf, pTag), "/" + param["tag"] + ">")
If 0 < len Then
findNext = "True" ' tag may be different
lTag = Text.GetLength(param["tag"]) + 1
len = len + lTag
tag = Text.GetSubText(buf, pTag, len)
Stack.PushValue("local", pTag)
GetAttrAndText()
pTag = Stack.PopValue("local")
If param["class"] <> "" Then
target = "class"
Else
target = "rel"
EndIf
If param[target] = attr[target] Then
findNext = "False" ' found the tag
Else
tag = ""
EndIf
p = pTag + len
EndIf
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
pQ = Text.GetIndexOf(SQ + WQ, Text.GetSubText(tag, pEq + 1, 1))
If 0 < pQ Then
Q = Text.GetSubText(SQ + WQ, pQ, 1)
pQ = Text.GetIndexOf(Text.GetSubTextToEnd(tag, pEq + 2), Q)
If 0 < pQ Then
pQ = pEq + 2 + pQ - 1
txt = Text.GetSubText(tag, pEq + 2, pQ - pEq - 2)
ConvertText()
attr[Text.GetSubText(tag, pTag, pEq - pTag)] = txt
pTag = pQ + 2
EndIf
EndIf
Else
pTag = pEnd + 1
EndIf
EndWhile
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 Buf_GetLine
''' Buffer | Get line from buf
''' param p - pointer to buf
''' param buf - buffer
''' param len - length of the buffer
''' return line - current line
''' return p - updated pointer to next line in buf
If p <= len Then
nl = Text.GetIndexOf(Text.GetSubTextToEnd(buf, p), CR)
If 0 < nl Then
line = Text.GetSubText(buf, p, nl - 1)
p = p + nl
Else
line = Text.GetSubTextToEnd(buf, p)
p = len + 1
EndIf
If Text.GetSubText(buf, p, 1) = LF Then
p = p + 1
EndIf
EndIf
EndSub
Sub Buf_Init
''' Buffer | Initialization
''' param buf - buffer
''' return CR - carriage return
''' return LF - line feed
''' return len - length of text in buf
''' return p - pointer to buf
CR = Text.GetCharacter(13)
LF = Text.GetCharacter(10)
len = Text.GetLength(buf)
p = 1
EndSub
Sub Form_GetForm
''' Form | Get form from file
''' param formName - form file name
''' return form - array for the form
folder = Program.Directory
' The following line could be harmful and has been automatically commented.
' buf = File.ReadContents(folder + "/" + formName)
Buf_Init()
nForm = 0
While p <= len
Buf_GetLine()
Line_RemoveLeadingSpace()
If Text.StartsWith(line, "'") Then
func = Text.GetIndexOf(line, "func=")
If 0 < func Then
nForm = nForm + 1
form[nForm] = Text.GetSubTextToEnd(line, func)
EndIf
EndIf
EndWhile
EndSub
Sub Form_ShowForm
''' Form | Show form
''' param form - array of the form
''' param nForm - number of objects in the form
''' return gw - width of the graphics window
''' return gh - height of the graphics window
''' return id - array of ids in the form
For i = 1 To nForm
frm = form[i]
If frm["id"] <> "" Then
id[frm["id"]] = i
EndIf
If frm["func"] = "form" Then
' func=form;bg=LightGray;gx=10;gy=10;gw=598;gh=428;title=Sample 0.5b;
If frm["bg"] <> "" Then
GraphicsWindow.BackgroundColor = frm["bg"]
EndIf
If frm["gx"] <> "" Then
GraphicsWindow.Left = frm["gx"]
EndIf
If frm["gx"] <> "" Then
GraphicsWindow.Top = frm["gy"]
EndIf
If frm["gw"] <> "" Then
GraphicsWindow.Width = frm["gw"]
EndIf
gw = GraphicsWindow.Width
If frm["gh"] <> "" Then
GraphicsWindow.Height = frm["gh"]
EndIf
gh = GraphicsWindow.Height
If frm["title"] <> "" Then
GraphicsWindow.Title = frm["title"]
EndIf
ElseIf frm["func"] = "text" Then
' func=text;text=Folder;x=10;y=15;bc=Black;fn=Segoe UI;fs=12;fb=True;fi=False;
' func=text;text=Filename;x=10;y=45;bc=Black;fn=Segoe UI;fs=12;fb=True;fi=False;
GraphicsWindow.FontName = frm["fn"]
GraphicsWindow.FontSize = frm["fs"]
GraphicsWindow.FontBold = frm["fb"]
GraphicsWindow.FontItalic = frm["fi"]
GraphicsWindow.BrushColor = frm["bc"]
frm["obj"] = Shapes.AddText(frm["text"])
Shapes.Move(frm["obj"], frm["x"], frm["y"])
ElseIf frm["func"] = "tbox" Then
' func=tbox;id=folder;x=70;y=12;width=460;height=22;bc=Black;fn=Segoe UI;fs=12;fb=True;fi=False;text=.;
' func=tbox;id=filename;x=70;y=42;width=140;height=22;bc=Black;fn=Segoe UI;fs=12;fb=True;fi=False;text=Form.sb;
GraphicsWindow.FontName = frm["fn"]
GraphicsWindow.FontSize = frm["fs"]
GraphicsWindow.FontBold = frm["fb"]
GraphicsWindow.FontItalic = frm["fi"]
GraphicsWindow.BrushColor = frm["bc"]
frm["obj"] = Controls.AddTextBox(frm["x"], frm["y"])
Controls.SetSize(frm["obj"], frm["width"], frm["height"])
Controls.SetTextBoxText(frm["obj"], frm["text"])
ElseIf frm["func"] = "btn" Then
' func=btn;caption=OK;x=220;y=40;width=28;height=26;bc=Black;fn=Segoe UI;fs=12;fb=True;fi=False;
GraphicsWindow.FontName = frm["fn"]
GraphicsWindow.FontSize = frm["fs"]
GraphicsWindow.FontBold = frm["fb"]
GraphicsWindow.FontItalic = frm["fi"]
GraphicsWindow.BrushColor = frm["bc"]
frm["obj"] = Controls.AddButton(frm["caption"], frm["x"], frm["y"])
Controls.SetSize(frm["obj"], frm["width"], frm["height"])
Controls.ButtonClicked = OnButtonClicked
ElseIf frm["func"] = "rect" Then
' func=rect;x=546;y=10;width=2;height=32;scale=2;pw=0;pc=Black;bc=#999999;
GraphicsWindow.PenWidth = frm["pw"]
GraphicsWindow.PenColor = frm["pc"]
GraphicsWindow.BrushColor = frm["bc"]
frm["obj"] = Shapes.AddRectangle(frm["width"], frm["height"])
Shapes.Move(frm["obj"], frm["x"], frm["y"])
ElseIf frm["func"] = "img" Then
' func=img;src=img/Form32.png;x=556;y=10;width=32;height=32;
img = ImageList.LoadImage(Program.Directory + "/" + frm["src"])
ix = ImageList.GetWidthOfImage(img)
iy = ImageList.GetHeightOfImage(img)
scaleX = frm["width"] / ix
scaleY = frm["height"] / iy
frm["obj"] = Shapes.AddImage(img)
Shapes.Move(frm["obj"], frm["x"] + (frm["width"] - ix) / 2, frm["y"] + (frm["height"] - iy) / 2)
Shapes.Zoom(frm["obj"], scaleX, scaleY)
ElseIf frm["func"] = "mtbox" Then
' func=mtbox;id=data;x=10;y=72;width=578;height=346;bc=Black;fn=Segoe UI;fs=12;fb=True;fi=False;
GraphicsWindow.FontName = frm["fn"]
GraphicsWindow.FontSize = frm["fs"]
GraphicsWindow.FontBold = frm["fb"]
GraphicsWindow.FontItalic = frm["fi"]
GraphicsWindow.BrushColor = frm["bc"]
frm["obj"] = Controls.AddMultiLineTextBox(frm["x"], frm["y"])
Controls.SetSize(frm["obj"], frm["width"], frm["height"])
Else
id[frm["id"]] = ""
EndIf
form[i] = frm
EndFor
EndSub
Sub OnButtonClicked
buttonClicked = "True"
EndSub
Sub Line_RemoveLeadingSpace
''' Line | Remove leading space
''' param line - to remove leading space
''' return line - the result
Stack.PushValue("local", p)
p = 1
While Text.GetSubText(line, p, 1) = " "
p = p + 1
EndWhile
line = Text.GetSubTextToEnd(line, p)
p = Stack.PopValue("local")
EndSub