Skip to content

Latest commit

 

History

History
803 lines (655 loc) · 31.3 KB

File metadata and controls

803 lines (655 loc) · 31.3 KB

This file lists all the individual Lua functions, be they onFilter and onGroup functions, or other background functions used in the global Lua Configuration or elsewhere, that I've written and the situations they are suited for. They have been grouped according to function.

Helper Functions

This section lists all those functions that help make understanding Simpletask (ST) easier. They are useful in understanding the input fields for in-built functions available from ST, which are listed here. They can also be used to understand some lua function return values as well.

-- General Syntax:

function onGroup(t, f, e)
    
    -- Some pre_processing if needed
    return parameter_value
end

This generic script will then group all tasks according to the return value, which will be the parameter in question. For example, if you wish to know what f.due is, simply use:

function onGroup(t, f, e)
    return f.due
end

This will group the tasks according to the internal representation of the due date, which is a large number (~10 to 11 digits) (representing the due date in seconds).

Some examples use os.time(). To understand what os.time() returns, instead of f.due, use os.time() in the above example. And to know exactly what the due or threshold or creation dates and times are for the corresponding internal representations stored in f.due, etc., use:

function onGroup(t, f, e)
    tim = f.due     --or os.time(), f.threshold, etc.
    return os.date("%c", tim)
end

Doing this will show that all due and threshold dates exceed os.time() at 00:00 hrs of the date listed by the user.

Similarly, if you wish to know exactly what due date ranges, and hence, tasks, will be covered by my time bound filters (listed subsequently), use:

function onGroup(t, f, e)
    
    tim = os.time()
    tim_d = tim-86400
    tim_w = tim+518400
    tim_m = tim+2505600 
    
    
    gr_name = ("Current Time: "..os.date("%c", tim).."\n\nOverdue task before (>=f.due): "..os.date("%c",tim_d).."\nToday task after (<f.due): "..os.date("%c",tim_d).."\nToday task before (>=f.due): "..os.date("%c",tim).."\nThis week task after (<f.due): "..os.date("%c",tim).."\nThis week task before (>=f.due): "..os.date("%c",tim_w).."\nThis month task after (<f.due): "..os.date("%c",tim_w).."\nThis month task before (>=f.due): "..os.date("%c",tim_m).."\nSomeday task after (<f.due): "..os.date("%c",tim_m))
    
    return gr_name
end
    

If you are testing with a todo list of few tasks, or just testing on a single task using the Test option in the script window, you can use the toast() function as well. This is particularly useful in understanding tables generated by Simpletask: f.lists and f.tags and the extensions (e in (t, f, e)). This is explored below.

Understanding Tables Generated by Simpletask

With a test task x 2017-02-02 (A) 2016-12-15 This is an example task with all features. @Testing @@Understanding_ST +Help ++Manual t:2016-12-15 due:2016-12-22 rec:+1d h:1, running:

function onFilter(t, f, e)
    
    for k, v in pairs(f.lists) do 
        toast_string = tostring(k)..": "..tostring(v)   -- ".." is for string concatenation in Lua
        toast(toast_string)
    end
end

will show all the keys and associated field values of the table f.lists (see the [Notes on Simpletask and Lua](Notes on Simpletask and Lua.md) file for details on keys and values).

Similarly, replacing f.lists in for k, v in pairs(f.lists) do with f.tags or e show the key:value pairs in the tags and extension tables respectively which are associated with the task. (This script was written because the Simpletask Lua Help manual does not describe exactly what the extensions are, and I wanted to find them out. I later discovered that the main help page does mention that due, h, etc. are the extensions and I did not realise it. It is still fun to watch the extensions being listed however. 😄)

The Lua Config File

This is the Lua Config file I have at present. The functions defined are heavily commented, so no separate descriptions are provided.

---------------------------------- ---------------------------------- ---------------------------------- ----------------------------------
-- BACKGROUND FUNCTIONS Needed for the functions defined under WELCOME and GROUPING AND FILTERING sections
---------------------------------- ---------------------------------- ---------------------------------- ----------------------------------

