Dim token As String
Dim currElement As String
LoadCSS = True
' Open the file
Dim iFileNum As Integer
iFileNum = FreeFile
Open f For Binary As #iFileNum
' Empty the style array.
ClearStyleList
' The premise behind this function:
' 1. You want to track four different states in this
' loop. What you read determines what state you're
' in. The initial state is ReadingTag.
' 2. Read a character at a time, constructing a token.
' 3. When you read a character that changes the state,
' close out the previous state by saving the token(s)
' you're holding onto, moving to the new state.
' 4. You're done when you reach the end of the file.
Dim ch As String * 1
' Holds the character you read
Dim state As ParserState
' Current parsing state
state = ReadingTag
' Set initial parsing state
iTagCount = 1
' Initialize tag counter
' Do a priming read.
Get #iFileNum, , ch
' Keep reading and parsing until we reach the end of
' the file.
Do While Not EOF(iFileNum)
' Decide what to do based on the character you read
' concentrating on the characters that separate parts
' of the style. These characters compose the subject
' of the cases.
Select Case UCase(ch)
Case vbCr
' Ignore it
Case vbLf
' Ignore it
Case Chr(9) ' Tab
' Ignore this too.
Case "{"
If state = ReadingTag Then
' Store the tag
StyleList(iTagCount).Tag = Trim(UCase(token))
' Clear the token now that it has been used.
token = "
End If
If state = ReadingClass Then
' Store the class
StyleList(iTagCount).TagClass = Trim(token)
' Clear the token now that it has been used.
token = "
End If
' Move to new state.
state = ReadingElement
Case "}"
If state = ReadingStyle Then
' Store the style with the current element.
InsertStyle Trim(token), currElement
' Clear the token and the current tag, now that
' they have been used.
token = "
currElement = "
End If
' In the following situation:
' A
' {
' font-family: Tahoma;
' }
'
' The semi-colon at the end of the style moves you
' to the ReadingElement state. You immediately
' read a closing brace, so there is no element to
' read. All you really need to do is switch state
' to ReadingTag.
' Move to new state
state = ReadingTag
' Increment the tag count.
iTagCount = iTagCount + 1
Case "."
If state = ReadingTag Then
' Store the tag
StyleList(iTagCount).Tag = Trim(UCase(token))
' Move to new state
state = ReadingClass
' Clear the token now that it has been used.
token = "
End If
' You can have decimals as part of a style, so:
If state = ReadingStyle Then
token = token & ch
End If
Case ";"
If state = ReadingStyle Then
' Store the style with the current element.
InsertStyle Trim(token), currElement
' Clear the token and the current tag, now that
' they have been used.
token = "
currElement = "
End If
' Move to a new state.
state = ReadingElement
Case ":"
If state = ReadingElement Then
' Save the element part of this style.
currElement = Trim(LCase(token))
' Move to a new state.
state = ReadingStyle
' Clear the token now that it has been used.
token = "
End If
' If the document has pseudo classes, just "sort
' of" handle it, adding it to the token in case
' you add support for it later, but it won't blow
' up the loading routine for now. This allows the
' user to enter a pseudo class outside this
' program manually, and it will be loaded and
' saved correctly. However, the user will not be
' able to edit the tag in the program.
If state = ReadingTag Then
token = token & ch
End If
Case Else
' You've accounted for all the special characters,
' good and bad. Anything else: Add it to the token
' as you read it.
token = token & ch
End Select
' Get next character
Get #iFileNum, , ch
Loop
' Adjust the tag counter to make it correct.
iTagCount = iTagCount - 1
' Close the file
Close #iFileNum
|