Last active
May 14, 2016 09:38
-
-
Save Wizek/d35c16ec23bff0dd2fb1 to your computer and use it in GitHub Desktop.
Advanced Pro-Con Decision helper for WorkFlowy; decision, workflowy, score summary, hierarchical data binding, searches for matching {{ decisionCount(children) }}, with radius and confidence%
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Advanced Pro-Con Decision helper for WorkFlowy | |
// @description If you write `{{ decisionCount(children) }}` somewhere, this script will sum up `(+)`s, `(-)`s `(+2.3)`s and similar in all children, helping you weigh pros vs cons. | |
// @match https://workflowy.com/* | |
// @version v0.3.1 | |
// @grant none | |
// @namespace https://gist.github.com/Wizek/d35c16ec23bff0dd2fb1 | |
// @downloadURL https://gist.github.com/Wizek/d35c16ec23bff0dd2fb1/raw/decision.user.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/ramda/0.17.1/ramda.min.js | |
// @author Milan Nagy | |
// ==/UserScript== | |
// jshint asi:true | |
"use strict"; | |
var E = {} | |
E.proc = function (a) { | |
// TODO Implement | |
return R.pipe(R.identity(a)) | |
} | |
setInterval(function(){ | |
var unboundSlice = Array.prototype.slice | |
var slice = Function.prototype.call.bind(unboundSlice) | |
var targets = R.pipe(slice, R.filter(R.pipe(R.curryN(1, $), R.invoker(0, 'text'), R.match(/{{\s*decisionCount\(children\)\s*}}/), R.prop('length'))))($('.content')) | |
//debugger | |
function processTarget (target) { | |
target = $(target) | |
var nameEl = target.find(' > .name > .content'); | |
var isClosed = '.project:not(.open, .task)' | |
if (target.is(isClosed) || target.find(isClosed).length) { | |
result = "Error: Closed children" | |
} else { | |
var matches = target.text().match(/\([-+]\d*(\.\d+)?\)/g) | |
var QMatches = target.text().match(/\(\?+\)/g) | |
var QCount = QMatches | |
? R.pipe(R.join(''), R.filter(R.equals('?')), R.prop('length'))(QMatches) | |
: 0 | |
var numbers = (matches || []).map(parseDecisionVector) | |
var sum = R.reduce(function(memo, num){ return memo + num; }, 0) | |
var total = sum(numbers) | |
var round = R.pipe(R.multiply(1000), Math.round, R.divide(R.__, 1000)) | |
var absNums = R.map(Math.abs, numbers) | |
var radius = sum(absNums) | |
var f = round | |
var QString = QCount | |
? ' Qs: ' + QCount | |
: '' | |
var conf = Math.abs(total*100)/radius | |
var confP = Math.round(conf) + '%' | |
var eConfP = Math.round(100 - conf) + '%' | |
var yesNo = (total > 0 ? 'Yes' : 'No' ) + ". " + confP | |
var answer = conf > 50 | |
? yesNo | |
: "Doesn't matter, either are good choices. " + eConfP + " Slightly leaning towards " + yesNo | |
var result | |
= answer | |
+ ' (score: ' + f(total) | |
+ ' confidence-in-choice: ' + confP | |
+ ' equally-good-choices: ' + eConfP | |
+ ' radius: ' + f(radius) | |
+ QString | |
+ ')' | |
} | |
var oldVal = nameEl.text() | |
var newVal = oldVal.replace(/{{\s*decisionCount\(children\)\s*}}.*/, '{{ decisionCount(children) }} = ' + result) | |
if (oldVal != newVal) { | |
nameEl.text(newVal) | |
} | |
} | |
function parseDecisionVector (i) { | |
var match | |
if (typeof i == "number") { return i } | |
if (i == "(+)") { return 1 } | |
if (i == "(-)") { return -1 } | |
if (match = i.match(/^\((.*)\)$/)) { return parseFloat(match[1], 10) } | |
return i | |
} | |
R.map(processTarget, slice($(targets).parent().parent())) | |
}, 2000) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
TODOs