function tablelength(T)
		--[[Returns the number of keys in the table.
			Source: http://stackoverflow.com/questions/2705793/how-to-get-number-of-entries-in-a-lua-table/2705804#2705804]]

	local count = 0
	for _ in pairs(T) do count = count + 1 end
	return count
end

---------------------------------- ---------------------------------- ---------------------------------- ----------------------------------

function sort_and_concatenate_keys(T)
    --[[Sort keys and convert to a multiline string.
        Sorting keys in table - Source: https://www.lua.org/pil/19.3.html]]

    a = {}            -- New table
    key_string = ""   -- Empty string

    for n in pairs(T) do table.insert(a, n) end
        -- Fill new table "a" with keys from "T" as values in "a"

    table.sort(a)    -- Sort keys

    for _, n in ipairs(a) do key_string = key_string..n..'\n' end
        -- Append sorted keys in empty string, separated by a newline
        
    key_string = key_string:sub(1, -2)	-- Delete extra newline character

    return key_string
end

---------------------------------- ---------------------------------- ---------------------------------- ----------------------------------
-- WELCOME MESSAGE: Announce date and a random message from table. Insert messages below or modify existing ones as shown.
---------------------------------- ---------------------------------- ---------------------------------- ----------------------------------

welc_msgs = {}
    -- Table constructor. Do not modify. Insert new messages below using syntax: welc_msgs[#] = "message"

welc_msgs[1] = "Hello!"
welc_msgs[2] = "Seize the day!"
welc_msgs[3] = "Carpe diem!"
welc_msgs[4] = "Today is your day!"
welc_msgs[5] = "Make the day count!"
welc_msgs[6] = "Make the night count!"

msg_no = math.random (1, tablelength(welc_msgs))
toast('Today is: '..os.date("%A, %B %d, %Y.", os.time ())..'\n\n'..welc_msgs[msg_no])
toast('Today is: '..os.date("%A, %B %d, %Y.", os.time ())..'\n\n'..welc_msgs[msg_no])
toast('Today is: '..os.date("%A, %B %d, %Y.", os.time ())..'\n\n'..welc_msgs[msg_no])
    -- Welcome message. Runs every time Simpletask starts afresh or the lua configuration script is run. Repeated thrice for persistence.

---------------------------------- ---------------------------------- ---------------------------------- ----------------------------------
-- GROUPING AND FILTERING FUNCTIONS: Group by due date or list or tag
---------------------------------- ---------------------------------- ---------------------------------- ----------------------------------

function multigroup_by_list_or_tag(t, f, e, parameter)
	-- Group tasks by list or tag, and separately classify tasks with multiple lists/tags.

    if parameter == 'tags' then
        tbl = f.tags
        
    else tbl = f.lists
    end
    
    L = tablelength(tbl)
    
    if L == 0 then
        return "Unsorted"	-- No list/tag. Custom label. Adapted from built-in example code.
    
    elseif L == 1 then
        return next(tbl)	-- One list/tag. Return that value. Adapted from built-in example code.
    
    else 
        return sort_and_concatenate_keys(tbl)	-- Multiple lists/tags. Group under multiline label.
    end
end

---------------------------------- ---------------------------------- ---------------------------------- ----------------------------------

function filter_by_date(t, f, e, time_period, date_to_be_used)
	--[[Filter tasks by date. 
	    Valid ranges for time_period are: 'over' (already past), 'today', 'this week' (next 6 days after today), 
	    'this month' (next 3 weeks after this week), and 'someday' (sometime after the next 30 days, or no due date set)
		Note that "this week" and "this month" are moving windows. They are calculated from the current day. 
		Not from the Sunday, or the 1st of that month.
		
	    Valid options for date_to_be_used are: 'creation', 'completion', 'due', 'threshold']]

    local curr_time, day, week, month = os.time(), 86400, 518400, 2505600
		--[[As f.due, os.time(), etc. return values in seconds:
				86400: Number of seconds in a day
				518400: Number of seconds in six days
				2505600: Number of seconds in 29 days (assuming a 30 day month)]]
				
    if date_to_be_used == 'creation' then
        use_date = f.createdate
	
    elseif date_to_be_used == 'completion' then
        use_date = f.completiondate
	
    elseif date_to_be_used == 'due' then
        use_date = f.due
	
    elseif date_to_be_used == 'threshold' then
        use_date = f.threshold
	
    else
        return false  -- Invalid date option. So no tasks to display.
    end
    
    if time_period == 'over' then
        if use_date ~= nil then
            return curr_time-day >= use_date
        end
        return false;    -- No due/threshold/creation/completion date specified. So do not display the task.
        
    elseif time_period == 'today' then
        if use_date ~= nil then
            return curr_time >= use_date and curr_time-day < use_date
        end
        return false;
        
    elseif time_period == 'this week' then
        if use_date ~= nil then
            return curr_time < use_date and curr_time+week >= use_date
        end
        return false;
        
    elseif time_period == 'this month' then
        if use_date ~= nil then
            return curr_time+week < use_date and curr_time+month >= use_date
        end
        return false;
        
    elseif time_period == 'someday' then
        return curr_time+month < use_date or use_date == nil
        
    else
        return false     -- No valid time range given. So no tasks to display.
    end
end

---------------------------------- ---------------------------------- ---------------------------------- ----------------------------------

function group_by_date(t, f, e, date_to_be_used)
	--[[Group tasks by date. 
	    Output ranges are: 'Already Overdue!!!' (etc, depending on date used), '...Today', 
	    '...in the rest of this Week' (next 6 days after today), '...in the remainder of this Month' (next 3 weeks after this week), 
		and 'Can Afford to Procrastinate on these for now!' (sometime after the next 30 days, or no specified date set)
		
	    Valid options for date_to_be_used are: 'creation', 'due', 'threshold'
	    Completion date is not used here as completed tasks are generally archived or deleted on a weekly basis.]]

    local curr_time, day, week, month = os.time(), 86400, 518400, 2505600	-- See above for details.
    
    if date_to_be_used == 'creation' then
        use_date = f.createdate
	overdue_string = "Creation Date is in the past"
	leading_string = "Created "
	someday_string = "Creation Date more than 30 days from now"
	no_date_string = "No Creation Date specified"
	
    elseif date_to_be_used == 'due' then
        use_date = f.due
	overdue_string = "Already Overdue!!!"
	leading_string = "Due "
	someday_string = "Can Afford to Procrastinate on these for now!"
	no_date_string = "Can Afford to Procrastinate on these for now!"
	
    elseif date_to_be_used == 'threshold' then
        use_date = f.threshold
	overdue_string = "Threshold Date is in the past"
	leading_string = "Started "
	someday_string = "Threshold Date more than 30 days from now"
	no_date_string = "No Threshold Date specified"
	
    else
        use_date = f.due
	overdue_string = "Invalid Date Option. Grouping by due date as default."
	leading_string = "Invalid Date Option. Grouping by due date as default."
	someday_string = "Invalid Date Option. Grouping by due date as default."
	no_date_string = "Invalid Date Option. Grouping by due date as default."
	    -- Invalid date option. Inform user of it and group by due date.
    end
    
    if f.completed == false then
        if use_date ~= nil then
            if curr_time-day >= use_date then
                return overdue_string
                
            elseif curr_time >= use_date and curr_time-day < use_date then
                return leading_string.."Today: "..os.date("%A, %B %d, %Y", curr_time)
                
            elseif curr_time < use_date and curr_time+week >= use_date then
                return leading_string.."in the rest of this Week"
                
            elseif curr_time+week < use_date and curr_time+month >= use_date then
                return leading_string.."in the remainder of this Month"
            
            else
                return someday_string  -- use_date greater than 30 days from today
	    end
	else
	    return no_date_string  -- no use_date present
	end
    else
	return "Completed Tasks"    -- f.completed is true implies task is completed,
    end
end

---------------------------------- ---------------------------------- ---------------------------------- ----------------------------------

onFilter and onGroup Functions

Once the above code is successfully imported and run (import it twice, if you are not pasting it, due to buggy behaviour), the following functions can be used in filter scripts:

Show only not-completed tasks

function onFilter(t, f, e)
    return not f.completed
end

-- OR

function onFilter(t, f, e)
    return f.completed == false
end

Show only completed tasks

function onFilter(t, f, e)
    return f.completed
end

-- OR

function onFilter(t, f, e)
    return f.completed == true
end

(The option to show completed tasks must be checked in the OTHER tab.)

Show only hidden tasks

function onFilter(t, f, e)
    return e.h ~= nil
end

(The option to show hidden tasks must be checked in the OTHER tab.)

Show only recurring tasks

function onFilter(t, f, e)
    return e.rec ~= nil
end

-- OR

function onFilter(t, f, e)
    return f.recurrence ~= nil
end

Group tasks by list or tag, even those with multiple of them in a single task. Such tasks are classified separately.

-- Group by lists

function onGroup(t, f, e)
    return multigroup_by_list_or_tag(t, f, e)
end


-- Group by tags

function onGroup(t, f, e)
    return multigroup_by_list_or_tag(t, f, e, "tags")
end

This was written primarily becase Simpletask does not handle multiple lists or tags assigned to the same task well.

Note that in order to also sort the tasks properly once they are grouped this way, it is advisable to have as the first two entries of the sort order: V Completed followed by V By List if grouping by multiple lists and V Completed followed by V By Tag if grouping by multiple tags. If you select not to display completed tasks (from the OTHER tab), then the first entry needn't be V Completed.

Filter tasks by due date

-- Filter by due date: Overdue

function onFilter(t, f, e)
    return filter_by_date(t, f, e, "over", "due")
end


-- Filter by due date: Due today

function onFilter(t, f, e)
    return filter_by_date(t, f, e, "today", "due")
end


-- Filter by due date: Due in the next seven days, excluding today

function onFilter(t, f, e)
    return filter_by_date(t, f, e, "this week", "due")
end


-- Filter by due date: Due in the next thirty days, excluding this week

function onFilter(t, f, e)
    return filter_by_date(t, f, e, "this month", "due")
end


-- Filter by due date: Due after the next 30 days (including today), or no due date set

function onFilter(t, f, e)
    return filter_by_date(t, f, e, "someday", "due")
end

Similarly, if you wish to filter by threshold date or completion date or creation date, use "threshold", "completion", or "creation" respectively in pace of due in the scripts above.

An earlier iteration of this function filtered out completed tasks. If you wish to display only uncompleted tasks, the scripts above need to be modified to:

function onFilter(t, f, e)
    return filter_by_date(t, f, e, <relevant time period option>, <relevant date option>) and f.completed == false
        -- ..and f.completed == true for showing only completed tasks
end

In case of hiding completed tasks, you could also use the function filter_by_date while unchecking the option to show completed tasks in the OTHER tab. Save it as a filter for quick access. (See [here](Individual Functions for Filtering and Grouping.md#saved-filters) for more on this.)

Group tasks by due date (as shown in filters defined in the previous section)

This results in something similar to the Any.Do layout, only, a lot more flexible, as you can define your own categories. If used in conjunction with one of the filter functions from the preceeding section, they would provide a header to the filter when opened in the main window.

If there is no filter, the first two entries in the sort order must be V Completed followed by V By Due Date in order to make the entries legible to follow.

function onGroup(t, f, e)
    return group_by_date(t, f, e, "due")
end

You can group by threshold or creation dates by using "threshold" and "creation" respectively instead of "due".

Note that onGroupfunction return values only show up when you open Simpletask. Not in widgets, as of now.

Saved Filters

Tasks can be filtered and grouped using a combination of Lua scripts and conventional Simpletask filters and other options (literally OTHER options). Any such combination can be saved by using the right drawer. Once saved, all of the saved settings are applied when you select the saved filter. The saved filters can be exported and used across devices. For more details, see Tips.md.

Listed below is my exported saved filters list. To use, copy this into the Simpletask data directory in a text file named saved_filters.txt and import using the right drawer.

{
  "10. Hidden (All)": {
    "TITLE": "10. Hidden (All)",
    "CONTEXTS": "",
    "CONTEXTSnot": false,
    "PROJECTS": "",
    "PROJECTSnot": false,
    "PRIORITIES": "",
    "PRIORITIESnot": false,
    "SORTS": "+!completed\n+!by_completion_date\n+!by_due_date\n+!by_context\n+!by_prio\n+!by_project\n+!by_threshold_date\n+!alphabetical\n+!by_creation_date\n+!in_future\n+!file_order",
    "HIDECOMPLETED": false,
    "HIDEFUTURE": false,
    "HIDELISTS": false,
    "HIDETAGS": false,
    "HIDECREATEDATE": false,
    "HIDEHIDDEN": false,
    "CREATEISTHRESHOLD": false,
    "LUASCRIPT": "function onFilter(t, f, e)\n    return e.h ~= nil\nend\n",
    "USE_SCRIPT": true,
    "LUASCRIPT_TEST_TASK": "",
    "query": ""
  },
  "01. Overdue (No Health)": {
    "TITLE": "01. Overdue (No Health)",
    "CONTEXTS": "Health",
    "CONTEXTSnot": true,
    "PROJECTS": "",
    "PROJECTSnot": false,
    "PRIORITIES": "",
    "PRIORITIESnot": false,
    "SORTS": "+!completed\n+!by_due_date\n+!by_context\n+!by_prio\n+!by_project\n+!by_threshold_date\n+!alphabetical\n+!by_creation_date\n+!in_future\n+!by_completion_date\n+!file_order",
    "HIDECOMPLETED": true,
    "HIDEFUTURE": false,
    "HIDELISTS": false,
    "HIDETAGS": false,
    "HIDECREATEDATE": false,
    "HIDEHIDDEN": true,
    "CREATEISTHRESHOLD": false,
    "LUASCRIPT": "function onFilter(t, f, e)\n    return filter_by_date(t, f, e, \"over\", \"due\")\nend\n\nfunction onGroup(t, f, e)\n    return group_by_date(t, f, e, \"due\")\nend",
    "USE_SCRIPT": true,
    "LUASCRIPT_TEST_TASK": "",
    "query": ""
  },
  "06. Health (Pending: Overdue and Today, Completed: Today)": {
    "TITLE": "06. Health (Pending: Overdue and Today, Completed: Today)",
    "CONTEXTS": "Health",
    "CONTEXTSnot": false,
    "PROJECTS": "",
    "PROJECTSnot": false,
    "PRIORITIES": "",
    "PRIORITIESnot": false,
    "SORTS": "+!completed\n+!by_due_date\n+!by_context\n+!by_prio\n+!by_project\n+!by_threshold_date\n+!alphabetical\n+!by_creation_date\n+!in_future\n+!by_completion_date\n+!file_order",
    "HIDECOMPLETED": false,
    "HIDEFUTURE": true,
    "HIDELISTS": false,
    "HIDETAGS": false,
    "HIDECREATEDATE": false,
    "HIDEHIDDEN": true,
    "CREATEISTHRESHOLD": false,
    "LUASCRIPT": "function onFilter(t, f, e)\n    if f.completed ==  true then\n        return filter_by_date(t, f, e, \"today\", \"completion\")\n                -- Show tasks completed only today\n                -- (to undo in case any were marked completed by mistake)\n    else\n        return true  -- Show all uncompleted tasks\n    end\nend\n\nfunction onGroup(t, f, e)\n    return group_by_date(t, f, e, \"due\")\nend",
    "USE_SCRIPT": true,
    "LUASCRIPT_TEST_TASK": "",
    "query": ""
  },
  "13. Any.do Layout - Pending Tasks only (No Health)": {
    "TITLE": "13. Any.do Layout - Pending Tasks only (No Health)",
    "CONTEXTS": "Health",
    "CONTEXTSnot": true,
    "PROJECTS": "",
    "PROJECTSnot": false,
    "PRIORITIES": "",
    "PRIORITIESnot": false,
    "SORTS": "+!completed\n+!by_due_date\n+!by_context\n+!by_prio\n+!by_project\n+!by_threshold_date\n+!alphabetical\n+!by_creation_date\n+!in_future\n+!by_completion_date\n+!file_order",
    "HIDECOMPLETED": true,
    "HIDEFUTURE": false,
    "HIDELISTS": false,
    "HIDETAGS": false,
    "HIDECREATEDATE": false,
    "HIDEHIDDEN": true,
    "CREATEISTHRESHOLD": false,
    "LUASCRIPT": "function onGroup(t, f, e)\n    return group_by_date(t, f, e, \"due\")\nend",
    "USE_SCRIPT": true,
    "LUASCRIPT_TEST_TASK": "",
    "query": ""
  },
  "05. Someday (No Health)": {
    "TITLE": "05. Someday (No Health)",
    "CONTEXTS": "Health",
    "CONTEXTSnot": true,
    "PROJECTS": "",
    "PROJECTSnot": false,
    "PRIORITIES": "",
    "PRIORITIESnot": false,
    "SORTS": "+!completed\n+!by_due_date\n+!by_context\n+!by_prio\n+!by_project\n+!by_threshold_date\n+!alphabetical\n+!by_creation_date\n+!in_future\n+!by_completion_date\n+!file_order",
    "HIDECOMPLETED": true,
    "HIDEFUTURE": false,
    "HIDELISTS": false,
    "HIDETAGS": false,
    "HIDECREATEDATE": false,
    "HIDEHIDDEN": true,
    "CREATEISTHRESHOLD": false,
    "LUASCRIPT": "function onFilter(t, f, e)\n    return filter_by_date(t, f, e, \"someday\", \"due\")\nend\n\nfunction onGroup(t, f, e)\n    return group_by_date(t, f, e, \"due\")\nend",
    "USE_SCRIPT": true,
    "LUASCRIPT_TEST_TASK": "",
    "query": ""
  },
  "03. Rest of this Week (No Health)": {
    "TITLE": "03. Rest of this Week (No Health)",
    "CONTEXTS": "Health",
    "CONTEXTSnot": true,
    "PROJECTS": "",
    "PROJECTSnot": false,
    "PRIORITIES": "",
    "PRIORITIESnot": false,
    "SORTS": "+!completed\n+!by_due_date\n+!by_context\n+!by_prio\n+!by_project\n+!by_threshold_date\n+!alphabetical\n+!by_creation_date\n+!in_future\n+!by_completion_date\n+!file_order",
    "HIDECOMPLETED": true,
    "HIDEFUTURE": false,
    "HIDELISTS": false,
    "HIDETAGS": false,
    "HIDECREATEDATE": false,
    "HIDEHIDDEN": true,
    "CREATEISTHRESHOLD": false,
    "LUASCRIPT": "function onFilter(t, f, e)\n    return filter_by_date(t, f, e, \"this week\", \"due\")\nend\n\nfunction onGroup(t, f, e)\n    return group_by_date(t, f, e, \"due\")\nend",
    "USE_SCRIPT": true,
    "LUASCRIPT_TEST_TASK": "",
    "query": ""
  },
  "04. Rest of this Month (No Health)": {
    "TITLE": "04. Rest of this Month (No Health)",
    "CONTEXTS": "Health",
    "CONTEXTSnot": true,
    "PROJECTS": "",
    "PROJECTSnot": false,
    "PRIORITIES": "",
    "PRIORITIESnot": false,
    "SORTS": "+!completed\n+!by_due_date\n+!by_context\n+!by_prio\n+!by_project\n+!by_threshold_date\n+!alphabetical\n+!by_creation_date\n+!in_future\n+!by_completion_date\n+!file_order",
    "HIDECOMPLETED": true,
    "HIDEFUTURE": false,
    "HIDELISTS": false,
    "HIDETAGS": false,
    "HIDECREATEDATE": false,
    "HIDEHIDDEN": true,
    "CREATEISTHRESHOLD": false,
    "LUASCRIPT": "function onFilter(t, f, e)\n    return filter_by_date(t, f, e, \"this month\", \"due\")\nend\n\nfunction onGroup(t, f, e)\n    return group_by_date(t, f, e, \"due\")\nend",
    "USE_SCRIPT": true,
    "LUASCRIPT_TEST_TASK": "",
    "query": ""
  },
  "14. Simpletask Default (With Test Script)": {
    "TITLE": "14. Simpletask Default (With Test Script)",
    "CONTEXTS": "",
    "CONTEXTSnot": false,
    "PROJECTS": "",
    "PROJECTSnot": false,
    "PRIORITIES": "",
    "PRIORITIESnot": false,
    "SORTS": "+!completed\n+!by_context\n+!by_prio\n+!by_project\n+!by_due_date\n+!by_threshold_date\n+!alphabetical\n+!by_creation_date\n+!in_future\n+!by_completion_date\n+!file_order",
    "HIDECOMPLETED": false,
    "HIDEFUTURE": false,
    "HIDELISTS": false,
    "HIDETAGS": false,
    "HIDECREATEDATE": false,
    "HIDEHIDDEN": true,
    "CREATEISTHRESHOLD": false,
    "LUASCRIPT": "",
    "USE_SCRIPT": false,
    "LUASCRIPT_TEST_TASK": "x 2017-02-02 (A) 2016-12-15 This is an example task with all features. @Testing @@Understanding_ST +Help ++Manual t:2016-12-15 due:2016-12-22 rec:+1d h:1",
    "query": ""
  },
  "15. Todo.txt File Order": {
    "TITLE": "15. Todo.txt File Order",
    "CONTEXTS": "",
    "CONTEXTSnot": false,
    "PROJECTS": "",
    "PROJECTSnot": false,
    "PRIORITIES": "",
    "PRIORITIESnot": false,
    "SORTS": "+!file_order\n+!completed\n+!by_context\n+!by_prio\n+!by_project\n+!by_due_date\n+!by_threshold_date\n+!alphabetical\n+!by_creation_date\n+!in_future\n+!by_completion_date",
    "HIDECOMPLETED": false,
    "HIDEFUTURE": false,
    "HIDELISTS": false,
    "HIDETAGS": false,
    "HIDECREATEDATE": false,
    "HIDEHIDDEN": true,
    "CREATEISTHRESHOLD": false,
    "LUASCRIPT": "",
    "USE_SCRIPT": false,
    "LUASCRIPT_TEST_TASK": "x 2017-02-02 (A) 2016-12-15 This is an example task with all features. @Testing @@Understanding_ST +Help ++Manual t:2016-12-15 due:2016-12-22 rec:+1d h:1",
    "query": ""
  },
  "08. Completed (Recurring Only)": {
    "TITLE": "08. Completed (Recurring Only)",
    "CONTEXTS": "",
    "CONTEXTSnot": false,
    "PROJECTS": "",
    "PROJECTSnot": false,
    "PRIORITIES": "",
    "PRIORITIESnot": false,
    "SORTS": "+!completed\n+!by_completion_date\n+!by_due_date\n+!by_context\n+!by_prio\n+!by_project\n+!by_threshold_date\n+!alphabetical\n+!by_creation_date\n+!in_future\n+!file_order",
    "HIDECOMPLETED": false,
    "HIDEFUTURE": false,
    "HIDELISTS": false,
    "HIDETAGS": false,
    "HIDECREATEDATE": false,
    "HIDEHIDDEN": true,
    "CREATEISTHRESHOLD": false,
    "LUASCRIPT": "function onFilter(t, f, e)\n    return e.rec ~= nil and f.completed\nend\n",
    "USE_SCRIPT": true,
    "LUASCRIPT_TEST_TASK": "",
    "query": ""
  },
  "00. Welcome Message": {
    "TITLE": "00. Welcome Message",
    "CONTEXTS": "",
    "CONTEXTSnot": false,
    "PROJECTS": "",
    "PROJECTSnot": false,
    "PRIORITIES": "",
    "PRIORITIESnot": false,
    "SORTS": "+!completed\n+!by_context\n+!by_prio\n+!by_project\n+!by_due_date\n+!by_threshold_date\n+!alphabetical\n+!by_creation_date\n+!in_future\n+!by_completion_date\n+!file_order",
    "HIDECOMPLETED": false,
    "HIDEFUTURE": false,
    "HIDELISTS": false,
    "HIDETAGS": false,
    "HIDECREATEDATE": false,
    "HIDEHIDDEN": true,
    "CREATEISTHRESHOLD": false,
    "LUASCRIPT": "msg_no = math.random (1, tablelength(welc_msgs))\r\ntoast('Today is: '..os.date(\"%A, %B %d, %Y.\", os.time ())..'\\n\\n'..welc_msgs[msg_no])\r\ntoast('Today is: '..os.date(\"%A, %B %d, %Y.\", os.time ())..'\\n\\n'..welc_msgs[msg_no])\r\ntoast('Today is: '..os.date(\"%A, %B %d, %Y.\", os.time ())..'\\n\\n'..welc_msgs[msg_no])\r\n \nfunction onFilter(t,f,e)\n    return false\nend",
    "USE_SCRIPT": true,
    "LUASCRIPT_TEST_TASK": "",
    "query": ""
  },
  "12. Any.do Layout - All (No Health)": {
    "TITLE": "12. Any.do Layout - All (No Health)",
    "CONTEXTS": "Health",
    "CONTEXTSnot": true,
    "PROJECTS": "",
    "PROJECTSnot": false,
    "PRIORITIES": "",
    "PRIORITIESnot": false,
    "SORTS": "+!completed\n+!by_due_date\n+!by_context\n+!by_prio\n+!by_project\n+!by_threshold_date\n+!alphabetical\n+!by_creation_date\n+!in_future\n+!by_completion_date\n+!file_order",
    "HIDECOMPLETED": false,
    "HIDEFUTURE": false,
    "HIDELISTS": false,
    "HIDETAGS": false,
    "HIDECREATEDATE": false,
    "HIDEHIDDEN": true,
    "CREATEISTHRESHOLD": false,
    "LUASCRIPT": "function onGroup(t, f, e)\n    return group_by_date(t, f, e, \"due\")\nend",
    "USE_SCRIPT": true,
    "LUASCRIPT_TEST_TASK": "",
    "query": ""
  },
  "11. Any.do Layout - All": {
    "TITLE": "11. Any.do Layout - All",
    "CONTEXTS": "",
    "CONTEXTSnot": false,
    "PROJECTS": "",
    "PROJECTSnot": false,
    "PRIORITIES": "",
    "PRIORITIESnot": false,
    "SORTS": "+!completed\n+!by_due_date\n+!by_context\n+!by_prio\n+!by_project\n+!by_threshold_date\n+!alphabetical\n+!by_creation_date\n+!in_future\n+!by_completion_date\n+!file_order",
    "HIDECOMPLETED": false,
    "HIDEFUTURE": false,
    "HIDELISTS": false,
    "HIDETAGS": false,
    "HIDECREATEDATE": false,
    "HIDEHIDDEN": true,
    "CREATEISTHRESHOLD": false,
    "LUASCRIPT": "function onGroup(t, f, e)\n    return group_by_date(t, f, e, \"due\")\nend",
    "USE_SCRIPT": true,
    "LUASCRIPT_TEST_TASK": "",
    "query": ""
  },
  "07. Completed (All)": {
    "TITLE": "07. Completed (All)",
    "CONTEXTS": "",
    "CONTEXTSnot": false,
    "PROJECTS": "",
    "PROJECTSnot": false,
    "PRIORITIES": "",
    "PRIORITIESnot": false,
    "SORTS": "+!completed\n+!by_completion_date\n+!by_due_date\n+!by_context\n+!by_prio\n+!by_project\n+!by_threshold_date\n+!alphabetical\n+!by_creation_date\n+!in_future\n+!file_order",
    "HIDECOMPLETED": false,
    "HIDEFUTURE": false,
    "HIDELISTS": false,
    "HIDETAGS": false,
    "HIDECREATEDATE": false,
    "HIDEHIDDEN": true,
    "CREATEISTHRESHOLD": false,
    "LUASCRIPT": "function onFilter(t, f, e)\n    return f.completed\nend\n",
    "USE_SCRIPT": true,
    "LUASCRIPT_TEST_TASK": "",
    "query": ""
  },
  "09. Completed (Non-Recurring Only)": {
    "TITLE": "09. Completed (Non-Recurring Only)",
    "CONTEXTS": "",
    "CONTEXTSnot": false,
    "PROJECTS": "",
    "PROJECTSnot": false,
    "PRIORITIES": "",
    "PRIORITIESnot": false,
    "SORTS": "+!completed\n+!by_completion_date\n+!by_due_date\n+!by_context\n+!by_prio\n+!by_project\n+!by_threshold_date\n+!alphabetical\n+!by_creation_date\n+!in_future\n+!file_order",
    "HIDECOMPLETED": false,
    "HIDEFUTURE": false,
    "HIDELISTS": false,
    "HIDETAGS": false,
    "HIDECREATEDATE": false,
    "HIDEHIDDEN": true,
    "CREATEISTHRESHOLD": false,
    "LUASCRIPT": "function onFilter(t, f, e)\n    return e.rec == nil and f.completed\nend\n",
    "USE_SCRIPT": true,
    "LUASCRIPT_TEST_TASK": "",
    "query": ""
  },
  "02. Today (No Health)": {
    "TITLE": "02. Today (No Health)",
    "CONTEXTS": "Health",
    "CONTEXTSnot": true,
    "PROJECTS": "",
    "PROJECTSnot": false,
    "PRIORITIES": "",
    "PRIORITIESnot": false,
    "SORTS": "+!completed\n+!by_due_date\n+!by_context\n+!by_prio\n+!by_project\n+!by_threshold_date\n+!alphabetical\n+!by_creation_date\n+!in_future\n+!by_completion_date\n+!file_order",
    "HIDECOMPLETED": true,
    "HIDEFUTURE": false,
    "HIDELISTS": false,
    "HIDETAGS": false,
    "HIDECREATEDATE": false,
    "HIDEHIDDEN": true,
    "CREATEISTHRESHOLD": false,
    "LUASCRIPT": "function onFilter(t, f, e)\n    return filter_by_date(t, f, e, \"today\", \"due\")\nend\n\nfunction onGroup(t, f, e)\n    return group_by_date(t, f, e, \"due\")\nend",
    "USE_SCRIPT": true,
    "LUASCRIPT_TEST_TASK": "",
    "query": ""
  }
}