Page 1 of 1

Use Macros in Strings

Posted: Sat Jul 30, 2011 10:23 pm
by Env
Here's a little utility library for parsing macro's within strings...

For example:

Parsing "The current directory is $(CurrentDirectory)." will return the full string, but will replace '$(CurrentDirectory)' with the macro's value.

stringMacro.pbi

Code: Select all

; ------------------------------------------------------------------------------------------
; Title:        String Macro Library
; Description:  Enables the use of Macros '$(Macro.Name)' in Strings.
; Revision:     2
; Author:       Michael R. King (mrking2910@gmail.com)
; Website:      http://littlebluefox.ucoz.com
; ------------------------------------------------------------------------------------------

; - Global Data -
Structure _scm_GlobalData
  Map stringEntry.s()
EndStructure

Global _scm_Global._scm_GlobalData

; - Check Key for Illegal Characters -
Procedure.a SCM_IsKeyLegal(Key.s)
  Protected.s sLegal, sChar
  Protected.l lChar
  sLegal = "abcdefghjiklmnopqrstuvwxyz0123456789." ; - Keep Lowercase
  For lChar = 1 To Len(Key)
    sChar = Mid(Key, lChar, 1)
    If FindString(sLegal, LCase(sChar), 0) = 0
      ProcedureReturn #False
    EndIf
  Next
  ProcedureReturn #True
EndProcedure

; - Format Key -
Procedure.s SCM_FormatKey(Key.s)
  If SCM_IsKeyLegal(Key)
    If Right(Key, 1) = "."
      Key = Left(Key, Len(Key) - 1)
    EndIf
    If Left(Key, 1) <> "."
      Key = "." + Key
    EndIf
  EndIf
  ProcedureReturn Key
EndProcedure

; - Add Element -
Procedure.a SCM_AddMacro(Key.s, Value.s)
  If SCM_IsKeyLegal(Key)
    Key = SCM_FormatKey(Key)
    AddMapElement(_scm_Global\stringEntry(), Key)
    _scm_Global\stringEntry(Key) = Value
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure

; - Get Element -
Procedure.s SCM_GetMacro(Key.s, DefaultValue.s = "")
  If SCM_IsKeyLegal(Key)
    Key = SCM_FormatKey(Key)
    If FindMapElement(_scm_Global\stringEntry(), Key)
      ProcedureReturn _scm_Global\stringEntry(Key)
    EndIf
  EndIf
  ProcedureReturn DefaultValue
EndProcedure

; - Parse String -
Procedure.s SCM_Parse(String.s)
  Protected.s sOutput, sChunk, sKey, sValue
  Protected.l lSPos, lEPos
  sOutput = String
  Repeat
    lSPos = FindString(String, "$(", lEPos)
    If lSPos
      lEPos = FindString(String, ")", lSPos)
      If lEPos
        sChunk = Mid(String, lSPos, (lEPos - lSPos) + 1)
        sKey = RemoveString(sChunk, "$(")
        sKey = RemoveString(sKey, ")")
        sValue = SCM_GetMacro(sKey, sChunk)
        sOutput = ReplaceString(sOutput, sChunk, sValue)
      EndIf
    Else
      Break
    EndIf
  ForEver
  ProcedureReturn sOutput 
EndProcedure

; - Remove Key -
Procedure.a SCM_RemoveMacro(Key.s)
  If SCM_IsKeyLegal(Key)
    Key = SCM_FormatKey(Key)
    If FindMapElement(_scm_Global\stringEntry(), Key)
      DeleteMapElement(_scm_Global\stringEntry(), Key)
      ProcedureReturn #True
    EndIf
  EndIf
  ProcedureReturn #False
EndProcedure

; - Remove All Keys -
Procedure SCM_RemoveAll()
  ClearMap(_scm_Global\stringEntry())
EndProcedure

; - Remove Elements in Group -
Procedure.l SCM_RemoveGroup(KeyGroup.s)
  Protected.l lPurged
  NewList sPurgeList.s()
  If SCM_IsKeyLegal(KeyGroup)
    If Left(KeyGroup, 1) <> "."
      KeyGroup = "." + KeyGroup
    EndIf
    If Right(KeyGroup, 1) <> "."
      KeyGroup + "."
    EndIf
    ResetMap(_scm_Global\stringEntry())
    While NextMapElement(_scm_Global\stringEntry())
      If Left(MapKey(_scm_Global\stringEntry()), Len(KeyGroup)) = KeyGroup
        AddElement(sPurgeList())
        sPurgeList() = MapKey(_scm_Global\stringEntry())
      EndIf
    Wend
    lPurged = ListSize(sPurgeList())
    ForEach sPurgeList()
      DeleteMapElement(_scm_Global\stringEntry(), sPurgeList())
    Next
    FreeList(sPurgeList())
    ProcedureReturn lPurged
  EndIf
  ProcedureReturn -1
EndProcedure
Usage Example:

Code: Select all

; - Add Some Macros -
SCM_AddMacro("CWD", GetCurrentDirectory())
SCM_AddMacro("User.Name", "PB User")
SCM_AddMacro("User.Age", "23")

; - Output Results -
Debug SCM_Parse("Hello, $(User.Name). You are $(User.Age) years old. The current directory is: $(CWD)")

; - Remove Macros with "User" as the prefix -
SCM_RemoveGroup("User")

; - Output Results -
Debug SCM_Parse("Hello, $(User.Name). You are $(User.Age) years old. The current directory is: $(CWD)")


Updates
  • Function Added: SCM_RemoveAll()

For any new revisions, and function references visit Here

Re: Use Macros in Strings

Posted: Sat Jul 30, 2011 10:54 pm
by luis
Can I say I like it ?

I like it :)

Re: Use Macros in Strings

Posted: Sat Jul 30, 2011 11:07 pm
by c4s
Good idea, thank you!

Re: Use Macros in Strings

Posted: Sun Jul 31, 2011 10:27 am
by Env
Thanks both :)

New revision with the function 'SCM_RemoveAll()' added.

Re: Use Macros in Strings

Posted: Sun Jul 31, 2011 5:43 pm
by Kwai chang caine
Good, thanks for sharing 8)