Skip to content

Instantly share code, notes, and snippets.

@LI7XI
Last active January 25, 2021 00:53
Show Gist options
  • Save LI7XI/b333cfccd7afce69acdc10f1addadc5d to your computer and use it in GitHub Desktop.
Save LI7XI/b333cfccd7afce69acdc10f1addadc5d to your computer and use it in GitHub Desktop.
Pure Lua Configuration files Parser, Converts ini to Lua Tables

Hi! This is a Pure Lua Implementation to Convert .ini Configuration Files to lua Tables.

The Conversion Mainly Depends on String Pattern Match.

function MakeConfigTable(ConfigPath)
  local Config = {}
  local Section, Key, Value

  for l in io.lines(ConfigPath) do
    -- Nested Loops to Simulate Continue Statement
    for i = 0, 0 do -- Loop Once per Line

      -- Basically we are going to read every line
      -- if it starts with a Section or a Key
      -- we will store them into the table

      -- Skip Comments
      if l:match('^;') ~= nil then break end

      if l:match('^[[]') ~= nil then
        -- Extract the Section Name
        Section = l:match('^[[](.+)[]]$')

        -- Create a New Table for each Section
        Config[Section] = {}
      end

      if l:match('(.+)=') ~= nil then
        -- Extract Key and Value, using = as a Seperator
        Key, Value = l:match('(.+)=(.+)')

        -- Check if the Value is a Number, and Explicitly Convert it to an integer
        if tonumber(Value) ~= nil then
          Value = tonumber(Value)
        end
      
        -- Add Each Key and Value into its Section Table
        Config[Section][Key] = Value
      end

    end
  end -- Nested Loops End

  return Config
end

Also, Since we wont read Comments anyway, We can remove the Nested Loop:

function MakeConfigTable(ConfigPath)
  local Config = {}
  local Section, Key, Value

  for l in io.lines(ConfigPath) do
  -- Basically we are going to read every line
  -- if it starts with a Section or a Key
  -- we will Store them into the table

    if l:match('^[[]') ~= nil then
    -- Extract the Section Name
    Section = l:match('^[[](.+)[]]$')

    -- Create a New Table for each Section
    Config[Section] = {}
    end

    if l:match('(.+)=') ~= nil then
      -- Extract Key and Value, using = as a Seperator
      Key, Value = l:match('(.+)=(.+)')

      -- Check if the Value is a Number, and Explicitly Convert it to an integer
      if tonumber(Value) ~= nil then
        Value = tonumber(Value)
      end
      
      -- Add Each Key and Value into its Section Table
      Config[Section][Key] = Value
    end

  end -- Lines Loop End

  return Config
end

Usage

Lets say a config file contains the following:

[SectionName]
KeyName=Value
; Some Comment

You would do:

local MyConfig = MakeConfigTable('PathToConfig.ini')

--- will result in a table like:
{
  SectionName = {
    KeyName = Value
  }
}

--- so to access Section Keys:

local MyKey = MyConfig.SectionName.KeyName
print(MyKey) --> Value
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment