Drafts Action Directory

Send to Things

Posted by @eichtyler, Last update 5 months ago

Send project outlines to Things using Markdown syntax (requires Things 3.4 and higher)

Add a list of todos to the inbox

Todo 1
Todo 2
// Comments go here and will be ignored
> Notes go here
> and here
- checklist item 1
- checklist item 2
Todo 3
#tag
#another tag
:when date
!deadline

Make a new project with todos under it

# Project 1
> Notes go here
> and here
#tag
#another tag
:when date
!deadline

Todo 1
Todo 2

## Heading for project 1
Todo 3

# Project 2
Todo 4

## Heading for project 2
Todo 5
Todo 6

Add a list of todos to an existing project or area, or add a project to an existing area

@ Existing project name
Todo 1
Todo 2
Todo 3

@ Area
Todo 4

# New project under Area
Todo 5
Todo 6
Install

Steps

  • script

    /*
      Send each line of a draft to things as a todo
    */
    
    
    
    const getTargetItem = state => state.todo || state.project
    
    const parsers = [
    	{
    		// Project
    		pattern: /^# /g,
    		transform(state, input) {
    			const project = TJSProject.create()
    			project.title = input
    
    			if (state.list) {
    				project.area = state.list
    			}
    
    			state.items.push(project)
    			state.project = project
    			// state.list = null
    			state.todo = null
    		}
    	},
    	{
    		// Heading
    		pattern: /^## /g,
    		transform(state, input) {
    			const heading = TJSHeading.create()
    			heading.title = input
    
    			if (state.project) {
    				state.project.addHeading(heading)
    			}
    		}
    	},
    	{
    		// Checklist item
    		pattern: /^- /g,
    		transform(state, input) {
    			const checklistItem = TJSChecklistItem.create()
    			checklistItem.title = input
    
    			if (state.todo) {
    				state.todo.addChecklistItem(checklistItem)
    			}
    		}
    	},
    	{
    		// Note
    		pattern: /^> ?/g,
    		transform(state, input) {
    			const targetItem = getTargetItem(state)
    
    			if (targetItem) {
    				if (!targetItem.notes) {
    					targetItem.notes = input
    				} else {
    					targetItem.notes += `\n${input}`
    				}
    			}
    		}
    	},
    	{
    		// Tag
    		pattern: /^#/g,
    		transform(state, input) {
    			const targetItem = getTargetItem(state)
    
    			if (targetItem) {
    				if (!Array.isArray(targetItem.tags)) {
    					targetItem.tags = [input]
    				} else {
    					targetItem.tags.push(input)
    				}
    			}
    		}
    	},
    	{
    		// List
    		pattern: /^@ ?/g,
    		transform(state, input) {
    			state.list = input
    		}
    	},
    	{
    		// When
    		pattern: /^: ?/g,
    		transform(state, input) {
    			const targetItem = getTargetItem(state)
    
    			if (targetItem) {
    				targetItem.when = input
    			}
    		}
    	},
    	{
    		// Deadline
    		pattern: /^! ?/g,
    		transform(state, input) {
    			const targetItem = getTargetItem(state)
    
    			if (targetItem) {
    				targetItem.deadline = input
    			}
    		}
    	},
    	{
    		// Comments
    		pattern: /^\/\//g,
    		transform(state, input) {
    			// These are comments, so this transform does nothing
    		}
    	},
    	{
    		// Todo (matches everything else)
    		pattern: /^/g,
    		transform(state, input) {
    			const todo = TJSTodo.create()
    			todo.title = input
    
    			if (state.list) {
    				todo.list = state.list
    			}
    
    			if (state.project) {
    				state.project.addTodo(todo)
    			} else {
    				state.items.push(todo)
    			}
    
    			state.todo = todo
    		}
    	}
    ]
    
    // const projectPattern = /^# /g
    // const subheadingPattern = /^## /g
    // const checklistItemPattern = /^- /g
    // const notePattern = /^> ?/g
    
    // const listPattern = /^@ ?/g
    // const tagPattern = /^#[^\s]|$ ?/g
    // const whenPattern = /^: ?/g
    // const deadlinePattern = /^! ?/g
    
    const lines = draft.content.split("\n").filter(line => line.length)
    
    
    
    const state = lines.reduce((state, line) => {
    	for (var {pattern, transform} of parsers) {
    		if (pattern.test(line)) {
    			const input = line.replace(pattern, "")
    			transform(state, input)
    			break
    		}
    	}
    	
    	return state
    },
    {
      project: null,
      todo: null,
      list: null,
      items: []
    })
    
    
    const {url} = TJSContainer.create(state.items)
    
    console.log(url)
    
    const cb = CallbackURL.create()
    cb.baseURL = url
    
    
    if (cb.open()) {
    	console.log("Todos created in Things")
    } else {
    	context.fail()
    }
    

Options

  • After Success Nothing
    Notification Info
    Log Level Info

Comments

Actions available in the Action Directory are uploaded by community members. Use appropriate caution reviewing downloaded actions before use.