britzl / defold-richtext

Defold-RichText is a system to create styled text based on an HTML inspired markup language
MIT License
75 stars 12 forks source link

Macro tag to apply multiple sets of commonly used tags at once #64

Closed subsoap closed 2 years ago

subsoap commented 4 years ago

A macro tag can help people reduce typing / tagging when working on large projects with common sets of tags.

Input <macro=lotus>undying lotus</macro>

Ouput <action=particles:text_emitter_red><color=lotus_red>undying lotus</color></action>

subsoap commented 4 years ago

My first naive attempt at making a macro tag was like this

M.macros = {}

M.macros["lotus"] = {
    action = "particles:text_emitter_red",
    color = "lotus_red"
}
...
    elseif tag == "macro" then
        print("Macro!")
        -- settings.color = color.parse("red")
        -- settings.macro = true
        local macro = params

        -- M.macros[macro_example] = {
        --  tag = params,
        --  tag = params,
        -- }
        print("Before")
        pprint(settings)
        if M.macros[macro] then
            for k,v in pairs(M.macros[macro]) do
                if k == "macro" then
                    print("Parse: Using macros in macros is dangerous. I hope you know what you're doing.")
                end
                local meta_settings = parse_tag(k, v)
                for kk,vv in pairs(meta_settings) do
                    if type(vv) == "table" then
                        settings[kk] = settings[kk] or {}
                        for kkk,vvv in pairs(vv) do
                            settings[kk][kkk] = vvv
                        end
                    else
                        settings[kk] = vv
                    end
                end

            end
        end
        print("After")
        pprint(settings)
    end

But it doesn't work because it makes the rest of the parsing think tags were never opened or closed early? Which makes the effect of the macro take place on all of the text. Maybe combining the info like this is just a bad idea. 😇

subsoap commented 4 years ago

My current thinking is to just apply a macro=name to the word, and then after all of the words are generated go through them and apply the macro modifiers to each individual word with that macro=name active.

I think this won't respect complicated overlapping tags but at least in my use case I don't need that.

subsoap commented 4 years ago

Behold! Now I have this monstrosity! It appears to work, but it will not respect overlapping tags and will always give macro data priority. I pray that a proper version can be done. 😇

    -- apply macro settings
    for k,v in ipairs(all_words) do
        if v.macro then
            for kk,vv in pairs(M.macros[v.macro]) do

                if kk == "macro" then
                    print("Parse: Using macros in macros is dangerous. I hope you know what you're doing.")
                end

                local meta_settings = parse_tag(kk, vv)

                for meta_key, meta_value in pairs(meta_settings) do
                    if meta_key == "tags" then
                        all_words[k]["tags"][meta_key] = meta_value
                    else
                        if type(meta_value) == "table" then
                            all_words[k][meta_key] = all_words[k][meta_key] or {}
                            for table_key, table_value in pairs(meta_value) do
                                all_words[k][meta_key][table_key] = table_value
                            end
                        else
                            all_words[k][meta_key] = meta_value
                        end
                    end
                end

            end
        end 
    end

    return all_words
end
britzl commented 4 years ago

The macro suggestion is feeling a bit like a css system. It could be really useful but it requires some careful planning. I don't want RichText to become too complex.