Use Macros in Strings

Share your advanced PureBasic knowledge/code with the community.
Env
Enthusiast
Enthusiast
Posts: 151
Joined: Tue Apr 27, 2010 3:20 pm
Location: Wales, United Kingdom

Use Macros in Strings

Post 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
Last edited by Env on Sun Jul 31, 2011 10:26 am, edited 1 time in total.
Thanks!
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Use Macros in Strings

Post by luis »

Can I say I like it ?

I like it :)
"Have you tried turning it off and on again ?"
c4s
Addict
Addict
Posts: 1981
Joined: Thu Nov 01, 2007 5:37 pm
Location: Germany

Re: Use Macros in Strings

Post by c4s »

Good idea, thank you!
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
Env
Enthusiast
Enthusiast
Posts: 151
Joined: Tue Apr 27, 2010 3:20 pm
Location: Wales, United Kingdom

Re: Use Macros in Strings

Post by Env »

Thanks both :)

New revision with the function 'SCM_RemoveAll()' added.
Last edited by Env on Sun Jul 31, 2011 10:19 pm, edited 1 time in total.
Thanks!
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Use Macros in Strings

Post by Kwai chang caine »

Good, thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
Post Reply