├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── docs └── index.html ├── plugins ├── ebalster_attribute-modules │ ├── $__core_modules_parsers_wikiparser_attributes_filtered.js.tid │ ├── $__core_modules_parsers_wikiparser_attributes_indirect.js.tid │ ├── $__core_modules_parsers_wikiparser_attributes_macro.js.tid │ ├── $__core_modules_widgets_attributes_filtered.js.tid │ ├── $__core_modules_widgets_attributes_indirect.js.tid │ ├── $__core_modules_widgets_attributes_macro.js.tid │ ├── $__plugins_ebalster_attribute-modules_patchSource_core_modules_utils_parseutils.js │ ├── $__plugins_ebalster_attribute-modules_patchSource_core_modules_utils_parseutils.js.meta │ ├── $__plugins_ebalster_attribute-modules_patchSource_core_modules_widgets_widget.js │ ├── $__plugins_ebalster_attribute-modules_patchSource_core_modules_widgets_widget.js.meta │ ├── $__plugins_ebalster_attribute-modules_patch_core_modules_utils_parseutils.js │ ├── $__plugins_ebalster_attribute-modules_patch_core_modules_utils_parseutils.js.meta │ ├── $__plugins_ebalster_attribute-modules_patch_core_modules_widgets_widget.js │ ├── $__plugins_ebalster_attribute-modules_patch_core_modules_widgets_widget.js.meta │ └── plugin.info ├── ebalster_condition │ └── plugin.info ├── ebalster_formula │ ├── $__plugins_ebalster_formula_coerce.js.tid │ ├── $__plugins_ebalster_formula_compile.js.tid │ ├── $__plugins_ebalster_formula_compute.js.tid │ ├── $__plugins_ebalster_formula_functions_arithmetic.js.tid │ ├── $__plugins_ebalster_formula_functions_arrays.js.tid │ ├── $__plugins_ebalster_formula_functions_compare.js.tid │ ├── $__plugins_ebalster_formula_functions_datetime.js.tid │ ├── $__plugins_ebalster_formula_functions_logic.js.tid │ ├── $__plugins_ebalster_formula_functions_math.js.tid │ ├── $__plugins_ebalster_formula_functions_regexp.js.tid │ ├── $__plugins_ebalster_formula_functions_strings.js.tid │ ├── $__plugins_ebalster_formula_functions_wiki.js.tid │ ├── $__plugins_ebalster_formula_lib_numeral.js.tid │ ├── $__plugins_ebalster_formula_license.tid │ ├── $__plugins_ebalster_formula_macros_formula.js.tid │ ├── $__plugins_ebalster_formula_nodes.js.tid │ ├── $__plugins_ebalster_formula_operators_arithmetic.js.tid │ ├── $__plugins_ebalster_formula_operators_compare.js.tid │ ├── $__plugins_ebalster_formula_operators_strings.js.tid │ ├── $__plugins_ebalster_formula_readme.tid │ ├── $__plugins_ebalster_formula_settings.tid │ ├── $__plugins_ebalster_formula_value.js.tid │ ├── $__plugins_ebalster_formula_widgets_attributes_formula.js.tid │ ├── $__plugins_ebalster_formula_widgets_formula-vars.js.tid │ ├── $__plugins_ebalster_formula_widgets_formula.js.tid │ ├── $__plugins_ebalster_formula_wikiparser_attributes_formula.js.tid │ ├── $__plugins_ebalster_formula_wikiparser_formula.js.tid │ └── plugin.info ├── ebalster_modloader │ ├── $__core_modules_startup.js.tid │ ├── $__plugins_ebalster_modloader_about.tid │ ├── $__plugins_ebalster_modloader_alert.tid │ ├── $__plugins_ebalster_modloader_diff_patch_match.js │ ├── $__plugins_ebalster_modloader_diff_patch_match.js.meta │ ├── $__plugins_ebalster_modloader_diff_patch_match_uncompressed.js │ ├── $__plugins_ebalster_modloader_diff_patch_match_uncompressed.js.meta │ ├── $__plugins_ebalster_modloader_loader.js.tid │ ├── $__plugins_ebalster_modloader_parsers_patch.js.tid │ ├── $__plugins_ebalster_modloader_patches_core_modules_startup.js.tid │ ├── $__plugins_ebalster_modloader_patchmaker.tid │ ├── $__plugins_ebalster_modloader_status.tid │ ├── $__plugins_ebalster_modloader_stylesheet.css.tid │ ├── $__plugins_ebalster_modloader_utils.js.tid │ ├── $__plugins_ebalster_modloader_widgets_action-createpatch.js │ ├── $__plugins_ebalster_modloader_widgets_action-createpatch.js.meta │ └── plugin.info ├── ebalster_timer │ └── plugin.info └── telmiger_details │ └── plugin.info ├── tiddlers ├── _system │ ├── Bob │ │ ├── AvailableLanguageList.tid │ │ └── AvailablePluginList.tid │ ├── DefaultTiddlers.tid │ ├── FormulasWiki │ │ ├── AutoSummarizeInView.tid │ │ └── FunctionMacros.tid │ ├── SiteSubtitle.tid │ ├── SiteTitle.tid │ ├── StoryList.tid │ ├── config │ │ ├── FileSystemPaths.tid │ │ ├── RelinkOnRename.tid │ │ └── TextEditor │ │ │ └── EnableToolbar.tid │ ├── core │ │ └── ui │ │ │ ├── PageTemplate.tid │ │ │ └── SideBarSegments │ │ │ └── search.tid │ ├── palette.tid │ └── themes_tiddlywiki_vanilla_options_sidebarlayout.tid └── wiki │ ├── -$_ │ └── plugins │ │ └── ebalster │ │ ├── formula---207639789.tid │ │ └── formula.tid │ ├── Argument List.tid │ ├── Array Literal.tid │ ├── ArrayValue.tid │ ├── Auto-Map Debug.tid │ ├── Auto-Map.tid │ ├── Auto-Map │ ├── Controls.tid │ ├── Logic-Old.tid │ ├── Logic.tid │ └── Render.tid │ ├── BNF Grammar.tid │ ├── BooleanValue.tid │ ├── BuiltInFunction.tid │ ├── Candy-Bar.tid │ ├── Cell Reference.tid │ ├── ChangeLog.tid │ ├── Condition Plugin.tid │ ├── Date Literal.tid │ ├── Datum.tid │ ├── Demo_ Bouncy Bounce.tid │ ├── Demo_ Conway's Game of Life.tid │ ├── Demo_ Harmonic Lattice.tid │ ├── Demo_ Line Graph.tid │ ├── Demo_ Real Projective Line.tid │ ├── Demo_ Starburst.tid │ ├── Demo_ Tabulator.tid │ ├── Demo_ Tabulator │ └── HairCut.tid │ ├── Demo_ Timed Counter.tid │ ├── Eval-Tester │ ├── Expression.tid │ └── SumFilter.tid │ ├── Evan Balster.tid │ ├── Expression.tid │ ├── Extending Formulas.tid │ ├── Filter.tid │ ├── Formula Plugin.tid │ ├── Formula Plugin │ └── Design.tid │ ├── Formula.tid │ ├── FormulaMacro.tid │ ├── FormulaVarsWidget.tid │ ├── FormulaWidget.tid │ ├── Formulas as Tag Attributes.tid │ ├── Formulas as an Attribute Type.tid │ ├── Formulas in WikiText.tid │ ├── Formulas.tid │ ├── Function Adder.tid │ ├── Function Call.tid │ ├── Function.tid │ ├── Functions.tid │ ├── HTML Render Checker.tid │ ├── Harmonic Lattice.tid │ ├── Harmonic Lattice │ └── State.tid │ ├── IFS Function.tid │ ├── LetConstruct.tid │ ├── LetStatement.tid │ ├── LocalVariable.tid │ ├── Mod-Loader Plugin.tid │ ├── Number Literal.tid │ ├── NumberValue.tid │ ├── Operand.tid │ ├── Operator.tid │ ├── Operators.tid │ ├── Parenthesized Expression.tid │ ├── PercentageValue.tid │ ├── Performance Notes.tid │ ├── Planned Changes.tid │ ├── Pomodoro Timer.tid │ ├── Real Projective Line.tid │ ├── Real Projective Line │ ├── Macros.tid │ └── State.tid │ ├── Refresh Optimizations.tid │ ├── RegexTiddler.tid │ ├── Regular Expression Literal.tid │ ├── Repack Helper_ attribute-modules.tid │ ├── Repack Helper_ condition.tid │ ├── Repack Helper_ formula.tid │ ├── Repack Helper_ modloader.tid │ ├── Repack Helper_ timer.tid │ ├── SWITCH Function.tid │ ├── Soda-Pop.tid │ ├── Source Code.tid │ ├── Spreadsheet Prototype.tid │ ├── Spreadsheet │ └── Data.tid │ ├── Startup Module Inspector.tid │ ├── String Literal.tid │ ├── StringValue.tid │ ├── StyleSheet.css │ ├── StyleSheet.css.meta │ ├── Syntax Design Resources.tid │ ├── Syntax.tid │ ├── Ten-Sodas.tid │ ├── Timer Plugin.tid │ ├── Transclusion.tid │ ├── Try Me.tid │ ├── UnitTest │ └── Functions │ │ └── nth │ │ └── sorted-return.tid │ ├── Unpack a Plugin.tid │ ├── Value.tid │ ├── Variable.tid │ ├── Widget Architecture.tid │ ├── Widget Architecture │ ├── Commonly Overridden Methods.tid │ ├── DOM.tid │ ├── Functionality.tid │ └── Implementor Utility Methods.tid │ ├── Widget Inspector.tid │ ├── Widget Refresh Inspector.tid │ ├── Widget Tree Visualizer.tid │ ├── Widget Variable Inspector.tid │ ├── range Operator.tid │ └── uplus Function.tid ├── tiddlywiki.info └── versions ├── formulas-tiddlywiki-5.1.20.html ├── formulas-tiddlywiki-5.1.20.html.zip ├── formulas-tiddlywiki-5.1.22.html ├── formulas-tiddlywiki-5.1.22.html.zip ├── formulas-tiddlywiki-5.1.23.html └── formulas-tiddlywiki-5.1.23.html.zip /.gitattributes: -------------------------------------------------------------------------------- 1 | # .gitattributes snippet to force users to use same line endings for project. 2 | # 3 | # Handle line endings automatically for files detected as text 4 | # and leave all files detected as binary untouched. 5 | * text=auto 6 | 7 | # 8 | # The above will handle all files NOT found below 9 | # https://help.github.com/articles/dealing-with-line-endings/ 10 | # https://github.com/Danimoth/gitattributes/blob/master/Web.gitattributes 11 | 12 | 13 | 14 | # These files are text and should be normalized (Convert crlf => lf) 15 | *.tid text 16 | *.meta text 17 | *.tw text 18 | *.tw5 text 19 | *.info text 20 | *.files tex 21 | *.md text 22 | *.php text 23 | *.css text 24 | *.js text 25 | *.json text 26 | *.htm text 27 | *.html text 28 | *.xml text 29 | *.txt text 30 | *.ini text 31 | *.inc text 32 | *.pl text 33 | *.rb text 34 | *.py text 35 | *.scm text 36 | *.sql text 37 | .htaccess text 38 | *.sh text 39 | 40 | # These files are binary and should be left untouched 41 | # (binary is a macro for -text -diff) 42 | *.png binary 43 | *.jpg binary 44 | *.jpeg binary 45 | *.gif binary 46 | *.ico binary 47 | *.mov binary 48 | *.mp4 binary 49 | *.mp3 binary 50 | *.flv binary 51 | *.fla binary 52 | *.swf binary 53 | *.gz binary 54 | *.zip binary 55 | *.7z binary 56 | *.ttf binary 57 | *.pyc binary -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore StoryList 2 | $__StoryList.tid 3 | archive/* 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Evan Balster, 2019 Joshua Fontany 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Formula for TiddlyWiki 2 | 3 | A TiddlyWiki plugin for functional formulas, combining the power of Excel and Google Sheets with TiddlyWiki's processing idioms. 4 | 5 | Created by Evan Balster 6 | 7 | * [Source on GitHub](https://github.com/EvanBalster/TiddlyWikiFormula). 8 | * [Demonstration Wiki](https://joshuafontany.github.io/TiddlyWikiFormula/). 9 | 10 | Get Formulas by opening the Demonstration Wiki and navigating to the plugins there. 11 | 12 | 13 | ## Examples 14 | 15 | 16 | feature | formula | result 17 | --- | --- | --- 18 | numbers | `(= 2 =)` | 2.00 19 | math | `(= 2+3*4 =)` | 14.00 20 | functions | `(= pow(2, 3) =)` | 8.00 21 | comparison | `(= 2+3*4 > 12 =)` | TRUE 22 | transclusion | `(= {{Soda-Pop!!value}} =)` | 1.49 23 | variables | `(= <> =)` | 15:38, 20th December 2017 24 | filters | `(= [tag[Expenses]] =)` | [Candy-Bar,Soda-Pop,Ten-Sodas] 25 | complex 26 | formulas | `(= round(5*sum([tag[Expenses]get[value]]), 2) =)` | 92.10 27 | strings | `(= "hello" =)` | hello 28 | concatenation | `(= '$' & 45.23*12 & " cost" =)` | $542.76 cost 29 | 30 | 31 | ## Contributing 32 | 33 | "This plugin is currently under development. I've written compilers before, but this is my first in-depth project in JavaScript. Please report any bugs you encounter, or any problems you spot in the code." - Evan Balster 34 | 35 | The Formula plugin has not been fully tested under IE, Edge or other mobile browsers. 36 | -------------------------------------------------------------------------------- /plugins/ebalster_attribute-modules/$__core_modules_parsers_wikiparser_attributes_filtered.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171224215126050 2 | description: Tag attribute rule for filtered values, eg. {{{[all[shadows]]}}}. 3 | modified: 20171224215155435 4 | module-type: attributerule 5 | revision: 0 6 | tags: 7 | title: $:/core/modules/parsers/wikiparser/attributes/filtered.js 8 | type: application/javascript 9 | 10 | /*\ 11 | title: $:/core/modules/parsers/wikiparser/attributes/filtered.js 12 | type: application/javascript 13 | module-type: attributerule 14 | 15 | Tag attribute parser rule for filtered values, eg. {{{[all[shadows]]}}}. 16 | 17 | \*/ 18 | (function(){ 19 | 20 | /*jslint node: true, browser: true */ 21 | /*global $tw: false */ 22 | "use strict"; 23 | 24 | exports.filtered = function(source,pos,node) { 25 | // Is it a filtered value? 26 | var reFilteredValue = /\{\{\{(.+?)\}\}\}/g; 27 | var value = $tw.utils.parseTokenRegExp(source,pos,reFilteredValue); 28 | if (!value) return null; 29 | node.type = "filtered"; 30 | node.filter = value.match[1]; 31 | node.end = value.end; 32 | return node; 33 | }; 34 | 35 | })(); -------------------------------------------------------------------------------- /plugins/ebalster_attribute-modules/$__core_modules_parsers_wikiparser_attributes_indirect.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171224214929513 2 | description: Tag attribute rule for transcluded values, eg. {{Layout!!height}}. 3 | modified: 20171224215110965 4 | module-type: attributerule 5 | revision: 0 6 | tags: 7 | title: $:/core/modules/parsers/wikiparser/attributes/indirect.js 8 | type: application/javascript 9 | 10 | /*\ 11 | title: $:/core/modules/parsers/wikiparser/attributes/indirect.js 12 | type: application/javascript 13 | module-type: attributerule 14 | 15 | Tag attribute parser rule for transcluded values, eg. {{Layout!!height}}. 16 | 17 | \*/ 18 | (function(){ 19 | 20 | /*jslint node: true, browser: true */ 21 | /*global $tw: false */ 22 | "use strict"; 23 | 24 | exports.indirect = function(source,pos,node) { 25 | // Is it an indirect (transcluded) value? 26 | var reIndirectValue = /\{\{([^\{\}]+)\}\}/g; 27 | var value = $tw.utils.parseTokenRegExp(source,pos,reIndirectValue); 28 | if (!value) return null; 29 | node.type = "indirect"; 30 | node.textReference = value.match[1]; 31 | node.end = value.end; 32 | return node; 33 | }; 34 | 35 | })(); -------------------------------------------------------------------------------- /plugins/ebalster_attribute-modules/$__core_modules_parsers_wikiparser_attributes_macro.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171224215158051 2 | description: Tag attribute rule for macros and variables, eg. <>. 3 | modified: 20171224215427368 4 | module-type: attributerule 5 | revision: 0 6 | tags: 7 | title: $:/core/modules/parsers/wikiparser/attributes/macro.js 8 | type: application/javascript 9 | 10 | /*\ 11 | title: $:/core/modules/parsers/wikiparser/attributes/macro.js 12 | type: application/javascript 13 | module-type: attributerule 14 | 15 | Tag attribute parser rule for macros and variables, eg. <>. 16 | 17 | \*/ 18 | (function(){ 19 | 20 | /*jslint node: true, browser: true */ 21 | /*global $tw: false */ 22 | "use strict"; 23 | 24 | exports.macro = function(source,pos,node) { 25 | // Is it a macro invocation? 26 | var macroInvocation = $tw.utils.parseMacroInvocation(source,pos); 27 | if (!macroInvocation) return null; 28 | node.type = "macro"; 29 | node.value = macroInvocation; 30 | node.end = macroInvocation.end; 31 | return node; 32 | }; 33 | 34 | })(); -------------------------------------------------------------------------------- /plugins/ebalster_attribute-modules/$__core_modules_widgets_attributes_filtered.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171225042329213 2 | description: An attribute value acquired via text reference. 3 | modified: 20171225042338300 4 | module-type: attributevalue 5 | revision: 0 6 | tags: 7 | title: $:/core/modules/widgets/attributes/filtered.js 8 | type: application/javascript 9 | 10 | /*\ 11 | title: $:/core/modules/widgets/attributes/filtered.js 12 | type: application/javascript 13 | module-type: attributevalue 14 | 15 | An attribute value acquired via filter expression. 16 | 17 | \*/ 18 | (function(){ 19 | 20 | /*jslint node: true, browser: true */ 21 | /*global $tw: false */ 22 | "use strict"; 23 | 24 | var FilteredAttribute = function(widget,node) { 25 | this.widget = widget; 26 | this.filter = node.filter; 27 | this.compiledFilter = this.widget.wiki.compileFilter(this.filter); 28 | this.value = this.compute(); 29 | }; 30 | 31 | /* 32 | Inherit from the base ??? class 33 | */ 34 | //FormulaAttribute.prototype = new AttributeGizmo(); 35 | 36 | FilteredAttribute.prototype.compute = function() { 37 | this.results = this.compiledFilter.call(this.widget.wiki,undefined,this.widget); 38 | // TODO why only one result? Can we return a list?? 39 | return this.results[0] || ""; 40 | }; 41 | 42 | FilteredAttribute.prototype.refresh = function(changedTiddlers) { 43 | // TODO can filters be selectively refreshed in the future? 44 | this.value = this.compute(); 45 | return this.value; 46 | }; 47 | 48 | 49 | exports.filtered = FilteredAttribute; 50 | 51 | })(); 52 | -------------------------------------------------------------------------------- /plugins/ebalster_attribute-modules/$__core_modules_widgets_attributes_indirect.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171225042213912 2 | description: An attribute value acquired via text reference. 3 | modified: 20171225042325491 4 | module-type: attributevalue 5 | revision: 0 6 | tags: 7 | title: $:/core/modules/widgets/attributes/indirect.js 8 | type: application/javascript 9 | 10 | /*\ 11 | title: $:/core/modules/widgets/attributes/indirect.js 12 | type: application/javascript 13 | module-type: attributevalue 14 | 15 | An attribute value acquired via filter expression. 16 | 17 | \*/ 18 | (function(){ 19 | 20 | /*jslint node: true, browser: true */ 21 | /*global $tw: false */ 22 | "use strict"; 23 | 24 | var IndirectAttribute = function(widget,node) { 25 | this.widget = widget; 26 | this.textReference = $tw.utils.parseTextReference(node.textReference); 27 | if (!this.textReference.title) this.currentTiddler = this.widget.getVariable("currentTiddler"); 28 | this.value = this.compute(); 29 | }; 30 | 31 | /* 32 | Inherit from the base ??? class 33 | */ 34 | //FormulaAttribute.prototype = new AttributeGizmo(); 35 | 36 | IndirectAttribute.prototype.compute = function() { 37 | var tr = this.textReference, 38 | title = tr.title || this.currentTiddler, 39 | wiki = this.widget.wiki; 40 | if(tr.field) { 41 | var tiddler = wiki.getTiddler(title); 42 | if(tr.field === "title") { // Special case so we can return the title of a non-existent tiddler 43 | return title; 44 | } else if(tiddler && $tw.utils.hop(tiddler.fields,tr.field)) { 45 | return tiddler.getFieldString(tr.field); 46 | } else { 47 | return ""; 48 | } 49 | } else if(tr.index) { 50 | return wiki.extractTiddlerDataItem(title,tr.index,""); 51 | } else { 52 | return wiki.getTiddlerText(title,""); 53 | } 54 | }; 55 | 56 | IndirectAttribute.prototype.refresh = function(changedTiddlers) { 57 | if (this.textReference.title) { 58 | // Recompute if the title tiddler changed. 59 | if (changedTiddlers[this.textReference.title]) 60 | this.value = this.compute(); 61 | } 62 | else { 63 | // Did currentTiddler change? 64 | var newTiddler = this.widget.getVariable("currentTiddler"); 65 | if (newTiddler != this.currentTiddler) { 66 | this.currentTiddler = newTiddler; 67 | this.value = this.compute(); 68 | } 69 | else if (changedTiddlers[this.currentTiddler]) { 70 | // Recompute if the tiddler changed. 71 | this.value = this.compute(); 72 | } 73 | } 74 | // Return the latest value. 75 | return this.value; 76 | }; 77 | 78 | 79 | exports.indirect = IndirectAttribute; 80 | 81 | })(); 82 | -------------------------------------------------------------------------------- /plugins/ebalster_attribute-modules/$__core_modules_widgets_attributes_macro.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171225042340029 2 | description: An attribute value acquired via text reference. 3 | modified: 20171225042346461 4 | module-type: attributevalue 5 | revision: 0 6 | tags: 7 | title: $:/core/modules/widgets/attributes/macro.js 8 | type: application/javascript 9 | 10 | /*\ 11 | title: $:/core/modules/widgets/attributes/macro.js 12 | type: application/javascript 13 | module-type: attributevalue 14 | 15 | An attribute value acquired via macro expansion. 16 | 17 | \*/ 18 | (function(){ 19 | 20 | /*jslint node: true, browser: true */ 21 | /*global $tw: false */ 22 | "use strict"; 23 | 24 | var MacroAttribute = function(widget,node) { 25 | this.widget = widget; 26 | this.macro = node.value; 27 | this.value = this.compute(); 28 | }; 29 | 30 | /* 31 | Inherit from the base ??? class 32 | */ 33 | //FormulaAttribute.prototype = new AttributeGizmo(); 34 | 35 | MacroAttribute.prototype.compute = function() { 36 | var value = this.widget.getVariable(this.macro.name,{params: this.macro.params}); 37 | if (value == null) value = ""; 38 | return value; 39 | }; 40 | 41 | MacroAttribute.prototype.refresh = function(changedTiddlers) { 42 | this.value = this.compute(); 43 | return this.value; 44 | }; 45 | 46 | 47 | exports.macro = MacroAttribute; 48 | 49 | })(); 50 | -------------------------------------------------------------------------------- /plugins/ebalster_attribute-modules/$__plugins_ebalster_attribute-modules_patchSource_core_modules_utils_parseutils.js.meta: -------------------------------------------------------------------------------- 1 | title: $:/plugins/ebalster/attribute-modules/patchSource/core/modules/utils/parseutils.js 2 | type: _application/javascript 3 | module-type: _utils -------------------------------------------------------------------------------- /plugins/ebalster_attribute-modules/$__plugins_ebalster_attribute-modules_patchSource_core_modules_widgets_widget.js.meta: -------------------------------------------------------------------------------- 1 | title: $:/plugins/ebalster/attribute-modules/patchSource/core/modules/widgets/widget.js 2 | type: _application/javascript 3 | module-type: _widget 4 | -------------------------------------------------------------------------------- /plugins/ebalster_attribute-modules/$__plugins_ebalster_attribute-modules_patch_core_modules_utils_parseutils.js: -------------------------------------------------------------------------------- 1 | @@ -79,33 +79,35 @@ 2 | dule-type: utils 3 | -%0A 4 | +%0D%0A%0D 5 | %0AUtility functio 6 | @@ -141,33 +141,35 @@ 7 | ext into tokens. 8 | -%0A 9 | +%0D%0A%0D 10 | %0AMost functions 11 | @@ -187,33 +187,35 @@ 12 | llowing pattern: 13 | -%0A 14 | +%0D%0A%0D 15 | %0A* The parameter 16 | @@ -771,33 +771,35 @@ 17 | scribe the token 18 | -%0A 19 | +%0D%0A%0D 20 | %0AThe exception i 21 | @@ -863,33 +863,35 @@ 22 | the whitespace. 23 | -%0A 24 | +%0D%0A%0D 25 | %0A%5C*/%0A(function() 26 | @@ -883,33 +883,35 @@ 27 | %5C*/%0A(function()%7B 28 | -%0A 29 | +%0D%0A%0D 30 | %0A/*jslint node: 31 | @@ -961,33 +961,35 @@ 32 | */%0A%22use strict%22; 33 | -%0A 34 | +%0D%0A%0D 35 | %0A/*%0ALook for a w 36 | @@ -1490,33 +1490,35 @@ 37 | end: p%0A%09%09%7D%0A%09%7D%0A%7D; 38 | -%0A 39 | +%0D%0A%0D 40 | %0A/*%0AConvenience 41 | @@ -1884,33 +1884,35 @@ 42 | n pos;%0A%09%09%7D%0A%09%7D%0A%7D; 43 | -%0A 44 | +%0D%0A%0D 45 | %0A/*%0ALook for a g 46 | @@ -2238,33 +2238,35 @@ 47 | %09return null;%0A%7D; 48 | -%0A 49 | +%0D%0A%0D 50 | %0A/*%0ALook for a t 51 | @@ -2669,33 +2669,35 @@ 52 | turn null;%0A%09%7D%0A%7D; 53 | -%0A 54 | +%0D%0A%0D 55 | %0A/*%0ALook for a s 56 | @@ -3246,33 +3246,35 @@ 57 | turn null;%0A%09%7D%0A%7D; 58 | -%0A 59 | +%0D%0A%0D 60 | %0A/*%0ALook for a m 61 | @@ -4346,33 +4346,35 @@ 62 | %09return node;%0A%7D; 63 | -%0A 64 | +%0D%0A%0D 65 | %0A/*%0ALook for a m 66 | @@ -5536,33 +5536,35 @@ 67 | %09return node;%0A%7D; 68 | -%0A 69 | +%0D%0A%0D 70 | %0A/*%0ALook for an 71 | @@ -5716,32 +5716,62 @@ 72 | art:, end:,%7D%0A*/%0A 73 | +var AttributeRules = null;%0D%0A%0D%0A 74 | exports.parseAtt 75 | @@ -6630,40 +6630,20 @@ 76 | l) %7B%0A%09%09%09 77 | -pos = stringLiteral.end; 78 | +%09%09%09%09 79 | %0A%09%09%09node 80 | @@ -6699,533 +6699,481 @@ 81 | alue;%0A%09%09 82 | -%7D else %7B%0A%09%09%09// Look for a filtered value%0A%09%09%09var filteredValue = $tw.utils.parseTokenRegExp(source,pos,reFilteredValue);%0A%09%09%09if(filteredValue) %7B%0A%09%09%09%09pos = filteredValue.end;%0A%09%09%09%09node.type = %22filtered%22;%0A%09%09%09%09node.filter = filteredValue.match%5B1%5D;%0A%09%09%09%7D else %7B%0A%09%09%09%09// Look for an indirect value%0A%09%09%09%09var indirectValue = $tw.utils.parseTokenRegExp(source,pos,reIndirectValue);%0A%09%09%09%09if(indirectValue) %7B%0A%09%09%09%09%09pos = indirectValue.end;%0A%09%09%09%09%09node.type = %22indirect%22;%0A%09%09%09%09%09node.textReference = indirectValue. 83 | +%09node.end = stringLiteral.end;%0A%09%09%09%09%09%09%09%09%0A%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%0A%09%09%09%09%09%09%0A%09%09%09%09%09%09%09%0A%09%09%09return node;%0A%09%09%7D%0A%09%09// Load attribute rules if needed%0A%09%09if (!AttributeRules) %7B%0A%09%09%09AttributeRules = %7B%7D;%0A%09%09%09$tw.modules.applyMethods(%22attributerule%22,AttributeRules);%0A%09%09%7D%0A%09%09// Look for an attribute rule%0A%09%09var match = null;%0A%09%09$tw.utils.each(AttributeRules,function(rule) %7B%0A%09%09%09match = rule(source,pos,node);%0A%09%09%09return !match;%0A%09%09%7D);%0A%09%09if (match) return 84 | match 85 | -%5B1%5D 86 | ;%0A%09%09%09%09 87 | -%7D else %7B 88 | +%09%09%09%09%09%09%09%09%09 89 | %0A%09%09%09 90 | +%0A 91 | %09%09// Loo 92 | @@ -7187,35 +7187,32 @@ 93 | unquoted value%0A 94 | -%09%09%09 95 | %09%09var unquotedVa 96 | @@ -7269,35 +7269,32 @@ 97 | otedAttribute);%0A 98 | -%09%09%09 99 | %09%09if(unquotedVal 100 | @@ -7304,45 +7304,20 @@ 101 | %7B%0A%09%09%09%09%09 102 | -%09pos = unquotedValue.end;%0A 103 | %09%09%09 104 | +%0A 105 | %09%09%09node. 106 | @@ -7325,35 +7325,32 @@ 107 | ype = %22string%22;%0A 108 | -%09%09%09 109 | %09%09%09node.value = 110 | @@ -7376,288 +7376,156 @@ 111 | %5B1%5D;%0A%09%09%09 112 | -%09%09%7D else %7B%0A%09%09%09%09%09%09// Look for a macro invocation value%0A%09%09%09%09%09%09var macroInvocation = $tw.utils.parseMacroInvocation(source,pos);%0A%09%09%09%09%09%09if(macroInvocation) %7B%0A%09%09%09%09%09%09%09pos = macroInvocation.end;%0A%09%09%09%09%09%09%09node.type = %22macro%22;%0A%09%09%09%09%09%09%09node.value = macroInvocation;%0A 113 | +node.end = unquotedValue.end;%0A%09%09%09%09%09%09%09%09%09%09%09%0A%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%09%0A%09%09%09%09%09%09%09%0A%09%09%09%09%09%09%09%09%09%0A%09%09%09return node;%0A%09%09 114 | %09%09%09%09 115 | +%09%09%09%0A 116 | %09%09%7D else %7B%0A 117 | -%09%09%09%09 118 | %09%09%09node. 119 | @@ -7533,36 +7533,32 @@ 120 | ype = %22string%22;%0A 121 | -%09%09%09%09 122 | %09%09%09node.value = 123 | @@ -7567,43 +7567,27 @@ 124 | rue%22;%0A%09%09 125 | -%09%09%09%09%7D%0A%09%09%09%09%09%7D%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D 126 | +%7D%0A%09%09%0A%09%09%0A%09%0A%09 127 | %0A%09%7D else 128 | @@ -7700,16 +7700,19 @@ 129 | node;%0A%7D; 130 | -%0A 131 | +%0D%0A%0D 132 | %0A%7D)();%0A 133 | +%09 134 | -------------------------------------------------------------------------------- /plugins/ebalster_attribute-modules/$__plugins_ebalster_attribute-modules_patch_core_modules_utils_parseutils.js.meta: -------------------------------------------------------------------------------- 1 | created: 20200428232337462 2 | modified: 20200428232337487 3 | modloader-source: $:/core 4 | modloader-target: $:/core/modules/utils/parseutils.js 5 | title: $:/plugins/ebalster/attribute-modules/patch/core/modules/utils/parseutils.js 6 | type: text/x-patch -------------------------------------------------------------------------------- /plugins/ebalster_attribute-modules/$__plugins_ebalster_attribute-modules_patch_core_modules_widgets_widget.js: -------------------------------------------------------------------------------- 1 | @@ -2240,32 +2240,184 @@ 2 | ;%0A%09%09%09%7D%0A%09%09%7D);%0A%09%7D%0A 3 | +%09// Hashmap of the attribute classes%0A%09if(!this.attributeClasses) %7B%0A%09%09Widget.prototype.attributeClasses = $tw.modules.applyMethods(%22attributevalue%22);%0A%09%7D%0A 4 | %7D;%0D%0A%0D%0A/*%0ARender 5 | @@ -9043,32 +9043,130 @@ 6 | this,%0A%09%09value;%0A 7 | +%09if (!this.attributeGizmos) %7B%0A%09%09// First-time attribute preparation%0A%09%09this.attributeGizmos = %7B%7D;%0A%09 8 | %09$tw.utils.each( 9 | @@ -9224,501 +9224,1462 @@ 10 | me) %7B%0A%09%09 11 | -if( 12 | +%09// Does the 13 | attribute 14 | -. 15 | + 16 | type 17 | -=== %22filtered%22) %7B%0A%09%09%09value = self.wiki.filterTiddlers(attribute.filter,self)%5B0%5D %7C%7C %22%22;%0A%09%09%7D else if(attribute.type === %22indirect%22) %7B 18 | +have a known module?%0A%09%09%09var AttributeClass = self.attributeClasses%5Battribute.type%5D;%0A%09%09%09if (AttributeClass) %7B%0A%09%09%09%09// Instantiate an attribute object.%0A%09%09%09%09self.attributeGizmos%5Bname%5D = new AttributeClass(self,attribute); 19 | %0A%09%09%09 20 | +%09 21 | value = self. 22 | -wiki.getTextReference(attribute.textReference,%22%22,self.getVariable(%22currentTiddler%22) 23 | +attributeGizmos%5Bname%5D.value;%0A%09%09%09%7D%0A%09%09%09else %7B%0A%09%09%09%09// Unknown attribute types are treated as strings.%0A%09%09%09%09// String attributes don't change after the first computeAttributes().%0A%09%09%09%09value = attribute.value;%0A%09%09%09%7D%0A%09%09%09// Is the value changed?%0A%09%09%09if (self.attributes%5Bname%5D !== value) %7B%0A%09%09%09%09self.attributes%5Bname%5D = value;%0A%09%09%09%09changedAttributes%5Bname%5D = true;%0A%09%09%09%7D%0A%09%09%09return true;%0A%09%09%7D 24 | );%0A 25 | -%09 26 | %09%7D 27 | - 28 | else 29 | -if(attribute.type === %22macro%22) %7B%0A%09%09%09value = self.getVariable(attribute.value.name,%7Bparams: attribute.value.params%7D);%0A%09%09%7D else %7B // String attribute%0A%09%09%09value = attribute.value;%0A%09%09%7D%0A%09%09// Check whether the attribute has changed 30 | +%7B%0A%09%09// Fully recompute all dynamic attributes (no selectivity is available)%0A%09%09$tw.utils.each(this.attributeGizmos,function(gizmo,name) %7B%0A%09%09%09value = gizmo.compute();%0A%09%09%09if(self.attributes%5Bname%5D !== value) %7B%0A%09%09%09%09self.attributes%5Bname%5D = value;%0A%09%09%09%09changedAttributes%5Bname%5D = true;%0A%09%09%09%7D%0A%09%09%7D);%0A%09%7D%0A%09return changedAttributes;%0A%7D;%0D%0A%0D%0A/*%0ASelectively re-compute previously computed attributes. Returns a hashmap of the names of the attributes that have changed%0A*/%0AWidget.prototype.refreshAttributes = function(changedTiddlers) %7B%0A%09if (!this.attributeGizmos) return computeAttributes();%0A%09var changedAttributes = %7B%7D,%0A%09%09self = this,%0A%09%09value;%0A%09// Fully recompute all dynamic attributes (no selectivity is available)%0A%09$tw.utils.each(this.attributeGizmos,function(gizmo,name) %7B%0A%09%09value = gizmo.refresh(changedTiddlers); 31 | %0A%09%09if(se 32 | -------------------------------------------------------------------------------- /plugins/ebalster_attribute-modules/$__plugins_ebalster_attribute-modules_patch_core_modules_widgets_widget.js.meta: -------------------------------------------------------------------------------- 1 | created: 20201208032458753 2 | creator: Joshua Fontany 3 | modified: 20201208032458793 4 | modifier: Joshua Fontany 5 | modloader-source: $:/core 6 | modloader-target: $:/core/modules/widgets/widget.js 7 | title: $:/plugins/ebalster/attribute-modules/patch/core/modules/widgets/widget.js 8 | type: text/x-patch -------------------------------------------------------------------------------- /plugins/ebalster_attribute-modules/plugin.info: -------------------------------------------------------------------------------- 1 | { 2 | "title": "$:/plugins/ebalster/attribute-modules", 3 | "created": "2017-12-25T05:48:46.674Z", 4 | "modified": "2020-04-17T00:00:01Z", 5 | "plugin-type": "plugin", 6 | "revision": "0", 7 | "version": "0.1.2", 8 | "core-version": ">=5.1.23" 9 | } -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_compute.js.tid: -------------------------------------------------------------------------------- 1 | created: 20180114170308058 2 | description: 3 | modified: 20180114170348576 4 | module-type: library 5 | revision: 0 6 | tags: 7 | title: $:/plugins/ebalster/formula/compute.js 8 | type: application/javascript 9 | 10 | (function(){ 11 | 12 | "use strict"; 13 | 14 | var Nodes = require("$:/plugins/ebalster/formula/nodes.js"); 15 | var Compiler = require("$:/plugins/ebalster/formula/compile.js"); 16 | var Coerce = require("$:/plugins/ebalster/formula/coerce.js"); 17 | 18 | var Numeral = require("$:/plugins/ebalster/formula/lib/numeral.js"); 19 | 20 | // TiddlyWiki array format 21 | function arrayFormatTW(arr,ctx) { 22 | var result = ""; 23 | for (var i = 0; i < arr.length; ++i) { 24 | var part = Coerce.ToText(arr[i],ctx); 25 | if (i && part.length) result += " "; 26 | if (part.indexOf(/\s/g) >= 0) result += "[[" + part + "]]"; 27 | else result += part; 28 | } 29 | return result; 30 | } 31 | 32 | // Number format functions... 33 | 34 | // SANE number formatting: if we find five consecutive 9s or 0s after the decimal point, round them off. 35 | function NumberStringSane(n) { 36 | var s = String(n); 37 | var parse = /^(0\.0*[1-9]\d*?|\d*\.\d*?)(0{5}\d*|9{5}\d*)(|e[+-]\d*)$/.exec(s); 38 | if (!parse) return s; 39 | var kept = parse[1], exp = parse[3]; 40 | var end = kept.slice(-1); 41 | if (parse[2][0] === '0') return ((end === '.') ? kept.substr(0,kept.length-1) : kept) + exp; 42 | if (end === '.') return (Number(kept.substr(0,kept.length-1))+1) + exp; 43 | return kept.substr(0,kept.length-1) + (Number(end)+1) + exp; 44 | } 45 | var numeralFormat = function(fmt) {return function(num) {return Numeral(num).format(fmt);};}; 46 | var numeralFormatPrec = function(fmt,digs) {return function(num) {return Numeral(num.toPrecision(digs)).format(fmt);};}; 47 | var numberFormatFixed = function(prec) {return function(num) {return num.toFixed (prec);};}; 48 | var numberFormatPrec = function(digs) {return function(num) {return num.toPrecision(digs);};}; 49 | var numberFormatSelect = function(settings) 50 | { 51 | if (settings.precision == "true" || settings.precision > 100) return String; 52 | if (typeof settings.numberFormat == "string") { 53 | // Use numeral 54 | return isNaN(settings.precision) ? 55 | numeralFormat (settings.numberFormat) : 56 | numeralFormatPrec(settings.numberFormat, settings.precision); 57 | } 58 | if (!isNaN(settings.fixed)) return numberFormatFixed(settings.fixed); 59 | if (!isNaN(settings.precision)) return numberFormatPrec (settings.precision); 60 | return NumberStringSane; 61 | // return String; 62 | }; 63 | 64 | exports.computeFormula = function(compiledFormula, widget, formatOptions, debug) { 65 | 66 | var value, context; 67 | 68 | formatOptions = formatOptions || {}; 69 | 70 | var dateFormat = formatOptions.dateFormat || "0hh:0mm, DDth MMM YYYY"; 71 | 72 | // Specify format. These are all required! 73 | var formats = { 74 | number: numberFormatSelect(formatOptions), 75 | date: function(date) {return $tw.utils.formatDateString(date, dateFormat);}, 76 | array: arrayFormatTW, 77 | }; 78 | 79 | context = new Nodes.Context(widget, formats); 80 | 81 | // Compute a value from the root node of the compiled formula. 82 | try { 83 | value = compiledFormula.computeText(context); 84 | } 85 | catch (err) { 86 | throw "ComputeError: " + String(err) + (err.fileName || "") + (err.lineNumber || "") 87 | + (debug ? "\nNodes: " + JSON.stringify(compiledFormula) : ""); 88 | } 89 | 90 | // Format the root node as a string. 91 | if (debug) return value + "\n - Val:" + String(value) + ", Op:" + compiledFormula.name; 92 | else return value; 93 | }; 94 | 95 | exports.evalFormula = function(formulaString, widget, formatOptions, debug) { 96 | 97 | var compiledFormula; 98 | 99 | // Compile the formula 100 | try { 101 | compiledFormula = Compiler.compileExpression(formulaString); 102 | } 103 | catch (err) { 104 | throw "CompileError: " + String(err); 105 | } 106 | 107 | // Compute the formula 108 | return exports.computeFormula(compiledFormula, widget, formatOptions, debug); 109 | }; 110 | 111 | })(); 112 | -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_functions_arithmetic.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171211192843088 2 | modified: 20171212223526867 3 | module-type: formula-function 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/formula/functions/arithmetic.js 7 | type: application/javascript 8 | 9 | (function(){ 10 | 11 | /*jslint node: true, browser: true */ 12 | /*global $tw: false */ 13 | "use strict"; 14 | 15 | 16 | // Unary sign operators 17 | exports.uplus = function(a) {return a;}; 18 | exports.uminus = function(a) {return -a;}; 19 | exports.uminus.inCast = 'N'; 20 | 21 | // Add 22 | exports.add = function(a, b) {return a + b;}; 23 | exports.add.inCast = 'NN'; 24 | exports.sub = function(a, b) {return a - b;}; 25 | exports.sub.inCast = 'NN'; 26 | 27 | // Multiply 28 | exports.mul = function(a, b) {return a * b;}; 29 | exports.mul.inCast = 'NN'; 30 | exports.div = function(a, b) {return a / b;}; 31 | exports.div.inCast = 'NN'; 32 | 33 | // Percent -- TODO make this a different value-type 34 | exports.percent = function(a) {return a / 100;}; 35 | exports.percent.inCast = 'N'; 36 | 37 | 38 | // Aliases 39 | exports.subtract = exports.sub; 40 | exports.minus = exports.sub; 41 | exports.multiply = exports.mul; 42 | exports.divide = exports.div; 43 | exports.quotient = exports.div; 44 | exports.power = exports.pow; 45 | 46 | 47 | })(); -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_functions_arrays.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171219014903147 2 | modified: 20171219014910148 3 | module-type: formula-function 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/formula/functions/arrays.js 7 | type: application/javascript 8 | 9 | (function(){ 10 | 11 | /*jslint node: true, browser: true */ 12 | /*global $tw: false */ 13 | "use strict"; 14 | 15 | 16 | // Array constructor function 17 | exports.array = function() { 18 | return Array.prototype.slice.call(arguments); 19 | }; 20 | exports.array.variadic = true; 21 | 22 | 23 | exports.nth = function(a, i) { 24 | i = Math.floor(i); 25 | if (i < 1 || i > a.length) return undefined; 26 | return a[i-1]; 27 | }; 28 | exports.nth.inCast = 'AN'; 29 | 30 | exports.first = function(a) { 31 | if (a.length) return a[0]; 32 | return undefined; 33 | }; 34 | exports.first.inCast = 'A'; 35 | 36 | exports.last = function(a) { 37 | if (a.length) return a[a.length-1]; 38 | return undefined; 39 | }; 40 | exports.last.inCast = 'A'; 41 | 42 | // MAP function 43 | exports.map = function(f, a) { 44 | if (f.min_args > 1 || f.max_args < 1) throw "MAP requires single-argument function."; 45 | var result = []; 46 | var func = f.bind(this); 47 | for (var i = 0; i < a.length; ++i) result.push(func(a[i])); 48 | return result; 49 | }; 50 | exports.map.inCast = 'FA'; 51 | 52 | 53 | /* 54 | Counting subroutines... 55 | countA counts every non-array value 56 | countS counts every non-array value but null, undefined and empty strings. 57 | */ 58 | function countS(a) { 59 | if (!(a instanceof Array)) return (a == null || a.length === 0) ? 0 : 1; 60 | var n = 0; 61 | for (var i = 0; i < a.length; ++i) n += countS(a[i]); 62 | return n; 63 | } 64 | function countA(a) { 65 | if (!(a instanceof Array)) return 1; 66 | var n = 0; 67 | for (var i = 0; i < a.length; ++i) n += countA(a[i]); 68 | return n; 69 | } 70 | function countS_multi() { 71 | var n = 0; 72 | for (var i = 0; i < arguments.length; ++i) n += countS(arguments[i]); 73 | return n; 74 | } 75 | function countA_multi() { 76 | var n = 0; 77 | for (var i = 0; i < arguments.length; ++i) n += countA(arguments[i]); 78 | return n; 79 | } 80 | exports.count = 81 | { 82 | min_args : 1, 83 | select : function(operands) 84 | { 85 | switch (operands) 86 | { 87 | case 1: return countS; 88 | default: return countS_multi; 89 | } 90 | } 91 | }; 92 | exports.counta = 93 | { 94 | min_args : 1, 95 | select : function(operands) 96 | { 97 | switch (operands) 98 | { 99 | case 1: return countA; 100 | default: return countA_multi; 101 | } 102 | } 103 | }; 104 | 105 | // COUNTA function, currently counts everything 106 | exports.counta = exports.count; 107 | 108 | 109 | })(); -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_functions_compare.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171214050022626 2 | modified: 20171214050803365 3 | module-type: formula-function 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/formula/functions/compare.js 7 | type: application/javascript 8 | 9 | (function(){ 10 | 11 | /*jslint node: true, browser: true */ 12 | /*global $tw: false */ 13 | "use strict"; 14 | 15 | 16 | // Equality 17 | exports.eq = function(a, b) {return a == b;}; 18 | exports.ne = function(a, b) {return a != b;}; 19 | 20 | // Inequality 21 | exports.gt = function(a, b) {return a > b;}; 22 | exports.gte = function(a, b) {return a >= b;}; 23 | exports.lt = function(a, b) {return a < b;}; 24 | exports.lte = function(a, b) {return a <= b;}; 25 | 26 | 27 | // Aliases 28 | exports.equal = exports.eq; 29 | exports.not_equal = exports.ne; 30 | exports.greater = exports.gt; 31 | exports.greater_or_equal = exports.gte; 32 | exports.less = exports.lt; 33 | exports.less_or_equal = exports.lte; 34 | 35 | 36 | })(); -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_functions_logic.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171214054240274 2 | modified: 20171214060456114 3 | module-type: formula-function 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/formula/functions/logic.js 7 | type: application/javascript 8 | 9 | (function(){ 10 | 11 | /*jslint node: true, browser: true */ 12 | /*global $tw: false */ 13 | "use strict"; 14 | 15 | var Node = require("$:/plugins/ebalster/formula/nodes.js").Node; 16 | 17 | 18 | // Constants 19 | exports.true = function() {return true;}; 20 | exports.false = function() {return false;}; 21 | 22 | exports.true.isConstant = true; 23 | exports.false.isConstant = true; 24 | 25 | // Logical operators 26 | exports.not = function(a) {return !a;}; 27 | exports.not.inCast = 'B'; 28 | exports.and = function(a, b) {return a && b;}; 29 | exports.and.inCast = 'BB'; 30 | exports.or = function(a, b) {return a || b;}; 31 | exports.or .inCast = 'BB'; 32 | exports.xor = function(a, b) {return a ? !b : b;}; 33 | exports.xor.inCast = 'BB'; 34 | 35 | // Ternary 36 | function IfNode(pred, tval, fval) { 37 | this.pred = pred; 38 | this.tval = tval; 39 | this.fval = fval; 40 | } 41 | IfNode.prototype = new Node(); 42 | IfNode.prototype.name = "if"; 43 | IfNode.prototype.compute = (function(ctx) { 44 | return (this.pred.computeBool(ctx) ? this.tval.compute(ctx) : this.fval.compute(ctx)); 45 | }); 46 | exports.if = { 47 | min_args: 3, max_args: 3, 48 | construct: function(operands) { 49 | return new IfNode(operands[0], operands[1], operands[2]); 50 | } 51 | }; 52 | 53 | 54 | // IFERROR 55 | /*exports.iferror = { 56 | min_args = 2, max_args = 2, 57 | func = function(a, b) { 58 | select: function(operands) { 59 | try {return a.compute();} 60 | catch (err) {return b.compute();} 61 | } 62 | };*/ 63 | 64 | 65 | // SWITCH (variadic) 66 | exports.switch = 67 | { 68 | min_args: 3, 69 | select: function(operands) 70 | { 71 | switch (operands.length % 2) 72 | { 73 | default: 74 | case 0: return function(a) // Switch with default 75 | { 76 | var value = a; 77 | for (var i = 1; i+1 < arguments.length; i += 2) 78 | {if (arguments[i] == value) return arguments[i+1];} 79 | return arguments[arguments.length-1]; 80 | }; 81 | case 1: return function(a) // Switch, no default 82 | { 83 | var value = a; 84 | for (var i = 1; i+1 < arguments.length; i += 2) 85 | {if (arguments[i] == value) return arguments[i+1];} 86 | return undefined; 87 | }; 88 | } 89 | } 90 | }; 91 | 92 | // CHOOSE (variadic) 93 | exports.choose = function(a, b) 94 | { 95 | var index = Math.floor(a); 96 | var result = arguments[index]; 97 | if (index < 1 || !result) return undefined; 98 | return result; 99 | }; 100 | exports.choose.inCast = 'N'; 101 | exports.choose.variadic = true; 102 | 103 | // IFS function (variadic) 104 | function ifsFunc() { 105 | for (var i = 0; i < arguments.length; i += 2) 106 | {if (arguments[i]) return arguments[i+1];} 107 | return undefined; 108 | }; 109 | ifsFunc.inCast = '+B_'; 110 | 111 | exports.ifs = 112 | { 113 | min_args : 2, 114 | input: '+B_', 115 | select : function(operands) { 116 | if (operands.length % 2 !== 0) throw "Odd number of arguments to IFS"; 117 | return ifsFunc; 118 | } 119 | }; 120 | 121 | })(); -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_functions_regexp.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171220230845098 2 | modified: 20171220230855457 3 | module-type: formula-function 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/formula/functions/regexp.js 7 | type: application/javascript 8 | 9 | (function(){ 10 | 11 | /*jslint node: true, browser: true */ 12 | /*global $tw: false */ 13 | "use strict"; 14 | 15 | 16 | // Compile regex. TODO: Precompile these where possible 17 | /*var TW_RX_FLAGS = /^\(\?[a-z]*\)|\(\?[a-z]*\)$/i; 18 | 19 | function tw_regex(rx_str, defaultFlags) { 20 | if (!rx_str) throw "Empty regular expression"; 21 | var flagPart = TW_RX_FLAGS.exec(rx_str); 22 | if (flagPart) { 23 | var flagLen = flagPart[0].length; 24 | var flags = flagPart[0].substr(2, flagPart[0].length-3); 25 | if (flagPart.index == 0) return new RegExp(rx_str.substr(flagLen), flags); 26 | else return new RegExp(rx_str.substr(0, rx_str.length-flagLen), flags); 27 | } 28 | return new RegExp(rx_str, defaultFlags); 29 | }*/ 30 | 31 | 32 | // Regex replace 33 | exports.regexreplace = function(s, rx, b) { 34 | //rx = tw_regex(rx, "g"); 35 | rx.lastIndex = 0; 36 | return s.replace(rx, b); 37 | }; 38 | exports.regexreplace.inCast = 'TRT'; 39 | 40 | // Regex match 41 | exports.regexmatch = function(s, rx) { 42 | //rx = tw_regex(rx, ""); 43 | rx.lastIndex = 0; 44 | return rx.test(s); 45 | }; 46 | exports.regexmatch.inCast = 'TR'; 47 | 48 | // Regex extract 49 | function regexextract(s, rx) { 50 | //rx = tw_regex(rx, "g"); 51 | rx.lastIndex = 0; 52 | s = s; 53 | var captureIndex = arguments[2] || 0; 54 | var matches = []; 55 | var match; 56 | while ((match = rx.exec(s)) != null) { 57 | if (match[0].length == 0) ++rx.lastIndex; 58 | matches.push(match[captureIndex] || ""); 59 | if (!rx.global) break; 60 | } 61 | return matches; 62 | } 63 | regexextract.inCast = 'TRN'; 64 | 65 | exports.regexextract = { 66 | min_args: 2, max_args: 3, 67 | select: function(operands) {return regexextract;} 68 | }; 69 | 70 | // Regex extract, single argument 71 | function regexextract1(s, rx, dfl) { 72 | //rx = tw_regex(rx, ""); 73 | rx.lastIndex = 0; 74 | s = s; 75 | var captureIndex = arguments[3] || 0; 76 | var match = rx.exec(s); 77 | return (match && match[captureIndex]) ? match[captureIndex] : dfl; 78 | } 79 | regexextract1.inCast = 'TRTN'; 80 | 81 | exports.regexextract1 = { 82 | min_args: 3, max_args: 4, 83 | select: function(operands) {return regexextract1;} 84 | }; 85 | 86 | })(); -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_functions_strings.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171213003135495 2 | modified: 20171213003237206 3 | module-type: formula-function 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/formula/functions/strings.js 7 | type: application/javascript 8 | 9 | (function(){ 10 | 11 | /*jslint node: true, browser: true */ 12 | /*global $tw: false */ 13 | "use strict"; 14 | 15 | var Coerce = require("$:/plugins/ebalster/formula/coerce.js"); 16 | 17 | 18 | // Cast to text. Second argument not yet supported. 19 | exports.t = function(a) {return a;}; 20 | exports.t.inCast = 'T'; 21 | 22 | function t_format(a, format) {return a;} 23 | t_format.inCast = 'TT'; 24 | 25 | exports.text = { 26 | min_args: 1, max_args: 1, 27 | input: 'TT', 28 | select: function(operands) { 29 | if (operands.length == 1) return exports.t; 30 | return t_format; 31 | } 32 | }; 33 | 34 | // Cast string to number. 35 | exports.value = function(a) {return a;}; 36 | exports.inCast = 'N'; 37 | 38 | // Array to string 39 | var JoinFunc = function(delimiter, ignore_empty, array, startIndex) { 40 | var join = "", part; 41 | for (var i = startIndex; i < array.length; ++i) 42 | { 43 | var arg = array[i]; 44 | if (arg instanceof Array) { 45 | part = JoinFunc(delimiter, ignore_empty, arg, 0); 46 | } 47 | else { 48 | part = Coerce.ToText(arg,this); 49 | } 50 | if (part.length || !ignore_empty) { 51 | if (join.length) join += delimiter; 52 | join += part; 53 | } 54 | } 55 | return join; 56 | }; 57 | 58 | // Join 59 | exports.join = function(delimiter) { 60 | return JoinFunc.call(this, delimiter, false, arguments, 1); 61 | }; 62 | exports.join.variadic = true; 63 | exports.join.inCast = 'T'; 64 | 65 | // Textjoin 66 | exports.textjoin = function(delimiter, ignore_empty) { 67 | return JoinFunc.call(this, delimiter, ignore_empty, arguments, 2); 68 | }; 69 | exports.textjoin.variadic = true; 70 | exports.textjoin.inCast = 'T'; 71 | 72 | // Split string to array 73 | exports.split = function(str, delimiter) { 74 | return str.split(delimiter); 75 | }; 76 | exports.split.inCast = 'T'; 77 | 78 | // String length 79 | exports.len = function(str) {return str.length;}; 80 | exports.len.inCast = 'T'; 81 | 82 | // String exact match 83 | exports.exact = function(a, b) {return a === b;}; 84 | exports.exact.inCast = 'TT'; 85 | 86 | 87 | // Substrings 88 | exports.mid = function(str, i, n) {return str.substr(i-1, n);}; 89 | exports.exact.inCast = 'TNN'; 90 | 91 | exports.substr = exports.mid; 92 | 93 | 94 | // Substitute 95 | exports.substitute = function(s, f, r) {return s.split(f).join(r);}; 96 | exports.substitute.inCast = 'TTT'; 97 | 98 | // Replace (N/I) 99 | //exports.replace = function(s, p, l, r) {return (s.splice(a, b));}; 100 | 101 | 102 | // Concatenate 103 | exports.cat = function(a, b) {return a + b;}; 104 | exports.cat.inCast = 'TT'; 105 | 106 | // Trim space 107 | exports.trim = function(a) {return a.split(/^\s+|\s+$/g).join("");}; 108 | exports.trim.inCast = 'T'; 109 | 110 | 111 | // Aliases 112 | exports.concatenate = exports.cat; 113 | 114 | 115 | })(); -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_functions_wiki.js.tid: -------------------------------------------------------------------------------- 1 | created: 20180108011928370 2 | modified: 20180108012007186 3 | module-type: formula-function 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/formula/functions/wiki.js 7 | type: application/javascript 8 | 9 | (function(){ 10 | 11 | /*jslint node: true, browser: true */ 12 | /*global $tw: false */ 13 | "use strict"; 14 | 15 | var Nodes = require("$:/plugins/ebalster/formula/nodes.js"); 16 | 17 | 18 | // Get variable string by name. 19 | exports.transclude = { 20 | min_args: 1, max_args: 2, 21 | construct: function(operands) { 22 | switch (operands.length) { 23 | case 1: return new Nodes.TranscludeText(operands[0]); 24 | case 2: return new Nodes.TranscludeField(operands[0], operands[1]); 25 | } 26 | } 27 | }; 28 | 29 | // Transclude tiddler text string by name. 30 | exports.transclude_index = { 31 | min_args: 2, max_args: 2, 32 | construct: function(operands) {return new Nodes.TranscludeIndex(operands[0], operands[1]);} 33 | }; 34 | 35 | // Transclude field string by name. 36 | exports.variable = { 37 | min_args: 1, max_args: 1, 38 | construct: function(operands) {return new Nodes.Variable(operands[0]);} 39 | }; 40 | 41 | // Interpret value as a datum. 42 | exports.datum = { 43 | min_args: 1, max_args: 1, 44 | construct: function(operands) {return new Nodes.Datum(operands[0]);} 45 | }; 46 | 47 | 48 | })(); -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_license.tid: -------------------------------------------------------------------------------- 1 | caption: license 2 | created: 20171220071005710 3 | modified: 20171220211838536 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/formula/license 7 | type: text/vnd.tiddlywiki 8 | 9 | !!The MIT License (MIT) 10 | 11 | Copyright (c) 2017 Evan Balster 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy of 14 | this software and associated documentation files (the "Software"), to deal in 15 | the Software without restriction, including without limitation the rights to 16 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 17 | the Software, and to permit persons to whom the Software is furnished to do so, 18 | subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 25 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 26 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 27 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 28 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_macros_formula.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171210215758530 2 | modified: 20171212194124031 3 | module-type: macro 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/formula/macros/formula.js 7 | type: application/javascript 8 | 9 | (function(){ 10 | 11 | /*jslint node: true, browser: true */ 12 | /*global $tw: false */ 13 | "use strict"; 14 | 15 | var Compute = require("$:/plugins/ebalster/formula/compute.js"); 16 | 17 | /* 18 | Information about this macro 19 | */ 20 | 21 | exports.name = "formula"; 22 | exports.params = [{"name": "formula"}]; 23 | 24 | /* 25 | Run the macro 26 | */ 27 | exports.run = function(formula) { 28 | 29 | try { 30 | return Compute.evalFormula(formula, this); 31 | } 32 | catch (err) { 33 | return "`" + String(err) + "`"; 34 | } 35 | }; 36 | 37 | })(); 38 | -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_operators_arithmetic.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171212223503019 2 | modified: 20171212223539769 3 | module-type: formula-operator 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/formula/operators/arithmetic.js 7 | type: application/javascript 8 | 9 | (function(){ 10 | 11 | /*jslint node: true, browser: true */ 12 | /*global $tw: false */ 13 | "use strict"; 14 | 15 | // Unary sign operators 16 | exports.uplus = {arity: 1, position: "pre", operator: "+", function: "uplus"}; 17 | exports.uminus = {arity: 1, position: "pre", operator: "-", function: "uminus"}; 18 | 19 | // Add 20 | exports.plus = {arity: 2, precedence: 10, operator: "+", function: "add"}; 21 | exports.minus = {arity: 2, precedence: 10, operator: "-", function: "sub"}; 22 | 23 | // Multiply 24 | exports.multiply = {arity: 2, precedence: 20, operator: "*", function: "mul"}; 25 | exports.divide = {arity: 2, precedence: 20, operator: "/", function: "div"}; 26 | 27 | // Exponential 28 | exports.pow = {arity: 2, precedence: 30, operator: "^", function: "pow", associativity: "right"}; 29 | 30 | // Percentage 31 | exports.percent = {arity: 1, position: "post", operator: "%", function: "percent"}; 32 | 33 | })(); -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_operators_compare.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171214050556123 2 | modified: 20171214050739104 3 | module-type: formula-operator 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/formula/operators/compare.js 7 | type: application/javascript 8 | 9 | (function(){ 10 | 11 | /*jslint node: true, browser: true */ 12 | /*global $tw: false */ 13 | "use strict"; 14 | 15 | // Equality 16 | exports.eq = {arity: 2, precedence: 0, operator: "=", function: "eq"}; 17 | exports.ne = {arity: 2, precedence: 0, operator: "<>", function: "ne"}; 18 | 19 | // Inequality 20 | exports.gt = {arity: 2, precedence: 0, operator: ">", function: "gt"}; 21 | exports.gte = {arity: 2, precedence: 0, operator: ">=", function: "gte"}; 22 | exports.lt = {arity: 2, precedence: 0, operator: "<", function: "lt"}; 23 | exports.lte = {arity: 2, precedence: 0, operator: "<=", function: "lte"}; 24 | 25 | })(); -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_operators_strings.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171213003246267 2 | modified: 20171213003346943 3 | module-type: formula-operator 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/formula/operators/strings.js 7 | type: application/javascript 8 | 9 | (function(){ 10 | 11 | /*jslint node: true, browser: true */ 12 | /*global $tw: false */ 13 | "use strict"; 14 | 15 | 16 | // Concatenate 17 | exports.concatenate = {arity: 2, precedence: 4, operator: "&", function: "cat"}; 18 | 19 | })(); -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_readme.tid: -------------------------------------------------------------------------------- 1 | caption: readme 2 | created: 20171220042006170 3 | modified: 20171220212520970 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/formula/readme 7 | type: text/vnd.tiddlywiki 8 | 9 | ''Formula'' for TiddlyWiki, version {{$:/plugins/ebalster/formula!!version}}, by Evan Balster. Updated by [[Joshua Fontany||https://joshuafontany.github.com/]] 10 | 11 | Formulas are written between `(=` mushroom brackets `=)`. Where possible, their functions and syntax are designed to emulate popular spreadsheet software (Microsoft Excel and Google Sheets). They //also// support WikiText-like syntax for `{{`transclusion`}}`, `[`filters`]`, `<<`variables`>>`, and a large number of functions. 12 | 13 | Formulas can also be evaluated by the `$formula` widget, the `$formula-vars` widget and the `<>` macro. 14 | 15 | Further documentation is available here: [[https://evanbalster.com/tiddlywiki/formulas.html]]. 16 | 17 | This plugin is a work in progress; please report any issues on GitHub: [[https://github.com/EvanBalster/TiddlyWikiFormula/issues]]. -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_settings.tid: -------------------------------------------------------------------------------- 1 | caption: readme 2 | created: 20171221001634811 3 | modified: 20171221002035357 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/formula/settings 7 | type: text/vnd.tiddlywiki 8 | 9 | Currently no global settings are implemented, but formulas can be controlled by setting some global macros. For example: 10 | 11 | |Macro|Meaning|h 12 | |`\define formulaFixed() 2`|makes numbers display with 2 decimal points.| 13 | |`\define formulaPrecision() 4`|makes numbers display with 4 significant digits (but `formulafixed` takes priority.| 14 | |`\define formulaDateFormat() YYYY-MM-0DD`|Sets a date display format using the same rules as TiddlyWiki.| 15 | 16 | Place these at the top of the tiddler where they should take effect, or create a tiddler tagged with <> to make them apply to all tiddlers. 17 | 18 | In the future, we'll probably add some global settings here... -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_widgets_attributes_formula.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171225035721011 2 | description: Evaluates a formula as an attribute value string. 3 | modified: 20171225035808674 4 | module-type: attributevalue 5 | revision: 0 6 | tags: 7 | title: $:/plugins/ebalster/formula/widgets/attributes/formula.js 8 | type: application/javascript 9 | 10 | (function(){ 11 | 12 | /*jslint node: true, browser: true */ 13 | /*global $tw: false */ 14 | "use strict"; 15 | 16 | var Compile = require("$:/plugins/ebalster/formula/compile.js"); 17 | var Compute = require("$:/plugins/ebalster/formula/compute.js"); 18 | var Nodes = require("$:/plugins/ebalster/formula/nodes.js"); 19 | 20 | var FormulaAttribute = function(widget, node) { 21 | this.widget = widget; 22 | this.formula = node.formula; 23 | try { 24 | this.compiledFormula = Compile.compileFormula(this.formula); 25 | } 26 | catch (err) { 27 | this.compiledFormula = new Nodes.ThrowError(err); 28 | } 29 | this.value = this.compute(); 30 | }; 31 | 32 | /* 33 | Inherit from the base ??? class 34 | */ 35 | //FormulaAttribute.prototype = new Attribute(); 36 | 37 | FormulaAttribute.prototype.compute = function() { 38 | // Compute options 39 | this.formatOptions = 40 | { 41 | fixed: (this.widget.getVariable("formulaFixed")), 42 | precision: (this.widget.getVariable("formulaPrecision")), 43 | numberFormat: (this.widget.getVariable("formulaNumberFormat")), 44 | dateFormat: (this.widget.getVariable("formulaDateFormat")), 45 | }; 46 | // Execute the formula. 47 | try { 48 | return Compute.computeFormula(this.compiledFormula, this.widget, this.formatOptions); 49 | } 50 | catch (err) { 51 | return ""; 52 | } 53 | }; 54 | 55 | FormulaAttribute.prototype.refresh = function(changedTiddlers) { 56 | this.value = this.compute(); 57 | return this.value; 58 | }; 59 | 60 | 61 | exports.formula = FormulaAttribute; 62 | 63 | })(); 64 | -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_widgets_formula-vars.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171216003055342 2 | description: As the $vars widget, but each attribute is interpreted as a formula. 3 | modified: 20171222071557661 4 | module-type: widget 5 | revision: 0 6 | tags: 7 | title: $:/plugins/ebalster/formula/widgets/formula-vars.js 8 | type: application/javascript 9 | 10 | (function(){ 11 | 12 | /*jslint node: true, browser: true */ 13 | /*global $tw: false */ 14 | "use strict"; 15 | 16 | var Widget = require("$:/core/modules/widgets/widget.js").widget; 17 | 18 | var Compile = require("$:/plugins/ebalster/formula/compile.js"); 19 | var Compute = require("$:/plugins/ebalster/formula/compute.js"); 20 | 21 | var FormulaVarsWidget = function(parseTreeNode,options) { 22 | // Call the constructor 23 | Widget.call(this); 24 | // Initialise 25 | this.initialise(parseTreeNode,options); 26 | }; 27 | 28 | /* 29 | Inherit from the base widget class 30 | */ 31 | FormulaVarsWidget.prototype = Object.create(Widget.prototype); 32 | 33 | /* 34 | Render this widget into the DOM 35 | */ 36 | FormulaVarsWidget.prototype.render = function(parent,nextSibling) { 37 | this.parentDomNode = parent; 38 | this.computeAttributes(); 39 | this.execute(); 40 | 41 | if (this.formulaError) { 42 | // Show an error. 43 | var parseTreeNodes = [{type: "element", tag: "span", attributes: { 44 | "class": {type: "string", value: "tc-error"} 45 | }, children: [ 46 | {type: "text", text: this.formulaError} 47 | ]}]; 48 | this.makeChildWidgets(parseTreeNodes); 49 | } 50 | else { 51 | // Construct and render the child widgets. 52 | this.makeChildWidgets(); 53 | } 54 | 55 | this.renderChildren(parent,nextSibling); 56 | }; 57 | 58 | /* 59 | Recompute formulas 60 | */ 61 | FormulaVarsWidget.prototype.formula_recompute = function() { 62 | // Parse variables 63 | var self = this; 64 | 65 | this.formatOptions = 66 | { 67 | fixed: (this.getAttribute("$fixed") || this.parentWidget.getVariable("formulaFixed")), 68 | precision: (this.getAttribute("$precision") || this.parentWidget.getVariable("formulaPrecision")), 69 | numberFormat: (this.getAttribute("$numberFormat") || this.parentWidget.getVariable("formulaNumberFormat")), 70 | dateFormat: (this.getAttribute("$dateFormat") || this.parentWidget.getVariable("formulaDateFormat")), 71 | }; 72 | 73 | // Deprecation 74 | if (this.getAttribute("$toFixed")) {this.formulaError = "Change '$toFixed' to '$fixed'."; return;} 75 | if (this.getAttribute("$toPrecision")) {this.formulaError = "Change '$toPrecision' to '$precision'."; return;} 76 | 77 | if (!this.currentValues) 78 | { 79 | // Initial values 80 | this.currentValues = {}; 81 | this.formulaSrc = {}; 82 | this.formulaComp = {}; 83 | } 84 | 85 | this.formulaError = null; 86 | 87 | try { 88 | if (this.getAttribute("$noRefresh")) throw "Illegal $noRefresh attribute; use $noRebuild instead."; 89 | 90 | $tw.utils.each(this.attributes,function(val,key) { 91 | if(key.charAt(0) !== "$") { 92 | // Recompile if necessary 93 | if (self.formulaSrc[key] != val) { 94 | self.formulaSrc[key] = val; 95 | try { 96 | self.formulaComp[key] = Compile.compileFormula(self.formulaSrc[key]); 97 | } 98 | catch (err) { 99 | self.formulaSrc[key] = null; 100 | throw "Variable " + key + ": " + String(err); 101 | } 102 | } 103 | // Recompute the formula 104 | if (self.formulaComp[key]) { 105 | try { 106 | self.currentValues[key] = Compute.computeFormula( 107 | self.formulaComp[key], self, self.formatOptions); 108 | } 109 | catch (err) { 110 | throw "Variable " + key + ": " + String(err); 111 | } 112 | } 113 | else { 114 | throw "Variable " + key + ": Formula not assigned"; 115 | } 116 | } 117 | }); 118 | } 119 | catch (err) { 120 | this.formulaError = String(err); 121 | } 122 | }; 123 | 124 | /* 125 | Compute the internal state of the widget 126 | */ 127 | FormulaVarsWidget.prototype.execute = function() { 128 | // Recompute formulas 129 | this.formula_recompute(); 130 | 131 | if (!this.formulaError) { 132 | for (var key in this.currentValues) { 133 | this.setVariable(key, this.currentValues[key]); 134 | } 135 | } 136 | }; 137 | 138 | /* 139 | Refresh the widget by ensuring our attributes are up to date 140 | */ 141 | FormulaVarsWidget.prototype.refresh = function formulaVarsRefresh(changedTiddlers) { 142 | this.computeAttributes(); 143 | var oldValues = Object.assign({}, this.currentValues || {}), oldError = this.formulaError; 144 | this.formula_recompute(); 145 | 146 | // Did any computed values change? 147 | var changedValues = false; 148 | for (var key in this.currentValues) { 149 | if (this.currentValues[key] !== oldValues[key]) { 150 | this.setVariable(key, this.currentValues[key]); 151 | changedValues = true; 152 | } 153 | } 154 | 155 | // Option to suppress full refreshing 156 | if (this.getAttribute("$noRebuild") === "true") changedValues = false; 157 | if (this.formulaError !== oldError) changedValues = true; 158 | 159 | if(changedValues) { 160 | // Regenerate and rerender the widget and replace the existing DOM node 161 | this.refreshSelf(); 162 | return true; 163 | } else { 164 | return this.refreshChildren(changedTiddlers); 165 | } 166 | }; 167 | 168 | exports["formula-vars"] = FormulaVarsWidget; 169 | 170 | })(); 171 | -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_widgets_formula.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171210232543292 2 | description: Evaluates a formula. 3 | modified: 20171212194059701 4 | module-type: widget 5 | revision: 0 6 | tags: 7 | title: $:/plugins/ebalster/formula/widgets/formula.js 8 | type: application/javascript 9 | 10 | (function(){ 11 | 12 | /*jslint node: true, browser: true */ 13 | /*global $tw: false */ 14 | "use strict"; 15 | 16 | var Widget = require("$:/core/modules/widgets/widget.js").widget; 17 | 18 | var Compile = require("$:/plugins/ebalster/formula/compile.js"); 19 | var Compute = require("$:/plugins/ebalster/formula/compute.js"); 20 | 21 | var FormulaWidget = function(parseTreeNode,options) { 22 | this.initialise(parseTreeNode,options); 23 | }; 24 | 25 | /* 26 | Inherit from the base widget class 27 | */ 28 | FormulaWidget.prototype = new Widget(); 29 | 30 | /* 31 | Render this widget into the DOM 32 | */ 33 | FormulaWidget.prototype.render = function(parent,nextSibling) { 34 | this.parentDomNode = parent; 35 | this.computeAttributes(); 36 | this.execute(); 37 | this.rerender(parent,nextSibling); 38 | }; 39 | 40 | FormulaWidget.prototype.rerender = function(parent, nextSibling) { 41 | 42 | this.removeChildDomNodes(); 43 | 44 | var parseTreeNodes; 45 | 46 | if (this.formulaError) { 47 | // Show an error as a tc-error span. 48 | parseTreeNodes = [{type: "element", tag: "span", attributes: { 49 | "class": {type: "string", value: "tc-error"} 50 | }, children: [ 51 | {type: "text", text: this.formulaError} 52 | ]}]; 53 | } 54 | else { 55 | // Parse the value, or, failing this, produce a text node. 56 | var parser = this.wiki.parseText( 57 | this.wikifyType, this.currentValue, 58 | {parseAsInline: this.wikifyMode === "inline"}); 59 | parseTreeNodes = (parser ? parser.tree : [{type: "text", text: this.currentValue}]); 60 | } 61 | 62 | // Construct and render the child widgets. 63 | this.makeChildWidgets(parseTreeNodes); 64 | this.renderChildren(parent,nextSibling); 65 | }; 66 | 67 | /* 68 | Compute the internal state of the widget 69 | */ 70 | FormulaWidget.prototype.execute = function() { 71 | 72 | var oldFormula = this.formula; 73 | 74 | // Get parameters from our attributes 75 | this.formula = this.getAttribute("formula"); 76 | this.debug = this.getAttribute("debug"); 77 | 78 | this.wikifyType = this.getAttribute("outputType"); 79 | this.wikifyMode = this.getAttribute("outputMode","inline"); 80 | 81 | this.formatOptions = 82 | { 83 | fixed: (this.getAttribute("fixed") || this.getVariable("formulaFixed")), 84 | precision: (this.getAttribute("precision") || this.getVariable("formulaPrecision")), 85 | numberFormat: (this.getAttribute("numberFormat") || this.getVariable("formulaNumberFormat")), 86 | dateFormat: (this.getAttribute("dateFormat") || this.getVariable("formulaDateFormat")), 87 | }; 88 | 89 | // Deprecation 90 | if (this.getAttribute("toFixed")) {this.formulaError = "Change 'toFixed' to 'fixed'."; return;} 91 | if (this.getAttribute("toPrecision")) {this.formulaError = "Change 'toPrecision' to 'precision'."; return;} 92 | 93 | // Compile the formula, if it has changed, yielding compiledFormula 94 | if(this.formula !== oldFormula) { 95 | // Clear the error flag 96 | this.formulaError = null; 97 | this.compiledFormula = null; 98 | if (this.formula) { 99 | try { 100 | this.compiledFormula = Compile.compileFormula(this.formula); 101 | } 102 | catch (err) { 103 | this.formulaError = String(err); 104 | this.formula = null; 105 | return; 106 | } 107 | } 108 | } 109 | 110 | // Compute the formula, yielding currentValue 111 | if(this.compiledFormula) { 112 | try { 113 | this.currentValue = Compute.computeFormula(this.compiledFormula, this, this.formatOptions, Boolean(this.debug)); 114 | } 115 | catch (err) { 116 | this.formulaError = String(err); 117 | } 118 | } 119 | else { 120 | this.formulaError = "Error: formula not assigned"; 121 | } 122 | }; 123 | 124 | /* 125 | Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering 126 | */ 127 | FormulaWidget.prototype.refresh = function(changedTiddlers) { 128 | // Re-execute the filter to get the count 129 | this.computeAttributes(); 130 | var oldValue = this.currentValue, oldError = this.formulaError; 131 | this.execute(); 132 | if(this.oldError !== this.formulaError || this.currentValue !== oldValue) { 133 | // Regenerate and rerender the widget and replace the existing DOM node 134 | // We DON'T call refreshSelf() because it call execute() again 135 | var nextSibling = this.findNextSiblingDomNode(); 136 | this.rerender(this.parentDomNode,nextSibling); 137 | return true; 138 | } else { 139 | return false; 140 | } 141 | 142 | }; 143 | 144 | exports.formula = FormulaWidget; 145 | 146 | })(); 147 | -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_wikiparser_attributes_formula.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171224060415431 2 | description: Tag attribute rule for formulas. Ex. `(= 2+2 =)` 3 | modified: 20171225042523039 4 | module-type: attributerule 5 | revision: 0 6 | tags: 7 | title: $:/plugins/ebalster/formula/wikiparser/attributes/formula.js 8 | type: application/javascript 9 | 10 | (function(){ 11 | 12 | /*jslint node: true, browser: true */ 13 | /*global $tw: false */ 14 | "use strict"; 15 | 16 | 17 | exports.formula = function(source, pos, node) { 18 | // Is it a formula? 19 | var reFormulaValue = /\(=(([^=]+|=[^\)])*)=\)/g; 20 | 21 | var value = $tw.utils.parseTokenRegExp(source,pos,reFormulaValue); 22 | if (!value) return null; 23 | 24 | node.type = "formula"; 25 | node.formula = value.match[1]; 26 | node.end = value.end; 27 | return node; 28 | }; 29 | 30 | })(); 31 | -------------------------------------------------------------------------------- /plugins/ebalster_formula/$__plugins_ebalster_formula_wikiparser_formula.js.tid: -------------------------------------------------------------------------------- 1 | created: 20171211033327565 2 | description: Wiki text inline rule for formulas. Ex. `((=2+2))` 3 | modified: 20171211181716654 4 | module-type: wikirule 5 | revision: 0 6 | tags: 7 | title: $:/plugins/ebalster/formula/wikiparser/formula.js 8 | type: application/javascript 9 | 10 | (function(){ 11 | 12 | /*jslint node: true, browser: true */ 13 | /*global $tw: false */ 14 | "use strict"; 15 | 16 | exports.name = "formula"; 17 | exports.types = {inline: true}; 18 | 19 | exports.init = function(parser) { 20 | this.parser = parser; 21 | // Regexp to match 22 | this.matchRegExp = /\(=/mg; 23 | this.endMatchRegExp = /=\)/mg; 24 | }; 25 | 26 | exports.parse = function() { 27 | // Move past the match 28 | this.parser.pos = this.matchRegExp.lastIndex; 29 | // Look for the end marker 30 | this.endMatchRegExp.lastIndex = this.parser.pos; 31 | var match = this.endMatchRegExp.exec(this.parser.source), 32 | text; 33 | // Process the text 34 | if(match) { 35 | text = this.parser.source.substring(this.parser.pos,match.index); 36 | this.parser.pos = match.index + match[0].length; 37 | } else { 38 | text = this.parser.source.substr(this.parser.pos); 39 | this.parser.pos = this.parser.sourceLength; 40 | } 41 | return [{ 42 | type: "formula", 43 | attributes: { 44 | formula: {type: "string", value: text}, 45 | } 46 | }]; 47 | }; 48 | 49 | })(); 50 | -------------------------------------------------------------------------------- /plugins/ebalster_formula/plugin.info: -------------------------------------------------------------------------------- 1 | { 2 | "title": "$:/plugins/ebalster/formula", 3 | "created": "2017-12-09T23:31:32.315Z", 4 | "description": "Spreadsheet-like formulas in TiddlyWiki.", 5 | "list": [ 6 | "readme", 7 | "settings", 8 | "license" 9 | ], 10 | "modified": "2018-07-12T04:57:31.135Z", 11 | "name": "TiddlyFormula", 12 | "plugin-type": "plugin", 13 | "revision": "0", 14 | "version": "0.2.5", 15 | "core-version": ">=5.1.22" 16 | } -------------------------------------------------------------------------------- /plugins/ebalster_modloader/$__core_modules_startup.js.tid: -------------------------------------------------------------------------------- 1 | created: 20180123222302495 2 | modified: 20190301000537293 3 | module-type: startup 4 | revision: 0 5 | tags: 6 | title: $:/core/modules/startup.js 7 | type: application/javascript 8 | 9 | /*\ 10 | title: $:/core/modules/startup.js 11 | type: application/javascript 12 | module-type: startup 13 | 14 | Miscellaneous startup logic for both the client and server. 15 | 16 | \*/ 17 | (function(){ 18 | 19 | /*jslint node: true, browser: true */ 20 | /*global $tw: false */ 21 | "use strict"; 22 | 23 | // Export name and synchronous status 24 | exports.name = "startup"; 25 | exports.after = ["load-modules"]; 26 | exports.synchronous = true; 27 | 28 | // Set to `true` to enable performance instrumentation 29 | var PERFORMANCE_INSTRUMENTATION_CONFIG_TITLE = "$:/config/Performance/Instrumentation"; 30 | 31 | // MODLOADER FIX var widget = require("$:/core/modules/widgets/widget.js"); 32 | 33 | exports.startup = function() { 34 | var widget = require("$:/core/modules/widgets/widget.js"); // MODLOADER FIX 35 | var modules,n,m,f; 36 | // Minimal browser detection 37 | if($tw.browser) { 38 | $tw.browser.isIE = (/msie|trident/i.test(navigator.userAgent)); 39 | $tw.browser.isFirefox = !!document.mozFullScreenEnabled; 40 | } 41 | // Platform detection 42 | $tw.platform = {}; 43 | if($tw.browser) { 44 | $tw.platform.isMac = /Mac/.test(navigator.platform); 45 | $tw.platform.isWindows = /win/i.test(navigator.platform); 46 | $tw.platform.isLinux = /Linux/i.test(navigator.appVersion); 47 | } else { 48 | switch(require("os").platform()) { 49 | case "darwin": 50 | $tw.platform.isMac = true; 51 | break; 52 | case "win32": 53 | $tw.platform.isWindows = true; 54 | break; 55 | case "freebsd": 56 | $tw.platform.isLinux = true; 57 | break; 58 | case "linux": 59 | $tw.platform.isLinux = true; 60 | break; 61 | } 62 | } 63 | // Initialise version 64 | $tw.version = $tw.utils.extractVersionInfo(); 65 | // Set up the performance framework 66 | $tw.perf = new $tw.Performance($tw.wiki.getTiddlerText(PERFORMANCE_INSTRUMENTATION_CONFIG_TITLE,"no") === "yes"); 67 | // Kick off the language manager and switcher 68 | $tw.language = new $tw.Language(); 69 | $tw.languageSwitcher = new $tw.PluginSwitcher({ 70 | wiki: $tw.wiki, 71 | pluginType: "language", 72 | controllerTitle: "$:/language", 73 | defaultPlugins: [ 74 | "$:/languages/en-US" 75 | ], 76 | onSwitch: function(plugins) { 77 | if($tw.browser) { 78 | var pluginTiddler = $tw.wiki.getTiddler(plugins[0]); 79 | if(pluginTiddler) { 80 | document.documentElement.setAttribute("dir",pluginTiddler.getFieldString("text-direction") || "auto"); 81 | } else { 82 | document.documentElement.removeAttribute("dir"); 83 | } 84 | } 85 | } 86 | }); 87 | // Kick off the theme manager 88 | $tw.themeManager = new $tw.PluginSwitcher({ 89 | wiki: $tw.wiki, 90 | pluginType: "theme", 91 | controllerTitle: "$:/theme", 92 | defaultPlugins: [ 93 | "$:/themes/tiddlywiki/snowwhite", 94 | "$:/themes/tiddlywiki/vanilla" 95 | ] 96 | }); 97 | // Kick off the keyboard manager 98 | $tw.keyboardManager = new $tw.KeyboardManager(); 99 | // Clear outstanding tiddler store change events to avoid an unnecessary refresh cycle at startup 100 | $tw.wiki.clearTiddlerEventQueue(); 101 | // Create a root widget for attaching event handlers. By using it as the parentWidget for another widget tree, one can reuse the event handlers 102 | if($tw.browser) { 103 | $tw.rootWidget = new widget.widget({ 104 | type: "widget", 105 | children: [] 106 | },{ 107 | wiki: $tw.wiki, 108 | document: document 109 | }); 110 | } 111 | // Find a working syncadaptor 112 | $tw.syncadaptor = undefined; 113 | $tw.modules.forEachModuleOfType("syncadaptor",function(title,module) { 114 | if(!$tw.syncadaptor && module.adaptorClass) { 115 | $tw.syncadaptor = new module.adaptorClass({wiki: $tw.wiki}); 116 | } 117 | }); 118 | // Set up the syncer object if we've got a syncadaptor 119 | if($tw.syncadaptor) { 120 | $tw.syncer = new $tw.Syncer({wiki: $tw.wiki, syncadaptor: $tw.syncadaptor}); 121 | } 122 | // Setup the saver handler 123 | $tw.saverHandler = new $tw.SaverHandler({wiki: $tw.wiki, dirtyTracking: !$tw.syncadaptor}); 124 | // Host-specific startup 125 | if($tw.browser) { 126 | // Install the popup manager 127 | $tw.popup = new $tw.utils.Popup(); 128 | // Install the animator 129 | $tw.anim = new $tw.utils.Animator(); 130 | } 131 | }; 132 | 133 | })(); 134 | -------------------------------------------------------------------------------- /plugins/ebalster_modloader/$__plugins_ebalster_modloader_about.tid: -------------------------------------------------------------------------------- 1 | created: 20180120061330117 2 | modified: 20190301000537293 3 | revision: 0 4 | tags: 5 | title: $:/plugins/ebalster/modloader/about 6 | type: text/vnd.tiddlywiki 7 | 8 | The ''Mod-Loader Plugin'' is a powerful meta-plugin for TiddlyWiki which facilitates plugins including the TiddlyWiki core to be modified at load-time. This allows for the creation of plugins that modify the TiddlyWiki core but can maintain compatibility with newer versions of the core. 9 | 10 | Mods can only affect shadow tiddlers. `startup` modules cannot be meaningfully patched at this time. 11 | 12 | 13 | !!Installing Mods 14 | 15 | Installing mods is simple. Simply install the modloader plugin and any mod plugins. Alternatively, patch tiddlers may be installed directly into your wiki. 16 | 17 | <<< 18 | To install the modloader plugin, drag-and-drop this to your wiki: 19 | 20 | {{$:/plugins/ebalster/modloader||$:/core/ui/Components/plugin-info}} 21 | <<< 22 | 23 | 24 | !!Limitations and Conflicts 25 | 26 | It may not be able to apply a patch due to conflicts with another patch or changes in the specific part of a file a patch is meant to modify. Currently, if //any// patch fails to apply, the modloader will abort completely and a warning will be displayed on startup. This avoids a situation where only certain changes are applied and the resulting code is non-functional. 27 | 28 | Future versions of the modloader may introduce a concept of patch "groups", where only those changes in a given group will be aborted upon failure or conflict. 29 | 30 | The modloader can patch the TiddlyWiki core, as well as other plugins, in principle. However, it //cannot// currently patch plugins that do not define any `plugin-priority`. In the future we may investigate lifting this limitation. 31 | 32 | 33 | !!Creating Mods 34 | 35 | A mod is a collection of Patch Tiddlers (see below) which is usually packaged as a plugin. To generate a mod, use the [[Mod Maker Utility|$:/plugins/ebalster/modloader/modmaker]]. 36 | 37 | 38 | !!Patch Tiddlers 39 | 40 | A patch tiddler is a tiddler with its `modloader-target` field set to the title of a shadow tiddler which it modifies. 41 | 42 | 43 | !!Technical Explanation 44 | 45 | The modloader patch runs before TiddlyWiki's startup modules, finds all tiddlers with a defined `modloader-target` field whose type is `text/x-patch` and applies the changes to the corresponding targets' text. The changed tiddlers are packaged into a new plugin `$:/temp/modloader-plugin` which is immediately added to the wiki. 46 | 47 | Patches are applied only to shadow tiddlers, and the tiddlers produced by the modloader are also shadows. Thus, it is not possible for the modloader to affect non-shadow tiddlers in the wiki. 48 | 49 | 50 | Development notes: 51 | 52 | * Can we force other startup modules to be re-eval'd? -------------------------------------------------------------------------------- /plugins/ebalster_modloader/$__plugins_ebalster_modloader_alert.tid: -------------------------------------------------------------------------------- 1 | created: 20180120194658741 2 | header: Mod Loader alert! 3 | modified: 20190301000537293 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/modloader/alert 7 | type: text/vnd.tiddlywiki 8 | 9 | !!{{!!header}} 10 | 11 | {{!!notices}} 12 | 13 | [[See Mod Loader Log|$:/temp/mod-plugin/status]]. -------------------------------------------------------------------------------- /plugins/ebalster_modloader/$__plugins_ebalster_modloader_diff_patch_match.js.meta: -------------------------------------------------------------------------------- 1 | created: 20180120063923147 2 | modified: 20190301000537293 3 | module-type: library 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/modloader/diff_patch_match.js 7 | type: application/javascript 8 | -------------------------------------------------------------------------------- /plugins/ebalster_modloader/$__plugins_ebalster_modloader_diff_patch_match_uncompressed.js.meta: -------------------------------------------------------------------------------- 1 | created: 20180120063923147 2 | modified: 20190301000537293 3 | module-type: library 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/modloader/diff_patch_match_uncompressed.js 7 | type: application/javascript 8 | -------------------------------------------------------------------------------- /plugins/ebalster_modloader/$__plugins_ebalster_modloader_parsers_patch.js.tid: -------------------------------------------------------------------------------- 1 | created: 20180121184614270 2 | modified: 20190301000537294 3 | module-type: parser 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/modloader/parsers/patch.js 7 | type: application/javascript 8 | 9 | /*\ 10 | title: $:/plugins/ebalster/modloader/parsers/patch.js 11 | type: application/javascript 12 | module-type: parser 13 | 14 | Render tiddlers of type "text/x-patch" like other plaintext tiddlers. 15 | 16 | \*/ 17 | (function(){ 18 | 19 | /*jslint node: true, browser: true */ 20 | /*global $tw: false */ 21 | "use strict"; 22 | 23 | var modutil = require("$:/plugins/ebalster/modloader/utils.js"); 24 | var diff = modutil.diff; 25 | 26 | var TextParser = function(type,text,options) { 27 | 28 | var patches = diff.patch_fromText(text || ""); 29 | 30 | //var src = 31 | 32 | //var diff = diff.diff_main() 33 | 34 | // Render the patch's insertions, deletions and preservations... 35 | var html = []; 36 | for (var i = 0; i < patches.length; i++) { 37 | 38 | // Render patch location note 39 | var patch = patches[i]; 40 | html.push({ 41 | type:"element", 42 | tag: "h3", 43 | children: [{ 44 | type: "text", 45 | text: "@@ -" + (patch.start1+1) + "," + patch.length1 + 46 | " +" + (patch.start2+1) + "," + patch.length2 + " @@" 47 | }] 48 | }); 49 | html.push({type:"element", tag: "hr"}); 50 | 51 | // Render the diffs 52 | for (var j = 0; j < patch.diffs.length; ++j) { 53 | var curdiff = patch.diffs[j]; 54 | var tag = "span"; 55 | switch (curdiff[0]) { 56 | case +1: tag = "ins"; break; 57 | case -1: tag = "del"; break; 58 | case 0: tag = "span"; break; 59 | } 60 | html.push({ 61 | type:"element", 62 | tag: tag, 63 | children: [{type: "text", text: curdiff[1]}] 64 | }); 65 | } 66 | html.push({type:"element", tag: "hr"}); 67 | } 68 | 69 | // DEBUG 70 | //var html = [{type:"text", text: text}]; //text: JSON.stringify(patch,null,' ')}]; 71 | 72 | this.tree = [{ 73 | type: "element", tag: "pre", 74 | attributes: {class: {type: "string", value: "modloader-patch"}}, 75 | children: [{type: "element", tag: "code", children: html}] 76 | }]; 77 | }; 78 | 79 | exports["text/x-patch"] = TextParser; 80 | 81 | })(); 82 | 83 | -------------------------------------------------------------------------------- /plugins/ebalster_modloader/$__plugins_ebalster_modloader_patches_core_modules_startup.js.tid: -------------------------------------------------------------------------------- 1 | created: 20180123225257337 2 | modified: 20190301000537294 3 | modloader-source: $:/core 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/modloader/patches/core/modules/startup.js 7 | type: text/x-patch 8 | 9 | @@ -500,32 +500,49 @@ 10 | trumentation%22;%0A%0A 11 | +// MODLOADER FIX 12 | var widget = req 13 | @@ -608,32 +608,109 @@ 14 | = function() %7B%0A 15 | +%09var widget = require(%22$:/core/modules/widgets/widget.js%22); // MODLOADER FIX%0A 16 | %09var modules,n,m 17 | -------------------------------------------------------------------------------- /plugins/ebalster_modloader/$__plugins_ebalster_modloader_patchmaker.tid: -------------------------------------------------------------------------------- 1 | created: 20180121081336699 2 | modified: 20190301000537294 3 | revision: 0 4 | tags: 5 | title: $:/plugins/ebalster/modloader/patchmaker 6 | type: text/vnd.tiddlywiki 7 | 8 | \define test_hint(filter) 9 | <$list filter="$filter$" emptyMessage="✘"> 10 | ✔ 11 | 12 | \end 13 | 14 | \define replace_hint(filter) 15 | <$list filter="$filter$"> 16 | Warning: This tiddler exists and will be replaced! 17 | 18 | \end 19 | 20 | Use this utility to generate patches, or examine its source to learn about the `action-createpatch` widget. 21 | 22 | If ''destination'' is not specified it will be set to ''source''. The mod-maker always uses a shadow tiddler for ''source'' even if there is a real tiddler replacing it. The ''destination'' will always be selected as a real tiddler. 23 | 24 | 25 | <$tiddler tiddler="$:/temp/modloader/modmaker"> 26 | 27 | 28 | 29 | 30 | 32 | <$edit-text 33 | field="patch-source" 34 | placeholder="Title of shadow tiddler to be modded." 35 | size=45/> 36 | 39 | 40 | 41 | 42 | 44 | <$edit-text 45 | field="patch-source-plugin" 46 | placeholder="Title of plugin containing source. Defaults to auto." 47 | size=45/> 48 | 51 | 52 | 53 | 54 | 56 | <$edit-text 57 | field="patch-destination" 58 | placeholder="Title of modified tiddler. Defaults to target." 59 | size=45/> 60 | 63 | 64 | 65 | 66 | 68 | <$edit-text 69 | field="patch-output" 70 | placeholder="Title of patch tiddler to create. (Replaces existing)" 71 | size=45/> 72 |
73 | <> 74 | 77 | 78 |
Source 31 | 37 | <> 38 |
Source Plugin 43 | 49 | <> 50 |
Destination 55 | 61 | <> 62 |
Output 67 | 75 | <> 76 |
79 | 80 | <$button>Compute Patch 81 | <$action-createpatch 82 | source={{!!patch-source}} 83 | source-plugin={{!!patch-source-plugin}} 84 | destination={{!!patch-destination}} 85 | output={{!!patch-output}} 86 | savetitle="!!patch-made" /> 87 | 88 | 89 | <$list filter="[{!!patch-made}is[tiddler]]"> 90 | <$link>Open your patch: {{!!title}} 91 | 92 | 93 | -------------------------------------------------------------------------------- /plugins/ebalster_modloader/$__plugins_ebalster_modloader_status.tid: -------------------------------------------------------------------------------- 1 | created: 20180121175357975 2 | modified: 20190301000537294 3 | revision: 0 4 | tags: 5 | title: $:/plugins/ebalster/modloader/status 6 | type: text/vnd.tiddlywiki 7 | 8 | !Modloader Status Report 9 | 10 | <$transclude tiddler="$:/temp/mod-plugin/status"> 11 | 12 | Not found. 13 | 14 | It appears the modloader did not run at startup. 15 | 16 | -------------------------------------------------------------------------------- /plugins/ebalster_modloader/$__plugins_ebalster_modloader_stylesheet.css.tid: -------------------------------------------------------------------------------- 1 | created: 20180123160859840 2 | modified: 20190301000537294 3 | revision: 0 4 | tags: $:/tags/Stylesheet 5 | title: $:/plugins/ebalster/modloader/stylesheet.css 6 | type: text/css 7 | 8 | .modloader-patch span { 9 | font-weight: bold; 10 | color: #555555; 11 | } 12 | 13 | .modloader-patch ins { 14 | text-decoration: none; 15 | font-weight: bold; 16 | color: #009900; 17 | background: #EEFFEE; 18 | } 19 | 20 | .modloader-patch del { 21 | text-decoration: strikethrough; 22 | color: #DD0000; 23 | background: #FFBBBB; 24 | } -------------------------------------------------------------------------------- /plugins/ebalster_modloader/$__plugins_ebalster_modloader_utils.js.tid: -------------------------------------------------------------------------------- 1 | created: 20180121075602920 2 | modified: 20190301000537294 3 | module-type: library 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/modloader/utils.js 7 | type: application/javascript 8 | 9 | /*\ 10 | title: $:/plugins/ebalster/modloader/utils.js 11 | type: application/javascript 12 | module-type: library 13 | 14 | Utility functions and data storage for the modloader. 15 | 16 | \*/ 17 | (function(){ 18 | 19 | /*jslint node: true, browser: true */ 20 | /*global $tw: true */ 21 | "use strict"; 22 | 23 | 24 | var DiffLib = require("$:/plugins/ebalster/modloader/diff_patch_match.js"); 25 | exports.diff = new DiffLib.diff_match_patch(); 26 | 27 | // Pretty liberal timeout 28 | exports.diff.Diff_Timeout = 10.0; 29 | 30 | // Plenty of context on patches 31 | exports.diff.Patch_Margin = 8; 32 | 33 | /* 34 | Find the shadow tiddler in the given plugin and return it. 35 | If no pluginTitle is provided, attempt to guess it. 36 | Result (if non-null) is a new object {source: , fields: {}} 37 | */ 38 | exports.findOriginalShadow = function findOriginalShadow(title, pluginTitle) { 39 | // Direct search if pluginTitle is specified. 40 | if (pluginTitle) { 41 | var plugInfo = $tw.wiki.getPluginInfo(pluginTitle); 42 | if (plugInfo && plugInfo.tiddlers && plugInfo.tiddlers[title]) return { 43 | fields: plugInfo.tiddlers[title], 44 | source: pluginTitle, 45 | }; 46 | return null; 47 | } 48 | 49 | // No pluginTitle: first try core (most likely mod target) 50 | var found = findOriginalShadow(title, "$:/core"); 51 | if (found) return found; 52 | 53 | // Then try all other tiddlers in the wiki. 54 | // TODO would be nice to do this in load order somehow 55 | $tw.wiki.each(function(searchTiddler, searchTitle) { 56 | // Do NOT consider temp tiddlers, which are usually generated. 57 | if (searchTitle.substr(0,7) == "$:/temp") return; 58 | if (!found) found = findOriginalShadow(title, searchTitle); 59 | }); 60 | return found; 61 | }; 62 | 63 | exports.modBackupTiddlers = {}; 64 | 65 | 66 | // Alert display path 67 | exports.PATH_ALERT_TEMPLATE = "$:/plugins/ebalster/modloader/alert"; 68 | 69 | exports.PATH_MOD_PLUGIN = "$:/temp/mod-plugin"; 70 | exports.PATH_MOD_STATUS = "$:/temp/mod-plugin/status"; 71 | exports.PATH_ALERT_PREFIX = "$:/temp/mod-plugin/alert"; 72 | 73 | var ALERT_COUNTER = 1; 74 | 75 | //var ALERT_PREFIX = "$:/temp/" 76 | 77 | 78 | exports.showModAlertEx = function(template, fields) { 79 | var tiddler; 80 | var affix = { 81 | title: exports.PATH_ALERT_PREFIX + "/" + exports.ALERT_COUNTER++, 82 | tags: "[[$:/tags/Alert]]", 83 | component: "Modloader Plugin" 84 | }; 85 | if (template) { 86 | tiddler = new $tw.Tiddler($tw.wiki.getTiddler(template), fields, affix); 87 | } 88 | else { 89 | tiddler = new $tw.Tiddler(fields, affix); 90 | } 91 | $tw.wiki.addTiddler(tiddler); 92 | }; 93 | 94 | exports.showModLoaderAlert = function(fields) { 95 | exports.showModAlertEx(exports.PATH_ALERT_TEMPLATE, fields); 96 | }; 97 | 98 | exports.showGenericAlert = function(text) { 99 | exports.showModAlertEx(null, {text: text}); 100 | }; 101 | 102 | 103 | })(); -------------------------------------------------------------------------------- /plugins/ebalster_modloader/$__plugins_ebalster_modloader_widgets_action-createpatch.js: -------------------------------------------------------------------------------- 1 | // created: 20180121073220273 2 | // modified: 20190301000537294 3 | // module-type: widget 4 | // revision: 0 5 | // tags: 6 | // title: $:/plugins/ebalster/modloader/widgets/action-createpatch.js 7 | // type: application/javascript 8 | 9 | /*\ 10 | title: $:/plugins/ebalster/modloader/widgets/action-createpatch.js 11 | type: application/javascript 12 | module-type: widget 13 | 14 | Action widget to create a patch tiddler for use with the modloader. 15 | 16 | \*/ 17 | (function(){ 18 | 19 | /*jslint node: true, browser: true */ 20 | /*global $tw: false */ 21 | "use strict"; 22 | 23 | var Widget = require("$:/core/modules/widgets/widget.js").widget; 24 | 25 | var modutil = require("$:/plugins/ebalster/modloader/utils.js"); 26 | var diff = modutil.diff; 27 | 28 | 29 | var CreatePatchWidget = function(parseTreeNode,options) { 30 | this.initialise(parseTreeNode,options); 31 | }; 32 | 33 | /* 34 | Inherit from the base widget class 35 | */ 36 | CreatePatchWidget.prototype = new Widget(); 37 | 38 | /* 39 | Render this widget into the DOM 40 | */ 41 | CreatePatchWidget.prototype.render = function(parent,nextSibling) { 42 | this.computeAttributes(); 43 | this.execute(); 44 | }; 45 | 46 | /* 47 | Compute the internal state of the widget 48 | */ 49 | CreatePatchWidget.prototype.execute = function() { 50 | this.patchSource = this.getAttribute("source"); 51 | this.patchSourcePlugin = this.getAttribute("source-plugin"); 52 | this.patchDestination = this.getAttribute("destination") || this.patchSource; 53 | this.patchOutput = this.getAttribute("output"); 54 | this.actionSaveTitle = this.getAttribute("savetitle"); 55 | }; 56 | 57 | /* 58 | Refresh the widget by ensuring our attributes are up to date 59 | */ 60 | CreatePatchWidget.prototype.refresh = function(changedTiddlers) { 61 | var changedAttributes = this.computeAttributes(); 62 | if($tw.utils.count(changedAttributes) > 0) { 63 | this.refreshSelf(); 64 | return true; 65 | } 66 | return this.refreshChildren(changedTiddlers); 67 | }; 68 | 69 | /* 70 | Invoke the action associated with this widget 71 | */ 72 | var ALERT_PREFIX = "!!Patch creation failed...\n\n"; 73 | 74 | CreatePatchWidget.prototype.invokeAction = function(triggeringWidget,event) { 75 | var self=this; 76 | var outTitle = this.patchOutput || this.wiki.generateNewTitle("ModloaderPatch"); 77 | 78 | if (!this.patchSource) { 79 | modutil.showGenericAlert(ALERT_PREFIX + 80 | "action-createpatch requires a `source` to be set."); 81 | return true; 82 | } 83 | 84 | // Grab the source tiddler (which must exist as a shadow). 85 | // Source plugin will be guessed if not provided. 86 | var sourceTiddler = modutil.findOriginalShadow( 87 | this.patchSource, 88 | this.patchSourcePlugin); 89 | if (!sourceTiddler) { 90 | modutil.showGenericAlert(ALERT_PREFIX + 91 | "Patch source `" + this.patchSource + "` not found in " + 92 | (this.patchSourcePlugin ? "source-plugin `" + this.patchSourcePlugin + "`" : "any plugin.")); 93 | return true; 94 | } 95 | 96 | // Grab the destination tiddler (which must exist as a non-shadow or overriding shadow.) 97 | if (!$tw.wiki.tiddlerExists(this.patchDestination) && 98 | $tw.wiki.getShadowSource(this.patchDestination) == sourceTiddler.source) { 99 | modutil.showGenericAlert(ALERT_PREFIX + 100 | "Patch destination `" + this.patchDestination + "` refers to the target."); 101 | return true; 102 | } 103 | var destTiddler = $tw.wiki.getTiddler(this.patchDestination); 104 | if (!destTiddler) { 105 | modutil.showGenericAlert(ALERT_PREFIX + 106 | "Patch destination `" + this.patchDestination + "` doesn't exist."); 107 | return true; 108 | } 109 | 110 | // 111 | var sourceData = sourceTiddler.fields.text.replace(/(\n)(\n)/g, "\r$1\r$2") || ""; 112 | var destData = destTiddler.fields.text.replace(/(\n)(\n)/g, "\r$1\r$2") || ""; 113 | //var destData = destTiddler.fields.text || ""; 114 | 115 | // Generate a diff and clean it up. 116 | var delta = diff.diff_main(sourceData, destData, false); 117 | diff.diff_cleanupSemantic(delta); 118 | 119 | // Generate the patch. 120 | var patch = diff.patch_make(sourceData, delta); 121 | patch = diff.patch_toText(patch); 122 | 123 | //var patch = diff.patch_make(sourceTiddler.fields.text, destTiddler.fields.text); // DBG 124 | 125 | // Generate fields for the patch tiddler. 126 | var fields = { 127 | text: patch, 128 | type: "text/x-patch", 129 | "modloader-target": String(this.patchSource), 130 | "modloader-source": String(sourceTiddler.source), 131 | }; 132 | 133 | // Add the generated patch tiddler to the wiki. 134 | var tiddler = this.wiki.addTiddler(new $tw.Tiddler( 135 | this.wiki.getCreationFields(), 136 | fields, 137 | this.wiki.getModificationFields(), 138 | {title: outTitle})); 139 | 140 | // Set the title reference, possibly. 141 | if(this.actionSaveTitle) { 142 | this.wiki.setTextReference(this.actionSaveTitle,outTitle,this.getVariable("currentTiddler")); 143 | } 144 | return true; // Action was invoked 145 | }; 146 | 147 | exports["action-createpatch"] = CreatePatchWidget; 148 | 149 | })(); 150 | -------------------------------------------------------------------------------- /plugins/ebalster_modloader/$__plugins_ebalster_modloader_widgets_action-createpatch.js.meta: -------------------------------------------------------------------------------- 1 | created: 20180121073220273 2 | modified: 20190301000537294 3 | module-type: widget 4 | revision: 0 5 | tags: 6 | title: $:/plugins/ebalster/modloader/widgets/action-createpatch.js 7 | type: application/javascript 8 | -------------------------------------------------------------------------------- /plugins/ebalster_modloader/plugin.info: -------------------------------------------------------------------------------- 1 | { 2 | "title": "$:/plugins/ebalster/modloader", 3 | "created": "2018-01-21T17:53:11.334Z", 4 | "list": [ 5 | "about", 6 | "patchmaker", 7 | "status" 8 | ], 9 | "modified": "2018-07-12T04:57:31.213Z", 10 | "plugin-priority": "1", 11 | "plugin-type": "plugin", 12 | "revision": "0", 13 | "version": "0.0.5", 14 | "core-version": ">=5.1.20" 15 | } -------------------------------------------------------------------------------- /plugins/ebalster_timer/plugin.info: -------------------------------------------------------------------------------- 1 | { 2 | "created": "20180106071024209", 3 | "modified": "20190726021015080", 4 | "plugin-type": "plugin", 5 | "revision": "0", 6 | "tags": "", 7 | "title": "$:/plugins/ebalster/timer", 8 | "type": "application/json", 9 | "version": "0.0.2", 10 | 11 | "tiddlers": { 12 | "$:/plugins/ebalster/timer/widgets/timer.js": { 13 | "text": "/*\\\ntitle: $:/plugins/ebalster/timer/widgets/timer.js\ntype: application/javascript\nmodule-type: widget\n\nWidget for triggering ActionWidgets on a timed interval\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar TimerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nTimerWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nTimerWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n\t// The timer callback...\n\tvar timerWidgetFunction = function timerWidgetFunction() {\n\t\t// Only perform actions if the TimerWidget is still in the widget tree.\n\t\tif (self.stillInWidgetTree()) {\n\t\t\tvar event = new CustomEvent(\"TimerWidget\");\n\t\t\tself.invokeActions(self,event);\n\t\t\tif(self.message) self.dispatchMessage(event);\n\t\t\t//if(self.set) self.setTiddler();\n\t\t\tif(self.actions) self.invokeActionString(self.actions,self,event);\n\t\t}\n\t};\n\t// How long should we wait?\n\tif (window) {\n\t\t// Unregister the old timer event\n\t\tif (this.timeoutID) window.clearTimeout (this.timeoutID);\n\t\tif (this.intervalID) window.clearInterval(this.intervalID);\n\t\tthis.timeoutID = this.intervalID = null;\n\t\tif (this.time && this.time.length) {\n\t\t\tvar currentTime = Date.now(), targetTime = null;\n\t\t\tif (this.time.length >= 14) {\n\t\t\t\t//TiddlyWiki date in native format\n\t\t\t\ttargetTime = $tw.utils.parseDate(this.time);\n\t\t\t\tif (targetTime) targetTime = targetTime.getTime();\n\t\t\t}\n\t\t\telse {\n\t\t\t\t//Unix epoch time in milliseconds\n\t\t\t\ttargetTime = parseFloat(this.time);\n\t\t\t}\n\t\t\tif (targetTime && targetTime > currentTime) {\n\t\t\t\t// Register a timeout event\n\t\t\t\tthis.timeoutID = window.setTimeout(timerWidgetFunction, targetTime-currentTime);\n\t\t\t}\n\t\t}\n\t\telse if (this.interval && this.interval.length) {\n\t\t\tvar interval = parseFloat(this.interval);\n\t\t\tif (interval && interval > 0) {\n\t\t\t\t// Register an interval event\n\t\t\t\tthis.intervalID = window.setInterval(timerWidgetFunction, interval*1000);\n\t\t\t}\n\t\t}\n\t\t\n\t}\n};\n\n/*\nDetect if the timer widget is still in the tree, by crawling up to the RootWidget.\n*/\nTimerWidget.prototype.stillInWidgetTree = function() {\n\tvar widget = this;\n\twhile (widget) {\n\t\tvar parent = widget.parentWidget;\n\t\tif (parent) {\n\t\t\t// Return false if some ancestor has disowned us.\n\t\t\tif (!parent.children || parent.children.indexOf(widget) < 0) return false;\n\t\t}\n\t\telse {\n\t\t\t// Return true if we get to the root widget.\n\t\t\treturn widget === $tw.rootWidget;\n\t\t}\n\t\twidget = parent;\n\t}\n};\n\n/*\nWe don't allow actions to propagate because we trigger actions ourselves\n*/\nTimerWidget.prototype.allowActionPropagation = function() {\n\treturn false;\n};\n\nTimerWidget.prototype.dispatchMessage = function(event) {\n\tthis.dispatchEvent({type: this.message, param: this.param, tiddlerTitle: this.getVariable(\"currentTiddler\"), event: event});\n};\n\n/*TimerWidget.prototype.setTiddler = function() {\n\tthis.wiki.setTextReference(this.set,this.setTo,this.getVariable(\"currentTiddler\"));\n};*/\n\n/*\nCompute the internal state of the widget\n*/\nTimerWidget.prototype.execute = function() {\n\t// Get attributes\n\tthis.actions = this.getAttribute(\"actions\");\n\tthis.message = this.getAttribute(\"message\");\n\tthis.param = this.getAttribute(\"param\");\n\tthis.interval = this.getAttribute(\"interval\");\n\tthis.time = this.getAttribute(\"time\");\n\t//this.set = this.getAttribute(\"set\");\n\t//this.setTo = this.getAttribute(\"setTo\");\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nTimerWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.time || changedAttributes.interval || changedAttributes.message || changedAttributes.param || changedAttributes.actions) {\n\t\t// || changedAttributes.set || changedAttributes.setTo || (this.set && changedTiddlers[this.set])\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.timer = TimerWidget;\n\n})();\n", 14 | "type": "application/javascript", 15 | "title": "$:/plugins/ebalster/timer/widgets/timer.js", 16 | "tags": "", 17 | "revision": "0", 18 | "module-type": "widget", 19 | "modified": "20190726012139500", 20 | "created": "20180106041642233" 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /tiddlers/_system/Bob/AvailableLanguageList.tid: -------------------------------------------------------------------------------- 1 | tags: 2 | title: $:/Bob/AvailableLanguageList 3 | type: application/json 4 | 5 | { 6 | "ca-ES": "Catalan (Spain)", 7 | "cs-CZ": "Česky (Czech Republic)", 8 | "da-DK": "Danish (Denmark)", 9 | "de-AT": "Deutsch (Österreich)", 10 | "de-CH": "Deutsch (Schweiz)", 11 | "de-DE": "Deutsch (Deutschland)", 12 | "el-GR": "Greek (Greece)", 13 | "en-US": "English (US)", 14 | "es-ES": "Castellano. (Spain)", 15 | "fa-IR": "Persian (Iran)", 16 | "fr-FR": "Français (France)", 17 | "he-IL": "Hebrew (Israel)", 18 | "hi-IN": "Hindi (India)", 19 | "ia-IA": "Interlingua (Interlingua)", 20 | "it-IT": "Italian (Italy)", 21 | "ja-JP": "Japanese (Japan)", 22 | "ko-KR": "Korean (Korea Republic)", 23 | "nl-NL": "Dutch (The Netherlands)", 24 | "pa-IN": "Punjabi (India)", 25 | "pt-BR": "Português (Brasil)", 26 | "pt-PT": "Portuguese (Portugal)", 27 | "ru-RU": "Russian (Russia)", 28 | "sk-SK": "Slovak (Slovakia)", 29 | "sl-SI": "Solvenian (Slovenia)", 30 | "sv-SE": "Swedish (Sweden)", 31 | "zh-CN": "Chinese (China)", 32 | "zh-Hans": "Chinese (Simplified)", 33 | "zh-Hant": "Chinese (Traditional)", 34 | "zh-HK": "Chinese (Hong Kong)", 35 | "zh-TW": "Chinese (Taiwan)" 36 | } -------------------------------------------------------------------------------- /tiddlers/_system/Bob/AvailablePluginList.tid: -------------------------------------------------------------------------------- 1 | list: @oss/bootstrap4 @oss/lodash ebalster/attribute-modules ebalster/formula ebalster/modloader joshuafontany/jsoneditor joshuafontany/jsonmangler matabele/action-maketid ooktech/Bob TheDiveO/FontAwesome tiddlywiki/async tiddlywiki/aws tiddlywiki/bibtex tiddlywiki/blog tiddlywiki/browser-sniff tiddlywiki/cecily tiddlywiki/classictools tiddlywiki/codemirror tiddlywiki/codemirror-autocomplete tiddlywiki/codemirror-closebrackets tiddlywiki/codemirror-closetag tiddlywiki/codemirror-fullscreen-editing tiddlywiki/codemirror-keymap-emacs tiddlywiki/codemirror-keymap-sublime-text tiddlywiki/codemirror-keymap-vim tiddlywiki/codemirror-mode-css tiddlywiki/codemirror-mode-htmlembedded tiddlywiki/codemirror-mode-htmlmixed tiddlywiki/codemirror-mode-javascript tiddlywiki/codemirror-mode-markdown tiddlywiki/codemirror-mode-x-tiddlywiki tiddlywiki/codemirror-mode-xml tiddlywiki/codemirror-search-replace tiddlywiki/comments tiddlywiki/d3 tiddlywiki/dynaview tiddlywiki/evernote tiddlywiki/external-attachments tiddlywiki/filesystem tiddlywiki/github-fork-ribbon tiddlywiki/googleanalytics tiddlywiki/hammerjs tiddlywiki/help tiddlywiki/highlight tiddlywiki/internals tiddlywiki/jasmine tiddlywiki/jszip tiddlywiki/katex tiddlywiki/markdown tiddlywiki/mobiledragdrop tiddlywiki/nodewebkitsaver tiddlywiki/pluginlibrary tiddlywiki/powered-by-tiddlywiki tiddlywiki/qrcode tiddlywiki/railroad tiddlywiki/savetrail tiddlywiki/sax tiddlywiki/stacked-view tiddlywiki/tahoelafs tiddlywiki/text-slicer tiddlywiki/tiddlyweb tiddlywiki/translators tiddlywiki/tw2parser tiddlywiki/tw5.com-docs tiddlywiki/twitter tiddlywiki/upgrade tiddlywiki/xlsx-utils tiddlywiki/xmldom 2 | tags: 3 | title: $:/Bob/AvailablePluginList 4 | 5 | -------------------------------------------------------------------------------- /tiddlers/_system/DefaultTiddlers.tid: -------------------------------------------------------------------------------- 1 | created: 20171210212050221 2 | modified: 20171229211841983 3 | title: $:/DefaultTiddlers 4 | type: text/vnd.tiddlywiki 5 | 6 | [[Formula Plugin]] -------------------------------------------------------------------------------- /tiddlers/_system/FormulasWiki/AutoSummarizeInView.tid: -------------------------------------------------------------------------------- 1 | created: 20171229183351169 2 | modified: 20171229183541849 3 | tags: $:/tags/ViewTemplate 4 | title: $:/FormulasWiki/AutoSummarizeInView 5 | type: text/vnd.tiddlywiki 6 | 7 | <$list filter="[all[current]tags[]]" variable="prefix_tag"><$transclude tiddler=<> field="auto_prefix"/> -------------------------------------------------------------------------------- /tiddlers/_system/FormulasWiki/FunctionMacros.tid: -------------------------------------------------------------------------------- 1 | created: 20171228051427638 2 | modified: 20190726013806598 3 | tags: $:/tags/Macro 4 | title: $:/FormulasWiki/FunctionMacros 5 | type: text/vnd.tiddlywiki 6 | 7 | \define functionTableRow() 8 | 9 | 10 | <$list variable=name filter="[enlist{!!names}]" emptyMessage="no `names`?!"> 11 | <$text text=<>/>
12 | 13 | 14 | 15 | <$text text={{!!params-short}}/> 16 | 17 | 18 | <$text text={{!!return-type}}/> 19 | 20 | 21 | {{!!summary}} 22 | 23 | 24 | \end 25 | 26 | \define functionLabelRow() 27 | 28 | Function 29 | Params. 30 | Result 31 | Summary 32 | 33 | \end 34 | 35 | \define functionTable(filter) 36 | 37 | <> 38 | <> 39 |
40 | \end 41 | 42 | \define functionTableSelf() 43 | 44 | <> 45 | <> 46 |
47 | \end -------------------------------------------------------------------------------- /tiddlers/_system/SiteSubtitle.tid: -------------------------------------------------------------------------------- 1 | created: 20171209232915675 2 | modified: 20171212014235006 3 | title: $:/SiteSubtitle 4 | type: text/vnd.tiddlywiki 5 | 6 | spreadsheet-inspired number crunching -------------------------------------------------------------------------------- /tiddlers/_system/SiteTitle.tid: -------------------------------------------------------------------------------- 1 | created: 20180121085648391 2 | modified: 20180121085650599 3 | title: $:/SiteTitle 4 | type: text/vnd.tiddlywiki 5 | 6 | Formulas for TiddlyWiki -------------------------------------------------------------------------------- /tiddlers/_system/StoryList.tid: -------------------------------------------------------------------------------- 1 | created: 20201225233840934 2 | creator: Joshua Fontany 3 | list: [[Formula Plugin]] 4 | modified: 20201225233913665 5 | modifier: Joshua Fontany 6 | title: $:/StoryList 7 | type: text/vnd.tiddlywiki -------------------------------------------------------------------------------- /tiddlers/_system/config/FileSystemPaths.tid: -------------------------------------------------------------------------------- 1 | created: 20171211181356482 2 | modified: 20171222215509357 3 | tags: 4 | title: $:/config/FileSystemPaths 5 | type: text/plain 6 | 7 | [is[system]removeprefix[$:/]addprefix[_system/]] 8 | [has[draft.of]addprefix[drafts/]] 9 | [!is[system]!has[draft.of]addprefix[wiki/]] -------------------------------------------------------------------------------- /tiddlers/_system/config/RelinkOnRename.tid: -------------------------------------------------------------------------------- 1 | created: 20171229211742058 2 | modified: 20171229211743100 3 | title: $:/config/RelinkOnRename 4 | type: text/vnd.tiddlywiki 5 | 6 | yes -------------------------------------------------------------------------------- /tiddlers/_system/config/TextEditor/EnableToolbar.tid: -------------------------------------------------------------------------------- 1 | created: 20171229051557765 2 | modified: 20171229051601889 3 | title: $:/config/TextEditor/EnableToolbar 4 | type: text/vnd.tiddlywiki 5 | 6 | yes -------------------------------------------------------------------------------- /tiddlers/_system/core/ui/PageTemplate.tid: -------------------------------------------------------------------------------- 1 | created: 20190726014112209 2 | modified: 20190726014123117 3 | tags: 4 | title: $:/core/ui/PageTemplate 5 | 6 | \whitespace trim 7 | \define containerClasses() 8 | tc-page-container tc-page-view-$(storyviewTitle)$ tc-language-$(languageTitle)$ 9 | \end 10 | \import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]] 11 | 12 | <$set name="tv-config-toolbar-icons" value={{$:/config/Toolbar/Icons}}> 13 | 14 | <$set name="tv-config-toolbar-text" value={{$:/config/Toolbar/Text}}> 15 | 16 | <$set name="tv-config-toolbar-class" value={{$:/config/Toolbar/ButtonClass}}> 17 | 18 | <$set name="tv-show-missing-links" value={{$:/config/MissingLinks}}> 19 | 20 | <$set name="storyviewTitle" value={{$:/view}}> 21 | 22 | <$set name="languageTitle" filter="[{$:/language}get[name]]"> 23 | 24 |
>> 25 | 26 | <$navigator story="$:/StoryList" history="$:/HistoryList" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}> 27 | 28 | <$dropzone> 29 | 30 | <$list filter="[all[shadows+tiddlers]tag[$:/tags/PageTemplate]!has[draft.of]]" variable="listItem"> 31 | 32 | <$transclude tiddler=<>/> 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /tiddlers/_system/core/ui/SideBarSegments/search.tid: -------------------------------------------------------------------------------- 1 | created: 20190726013300788 2 | modified: 20190726013302318 3 | tags: $:/tags/SideBarSegment 4 | title: $:/core/ui/SideBarSegments/search 5 | 6 | 57 | -------------------------------------------------------------------------------- /tiddlers/_system/palette.tid: -------------------------------------------------------------------------------- 1 | created: 20171210200656891 2 | modified: 20171210200719659 3 | title: $:/palette 4 | type: text/vnd.tiddlywiki 5 | 6 | $:/palettes/Blanca -------------------------------------------------------------------------------- /tiddlers/_system/themes_tiddlywiki_vanilla_options_sidebarlayout.tid: -------------------------------------------------------------------------------- 1 | created: 20171211035204892 2 | modified: 20171211035206170 3 | title: $:/themes/tiddlywiki/vanilla/options/sidebarlayout 4 | type: text/vnd.tiddlywiki 5 | 6 | fluid-fixed -------------------------------------------------------------------------------- /tiddlers/wiki/-$_/plugins/ebalster/formula---207639789.tid: -------------------------------------------------------------------------------- 1 | created: 20191228021127892 2 | modified: 20191228021127892 3 | title: -$:/plugins/ebalster/formula---207639789 4 | 5 | contents -------------------------------------------------------------------------------- /tiddlers/wiki/-$_/plugins/ebalster/formula.tid: -------------------------------------------------------------------------------- 1 | created: 20191228021121773 2 | modified: 20191228021121773 3 | title: -$:/plugins/ebalster/formula 4 | 5 | yes -------------------------------------------------------------------------------- /tiddlers/wiki/Argument List.tid: -------------------------------------------------------------------------------- 1 | bnf: = "" | | "," 2 | created: 20171212035523565 3 | modified: 20171212035654587 4 | tags: Syntax 5 | title: Argument List 6 | type: text/vnd.tiddlywiki 7 | 8 | -------------------------------------------------------------------------------- /tiddlers/wiki/Array Literal.tid: -------------------------------------------------------------------------------- 1 | bnf: ::= '{' '}' 2 | created: 20180211213818335 3 | modified: 20180211214103727 4 | tags: Syntax 5 | title: Array Literal 6 | type: text/vnd.tiddlywiki 7 | 8 | An ''Array Literal'' in Formulas is expressed as a pair of curly braces containing a series of [[expressions|Expression]] separated by commas. 9 | 10 | ``` 11 | {1, 2, 3, "fork"} 12 | ``` 13 | 14 | The syntax is similar to the one used in popular spreadsheet software. 2D arrays with `;` are not currently supported, however. -------------------------------------------------------------------------------- /tiddlers/wiki/ArrayValue.tid: -------------------------------------------------------------------------------- 1 | created: 20171214035639757 2 | modified: 20171222230252190 3 | tags: ValueType 4 | title: ArrayValue 5 | type: text/vnd.tiddlywiki 6 | 7 | An ''Array Value'' is a [[Value]] expressing a number of other values in a sequence. A formula with an array result will be converted into a string that lists the elements of the array separated by commas. 8 | 9 | A [[Filter]] produces an array. [[Summing operators|Operators]] can add up all the elements in an array. -------------------------------------------------------------------------------- /tiddlers/wiki/Auto-Map Debug.tid: -------------------------------------------------------------------------------- 1 | created: 20180107193147185 2 | modified: 20180110040752046 3 | tags: 4 | title: Auto-Map Debug 5 | type: text/vnd.tiddlywiki 6 | 7 | \define formulaFixed() 2 8 | 9 | \define point_x(pointvar) regexextract1(<<$pointvar$>>,'([^,]+),','0',1) 10 | \define point_y(pointvar) regexextract1(<<$pointvar$>>,',([^,]+)','0',1) 11 | 12 | <$tiddler tiddler="$:/temp/self-organizing-map"> 13 | 14 | Frame number: {{!!counter}} 15 | 16 |
    17 | <$list variable=id filter="[all[current]indexes[]]"> 18 | <$vars p={{{ [all[current]getindex] }}}> 19 | <$formula-vars $noRebuild x=<> y=<> > 20 |
  • <>: (<

    >) => (<>,<>)

  • 21 | 22 | 23 | 24 |
25 | 26 | Links 27 | 28 | -------------------------------------------------------------------------------- /tiddlers/wiki/Auto-Map.tid: -------------------------------------------------------------------------------- 1 | created: 20180107173851197 2 | modified: 20180204012007527 3 | tags: [[Formula Plugin]] [[Timer Plugin]] Demo 4 | title: Auto-Map 5 | type: text/vnd.tiddlywiki 6 | 7 | \define formulaFixed() 2 8 | 9 | \define point_x(pointvar) regexextract1(<<$pointvar$>>,'([^,]+),','0',1) 10 | \define point_y(pointvar) regexextract1(<<$pointvar$>>,',([^,]+)','0',1) 11 | 12 | This tiddler creates a dynamically-generated map of tiddlers in the host wiki which link directly or indirectly to the original one, [[Formula Plugin]]. 13 | 14 | This program is an experiment in progress. Its current implementation uses a large number of action-setfield to update the map each frame, which has proven too inefficient to perform well. 15 | 16 | Uses: 17 | 18 | * [[Formula Plugin]] 19 | * [[Timer Plugin]] 20 | * [[Condition Plugin]] 21 | 22 | {{Auto-Map/Controls}} 23 | 24 | {{Auto-Map/Render}} 25 | 26 | {{Auto-Map/Logic}} 27 | 28 | 29 | The moving parts: 30 | 31 | * [[State Tiddler|$:/temp/self-organizing-map]] 32 | * [[Auto-Map Debug]] 33 | * [[Auto-Map/Controls]] 34 | * [[Auto-Map/Render]] 35 | * [[Auto-Map/Logic]] 36 | * [[Auto-Map/Logic-Old]] -------------------------------------------------------------------------------- /tiddlers/wiki/Auto-Map/Controls.tid: -------------------------------------------------------------------------------- 1 | created: 20180204004452051 2 | modified: 20180204004455591 3 | title: Auto-Map/Controls 4 | type: text/vnd.tiddlywiki 5 | 6 | <$tiddler tiddler="$:/temp/self-organizing-map"> 7 | 8 | Build: 9 | <$button>Set up 10 | <$action-setfield indirection=0 /> 11 | <$action-setfield text="""{"Formula Plugin": "0,0"}""" type="application/json" /> 12 | 13 | <$button>Add a level 14 | <$action-setfield indirection=(= {{!!indirection}}+1 =) /> 15 | <$list variable=a filter="[all[current]indexes[]]"> 16 | <$list variable=b filter="[links[]!is[system]] -[all[current]indexes[]]"> 17 | <$action-setfield $index=<> $value=(= randbetween(-100, 100) & ',' & randbetween(-100,100) =) /> 18 | 19 | 20 | 21 | <$if value={{!!indirection}}> 22 | Organize: 23 | <$button>Start<$action-setfield next-tick=<> dt=.05 /> 24 | <$button>Stop<$action-setfield next-tick="" dt=0/> 25 | 26 | 27 | (Levels of indirection: {{!!indirection}}) 28 | 29 | -------------------------------------------------------------------------------- /tiddlers/wiki/Auto-Map/Logic-Old.tid: -------------------------------------------------------------------------------- 1 | created: 20180204004357400 2 | modified: 20180204004408141 3 | title: Auto-Map/Logic-Old 4 | type: text/vnd.tiddlywiki 5 | 6 | Old logic: 7 | 8 | ``` 9 | <$vars p_a={{{[all[current]getindex]}}}> 10 | <$formula-vars $noRebuild x_a=<> y_a=<> > 11 | 12 | <$formula-vars $noRebuild b="nth([links[]]-[], randbetween(1,count([links[]]-[])))"> 13 | <$vars p_b={{{[all[current]getindex]}}}> 14 | <$formula-vars $noRebuild x_b=<> y_b=<> > 15 | <$if value=(= (<>-<>)^2+(<>-<>)^2 > 300 =)> 16 | <$action-setfield $index=<> $value=(= mix(<>,<>,.05) & ',' & mix(<>,<>,.05) =)/> 17 | 18 | 19 | 20 | 21 | 22 | <$list variable=b filter="[all[current]indexes[]] -[]"> 23 | <$vars p_b={{{[all[current]getindex]}}}> 24 | <$formula-vars $noRebuild x_b=<> y_b=<> > 25 | <$formula-vars $noRebuild dist2="(<>-<>)^2+(<>-<>)^2" dir="atan2(<>-<>,<>-<>)" > 26 | <$if value=(= <> < 200 =)> 27 | <$action-setfield $index=<> $value=(= <>+5*cos(<>)+randbetween(-3,3) & ',' & <>+5*sin(<>)+randbetween(-3,3) =)/> 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | ``` -------------------------------------------------------------------------------- /tiddlers/wiki/Auto-Map/Logic.tid: -------------------------------------------------------------------------------- 1 | created: 20180204003908676 2 | modified: 20180211234707847 3 | title: Auto-Map/Logic 4 | type: text/vnd.tiddlywiki 5 | 6 | \define formulaFixed() 2 7 | 8 | <$tiddler tiddler="$:/temp/self-organizing-map"> 9 | 10 | 11 | 12 | <$if value={{!!dt}}> 13 | 14 | <$timer interval={{!!dt}}> 15 | 16 | <$list variable=a filter="[all[current]indexes[]]"> 17 | <$formula-vars $fixed=2 newpos=""" 18 | let 19 | ( 20 | // getXY grabs index 'i' and turns it into an array {x,y}. 21 | parseVec = function(i):(map(function(s):(value(s)), 22 | split(transclude_index(<>, i),','))), 23 | 24 | // setXY turns X and Y values into a glued string 25 | encodeVec = function(x,y):(x&','&y), 26 | 27 | vecX = function(v):(nth(v,1)), 28 | vecY = function(v):(nth(v,2)), 29 | 30 | // Unpack point A 31 | aVec = parseVec(<>), 32 | a_x = vecX(aVec), a_y = vecY(aVec), 33 | 34 | // Proximity function 35 | proximity_rule = function(b,offset_func) : 36 | ( 37 | let 38 | ( 39 | // Unpack point B 40 | bVec = parseVec(b), 41 | b_x = vecX(bVec), b_y = vecY(bVec), 42 | 43 | // Compute the distance 44 | distance = ((b_x-a_x)^2+(b_y-a_y)^2)^.5, 45 | 46 | // Compute the offset magnitude 47 | offset = offset_func(distance), 48 | 49 | // Compute the offset 50 | off_x = (b_x-a_x) * offset/distance, 51 | off_y = (b_y-a_y) * offset/distance 52 | ): 53 | ({off_x,off_y}) 54 | ), 55 | 56 | // Attraction 57 | repulse_step = function(dist):(-5 / (1 + dist/10)^2), 58 | attract_step = function(dist):(.25 * (dist/20)^2), 59 | 60 | attract_rule = function(b) : (if(transclude_index(<>, b), proximity_rule(b, attract_step), {0,0})), 61 | repulse_rule = function(b) : (proximity_rule(b, repulse_step)), 62 | 63 | attract = map(attract_rule, [links[]] [backlinks[]] -[]), 64 | repulse = map(repulse_rule, [all[current]indexes[]] -[]), 65 | 66 | allX = function(vec):(vecX(vec)), 67 | allY = function(vec):(vecY(vec)), 68 | 69 | move_x = sum(map(allX, attract), map(allX, repulse)), 70 | move_y = sum(map(allY, attract), map(allY, repulse)) 71 | ): 72 | ( 73 | encodeVec( 74 | clamp(a_x + move_x + randbetween(-1,+1), -95, +95), 75 | clamp(a_y + move_y + randbetween(-1,+1), -95, +95)) 76 | ) 77 | """> 78 | <$action-setfield $index=<> $value=<> /> 79 | 80 | 81 | <$action-setfield counter=(= {{!!counter}}+1 =)/> 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /tiddlers/wiki/Auto-Map/Render.tid: -------------------------------------------------------------------------------- 1 | created: 20180204004252562 2 | modified: 20180204011841079 3 | title: Auto-Map/Render 4 | type: text/vnd.tiddlywiki 5 | 6 | <$tiddler tiddler="$:/temp/self-organizing-map"> 7 | 8 | 9 | 10 | 11 | 12 | <$list variable=a filter="[all[current]indexes[]]"> 13 | <$list variable=b filter="[links[]] -[]"> 14 | <$vars 15 | p_a={{{[all[current]getindex]}}} 16 | p_b={{{[all[current]getindex]}}}> 17 | >,','),1) =) 19 | y1=(= nth(split(<>,','),2) =) 20 | x2=(= nth(split(<>,','),1) =) 21 | y2=(= nth(split(<>,','),2) =)/> 22 | 23 | 24 | 25 | 26 | <$list variable=id filter="[all[current]indexes[]]"> 27 | <$vars p={{{[all[current]getindex]}}}> 28 | >>>,','),1) =) cy=(= nth(split(<

>,','),2) =) r=5/> 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /tiddlers/wiki/BNF Grammar.tid: -------------------------------------------------------------------------------- 1 | bnf: 2 | created: 20171211224604559 3 | modified: 20171212080303311 4 | tags: 5 | title: BNF Grammar 6 | type: text/vnd.tiddlywiki 7 | 8 |

<$list filter="[has[bnf]!has[draft.of]]">
 9 | <{{!!title}}> ::= <$text text={{!!bnf}}>
10 | 11 |
-------------------------------------------------------------------------------- /tiddlers/wiki/BooleanValue.tid: -------------------------------------------------------------------------------- 1 | created: 20180114203018589 2 | modified: 20180114203230572 3 | tags: ValueType 4 | title: BooleanValue 5 | type: text/vnd.tiddlywiki 6 | 7 | A ''Boolean Value'' is a [[Value]] that can be ''TRUE'' or ''FALSE''. They are typically used to test things and make decisions. -------------------------------------------------------------------------------- /tiddlers/wiki/BuiltInFunction.tid: -------------------------------------------------------------------------------- 1 | auto_prefix: <> 2 | created: 20171229183445172 3 | modified: 20180114194350483 4 | tags: tag 5 | title: BuiltInFunction 6 | type: text/vnd.tiddlywiki 7 | 8 | ''Built-In Functions'' are functions provided by the formula plugin and extensions to it. 9 | 10 | For a listing, see [[Functions]]. -------------------------------------------------------------------------------- /tiddlers/wiki/Candy-Bar.tid: -------------------------------------------------------------------------------- 1 | created: 20171211021254020 2 | modified: 20171211182657109 3 | tags: Expenses 4 | title: Candy-Bar 5 | type: text/vnd.tiddlywiki 6 | value: 2.03 7 | 8 | -------------------------------------------------------------------------------- /tiddlers/wiki/Cell Reference.tid: -------------------------------------------------------------------------------- 1 | bnf: ::= [] | 2 | created: 20171215044125120 3 | modified: 20180212024531903 4 | tags: Syntax 5 | title: Cell Reference 6 | type: text/vnd.tiddlywiki 7 | 8 | A ''Cell Reference'' consists of one or two capital letters followed by one or more digits. These are interpreted as index references for the current (data) tiddler. So writing `B3` in a formula is equivalent to the [[Transclusion]] `{{##B3}}`. 9 | 10 | ``` 11 | (= A1+A2+A3+A4 * B1 =) 12 | ``` 13 | 14 | This is an advanced feature meant to help other developers implement spreadsheets using the Formulas plugin. Currently, the `<$tiddler>` widget is necessary to make this feature work. -------------------------------------------------------------------------------- /tiddlers/wiki/Condition Plugin.tid: -------------------------------------------------------------------------------- 1 | created: 20171230052133191 2 | modified: 20171230054027050 3 | tags: Plugin 4 | title: Condition Plugin 5 | type: text/vnd.tiddlywiki 6 | 7 | {{$:/plugins/ebalster/condition/readme}} 8 | 9 | !Get the Plugin 10 | 11 | <<< 12 | Drag-and-drop this to your wiki: 13 | 14 | {{$:/plugins/ebalster/condition||$:/core/ui/Components/plugin-info}} 15 | <<< -------------------------------------------------------------------------------- /tiddlers/wiki/Date Literal.tid: -------------------------------------------------------------------------------- 1 | created: 20171217215558004 2 | modified: 20171217220533053 3 | tags: Syntax 4 | title: Date Literal 5 | type: text/vnd.tiddlywiki 6 | 7 | A ''Date Literal'' specifies a date and optionally a 24-hour time. The time may include seconds and milliseconds. 8 | 9 | ``` 10 | 2017-12-15 11 | 2017-12-15 13:07 12 | 2017-12-15 13:07 13 | ``` 14 | 15 | Date literals can be used in a [[Datum]] but not in a [[Formula]]. Use the DATE function to create dates in formulas. -------------------------------------------------------------------------------- /tiddlers/wiki/Datum.tid: -------------------------------------------------------------------------------- 1 | bnf: ::= | | | | | 2 | created: 20171211224412729 3 | modified: 20200429022557322 4 | tags: Syntax 5 | title: Datum 6 | type: text/vnd.tiddlywiki 7 | 8 | A ''Datum'' is some text that may be included into a formula by a [[Transclusion]], [[Filter]] or [[Variable]]. It can be: 9 | 10 | * A [[Formula]] starting with an equals sign `=` (spreadsheet style). 11 | * A [[Formula]] in mushroom brackets `(= =)` ([[wikitext style|Formulas in WikiText]]) 12 | * A [[Transclusion]] in curly braces `{{ }}` (yielding another ''Datum''). 13 | * A [[Variable]] in pointy braces `<< >>` (yielding another ''Datum''). 14 | * Some other value, which is treated as a constant. 15 | ** A [[Number Literal]] such as `1.23` 16 | ** A [[Date Literal]] such as `2017-12-15` 17 | ** A TiddlyWiki date as used in the created and modified fields. 18 | ** Any other text 19 | 20 | |!
{{$:/core/images/warning}}
|A 14- or 17-digit number may be interpreted as a TiddlyWiki date, but only if the month, day, hour, minute and second are within acceptable ranges. The chance of this happening randomly is about <$formula formula=100*.12*.31*.24*.60*.60 precision=3/>%.| 21 | 22 | A ''Datum'' is analog to a cell in spreadsheet software. -------------------------------------------------------------------------------- /tiddlers/wiki/Demo_ Bouncy Bounce.tid: -------------------------------------------------------------------------------- 1 | created: 20180106181434935 2 | modified: 20180119013130165 3 | tags: [[Timer Plugin]] Demo 4 | title: Demo: Bouncy Bounce 5 | type: text/vnd.tiddlywiki 6 | 7 | This is a simple simulation meant to demonstrate the use of the [[Timer Plugin]] for iterative computing. 8 | 9 | <$tiddler tiddler="$:/temp/demo-physics"> 10 | 11 | Simulation: <$button>Start<$action-setfield next-tick=<> dt=.05 grav.y=60 /> 12 | <$button>Stop<$action-setfield next-tick="" /> 13 | 14 | Actions: <$button>Reset<$action-setfield pos.x=0 pos.y=0 vel.x=0 vel.y=0 grav.y=60 counter=0 /> 15 | <$button>Kick<$action-setfield vel.x=(= randbetween(-100, 100) =) vel.y=(= randbetween(-140, 0) =) /> 16 | 17 | Frame # {{!!counter}} (<$link>State Tiddler) 18 | 19 | 20 | 21 | 22 | 23 | <$list variable=offset filter="[range[-.025,.025,.005]]"> 24 | >*{{!!vel.x}} =) cy=(= {{!!pos.y}}+<>*{{!!vel.y}}+<>^2*{{!!grav.y}} =) r=5 style="fill:red; opacity:.1"/> 25 | 26 | 27 | 28 | 29 | 30 | 31 | <$if value={{!!next-tick}}> 32 | 33 | <$timer interval={{!!dt}}> 34 | <$formula-vars $noRebuild 35 | move-x=(= {{!!pos.x}}+{{!!vel.x}}*{{!!dt}} =) 36 | move-y=(= {{!!pos.y}}+{{!!vel.y}}*{{!!dt}} =) 37 | > 38 | 39 | <$if value=(= abs(<>) > 100 =)> 40 | <$action-setfield pos.x=(= clamp(<>,-100,100) =) vel.x=(= -.8*sign(<>)*abs({{!!vel.x}}) =) /> 41 | 42 | <$else> 43 | <$action-setfield pos.x=<> /> 44 | 45 | 46 | <$if value=(= <> > 0 =)> 47 | <$action-setfield pos.y=0 vel.y=(= -.8*abs({{!!vel.y}}) =) /> 48 | 49 | <$else> 50 | <$action-setfield pos.y=<> vel.y=(= {{!!vel.y}}+{{!!grav.y}}*{{!!dt}} =) /> 51 | 52 | 53 | <$action-setfield counter=(= {{!!counter}}+1 =)/> 54 | <$action-setfield next-tick=<> /> 55 | 56 | 57 | -------------------------------------------------------------------------------- /tiddlers/wiki/Demo_ Conway's Game of Life.tid: -------------------------------------------------------------------------------- 1 | created: 20180119011423816 2 | modified: 20180120031328684 3 | tags: Demo 4 | title: Demo: Conway's Game of Life 5 | type: text/vnd.tiddlywiki 6 | 7 | \define width() 16 8 | \define height() 16 9 | 10 | \define x_range() [range[1,$(width)$]] 11 | \define y_range() [range[1,$(height)$]] 12 | 13 | \define cell_id() $(x)$-$(y)$ 14 | \define cell_state() {{##$(cell_id)$}} 15 | 16 | \define alive_style() width:1em; height:1em; margin:0; padding:0; background:black; border-radius:.5em; 17 | \define dead_style() width:1em; height:1em; margin:0; padding:0; white; 18 | 19 | 20 | A simple implementation of Conway's game of life with formulas. 21 | 22 | 23 | <$tiddler tiddler="$:/temp/demo-conway"> 24 | 25 | Simulation 26 | <$button>Stop<$action-setfield dt=""/> 27 | <$button>Slow<$action-setfield dt=.4/> 28 | <$button>Medium<$action-setfield dt=.2/> 29 | <$button>Fast<$action-setfield dt=.05/> 30 | 31 | <$button>Make a Glider<$action-setfield type="application/json" text=""" 32 | {"5-5": "1", "5-6": "1", "5-7": "1", "6-5": "1", "7-6": "1"} 33 | """/> 34 | 35 | 36 | 37 | 38 | <$list variable=y filter=<> > 39 | 40 | <$list variable=x filter=<> > 41 | 53 | 54 | 55 | 56 |
42 | <$if value=(= transclude_index(<>, <>) =)> 43 | <$button class=tc-btn-invisible style=<> > 44 | <$action-setfield $index=<> $value=0/> 45 | 46 | 47 | <$else> 48 | <$button class=tc-btn-invisible style=<> > 49 | <$action-setfield $index=<> $value=1/> 50 | 51 | 52 |
57 | 58 | <$link>State tiddler 59 | 60 | 61 | 62 | 63 | 64 | 65 | <$timer interval={{!!dt}} > 66 | <$list variable=y filter=<> ><$list variable=x filter=<> > 67 | <$action-setfield 68 | $tiddler="$:/temp/demo-conway-next" 69 | $index=<> 70 | $value=(= 71 | 72 | /* 73 | inline comment 74 | */ 75 | 76 | // This is our "Conway's game of life" rule. 77 | // Each step, we use it to set the NEW value of each cell, 78 | // based on the OLD value of the cells around it. 79 | let 80 | ( 81 | // Shorthand for "currentTiddler" 82 | data = "$:/temp/demo-conway", 83 | 84 | // Grab a neighbor cell's state (1 or 0). Wrap around the edges. 85 | adj = function(xo, yo): 86 | ( 87 | if(transclude_index(data, 88 | (modulo(<>-1+xo, <>)+1) & '-' & 89 | (modulo(<>-1+yo, <>)+1) ), 1, 0) 90 | ), 91 | 92 | // Sum up the eight neighboring spaces 93 | neighbors = 94 | adj(-1,-1) + adj( 0,-1) + adj(+1,-1) + 95 | adj(-1, 0) + adj(+1, 0) + 96 | adj(-1,+1) + adj( 0,+1) + adj(+1,+1), 97 | 98 | // Note this cell's state. 99 | keep = if(adj(0, 0),1,0) 100 | ): 101 | ( 102 | // Result depends on the number of neighbors... 103 | switch (neighbors, 104 | 0, 0, // 0 neighbors: turn off due to underpopulation. 105 | 1, 0, // 1 neighbor: turn off due to underpopulation. 106 | 2, keep, // 2 neighbors: no change. 107 | 3, 1, // 3 neighbors: turn on due to reproduction. 108 | 0) // 4 or more neighbors: turn off due to overpopulation. 109 | ) 110 | 111 | =) /> 112 | 113 | <$action-setfield text={{$:/temp/demo-conway-next}} /> 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /tiddlers/wiki/Demo_ Harmonic Lattice.tid: -------------------------------------------------------------------------------- 1 | created: 20171229224421758 2 | modified: 20171229224436035 3 | tags: 4 | title: Demo: Harmonic Lattice 5 | type: text/vnd.tiddlywiki 6 | 7 | {{Harmonic Lattice}} -------------------------------------------------------------------------------- /tiddlers/wiki/Demo_ Line Graph.tid: -------------------------------------------------------------------------------- 1 | created: 20180103070200897 2 | func1: (= function(x) : (sin(x/10)*(x*x)/5000) =) 3 | modified: 20180117054902051 4 | tags: Demo 5 | title: Demo: Line Graph 6 | type: text/vnd.tiddlywiki 7 | use-func: func1 8 | 9 | This demo uses the `map` function to compute a function of the form ''y = f(x)'' and plot it as a graph. 10 | 11 | With the introduction of closures, we can write our ''f'' as a function: 12 | 13 | y = {{!!func1}} 14 | 15 | 16 | 17 | 27 | -------------------------------------------------------------------------------- /tiddlers/wiki/Demo_ Real Projective Line.tid: -------------------------------------------------------------------------------- 1 | created: 20171223032412652 2 | modified: 20171229224918654 3 | tags: 4 | title: Demo: Real Projective Line 5 | type: text/vnd.tiddlywiki 6 | 7 | {{Real Projective Line}} -------------------------------------------------------------------------------- /tiddlers/wiki/Demo_ Starburst.tid: -------------------------------------------------------------------------------- 1 | created: 20171215181411828 2 | modified: 20180114203536648 3 | tags: 4 | title: Demo: Starburst 5 | type: text/vnd.tiddlywiki 6 | 7 | Drag this: 8 | 9 | <$edit-text tag=Input tiddler="$:/temp/SvgSlider" field=val type=range class=full-slider/> 10 | 11 | <$tiddler tiddler="$:/temp/SvgSlider"> 12 | 13 | 14 | > style="fill:black;"/> 15 | > style="fill:red;"/> 16 | > style="fill:white;"/> 17 | <$list filter=".1 .2 .3 .4 .5 .6 .7 .8 .9 1" variable=rad> 18 | <$list filter="0 1 2 3 4 5 6 7 8" variable=ori> 19 | >*100*{{!!val}}%^1.2*sin(pi*<>/4.5+{{!!val}}*.08+<>)">> 21 | cy=<>*100*{{!!val}}%^1.2*cos(pi*<>/4.5+{{!!val}}*.06+<>+.5)">> 22 | r=<> style="fill:white;"/> 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /tiddlers/wiki/Demo_ Tabulator.tid: -------------------------------------------------------------------------------- 1 | created: 20171218170936546 2 | modified: 20171218191642209 3 | tags: Demo 4 | title: Demo: Tabulator 5 | type: text/vnd.tiddlywiki 6 | 7 | 8 | 9 | <$vars formulaDateFormat="DD/mmm/YYYY" formulaFixed="2"> 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | <$list filter="[prefix[Demo]tag[Expense]]"> 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
DateDescriptionCost
<$link>(= {{!!date}} =) {{!!summary}} {{!!cost}}

TOTAL: 35 | (= sum([prefix[Demo]tag[Expense]get[cost]]) =) 36 |
Average per day (December): (= sum([prefix[Demo]tag[Expense]get[cost]]) / 31 =)
45 | 46 | -------------------------------------------------------------------------------- /tiddlers/wiki/Demo_ Tabulator/HairCut.tid: -------------------------------------------------------------------------------- 1 | cost: 12.00 2 | created: 20171218171049555 3 | date: 2017-12-01 4 | modified: 20171218234619437 5 | summary: Hair Cut 6 | tags: Expense Data 7 | title: Demo: Tabulator/HairCut 8 | type: text/vnd.tiddlywiki 9 | 10 | -------------------------------------------------------------------------------- /tiddlers/wiki/Demo_ Timed Counter.tid: -------------------------------------------------------------------------------- 1 | created: 20180106070709211 2 | modified: 20180106195245451 3 | tags: 4 | title: Demo: Timed Counter 5 | type: text/vnd.tiddlywiki 6 | 7 | This is a demo of a non-interval timer. It can't keep precise time because it re-sets the timer when the timer is activated. 8 | 9 | 10 | !!Method 1 11 | 12 | <$tiddler tiddler="$:/temp/counter"> 13 | 14 | <$vars v={{$:/temp/search}}> 15 | 16 | <$button>Start<$action-setfield next-tick=<> /> 17 | <$button>Stop<$action-setfield next-tick="" /> 18 | 19 | <$timer time={{!!next-tick}}> 20 | <$action-setfield counter=(= {{!!counter}}+1 =)/> 21 | <$action-setfield next-tick=<> /> 22 | 23 | 24 | Next Tick: <$transclude field=next-tick>NOT SET 25 | 26 | Ticks counted: {{!!counter}} 27 | 28 | 29 | !!Method 2 -------------------------------------------------------------------------------- /tiddlers/wiki/Eval-Tester/Expression.tid: -------------------------------------------------------------------------------- 1 | created: 20171211021239925 2 | modified: 20200428232954882 3 | title: Eval-Tester/Expression 4 | type: text/vnd.tiddlywiki 5 | 6 | round(5*sum([tag[Expenses]get[value]]), 2) -------------------------------------------------------------------------------- /tiddlers/wiki/Eval-Tester/SumFilter.tid: -------------------------------------------------------------------------------- 1 | created: 20171212012803536 2 | modified: 20171212012804589 3 | title: Eval-Tester/SumFilter 4 | type: text/vnd.tiddlywiki 5 | 6 | [has[value]get[value]] -------------------------------------------------------------------------------- /tiddlers/wiki/Evan Balster.tid: -------------------------------------------------------------------------------- 1 | created: 20171212015357949 2 | modified: 20171212015516703 3 | title: Evan Balster 4 | type: text/vnd.tiddlywiki 5 | 6 | Hi, I'm Evan! I'm a big fan of TiddlyWiki and keen to contribute to the corpus of tools for computatinal notetaking. I'm also an audio programmer with experience in compiler design. 7 | 8 | Find me here: 9 | 10 | * Twitter: [[@EvanBalster|https://twitter.com/EvanBalster]] 11 | * GitHub: [[@EvanBalster|https://github.com/EvanBalster]] 12 | * E-mail: [[evan@imitone.com|mailto://evan@imitone.com]] 13 | * [[TiddlyWikiDev group|https://groups.google.com/forum/#!forum/tiddlywikidev]] -------------------------------------------------------------------------------- /tiddlers/wiki/Expression.tid: -------------------------------------------------------------------------------- 1 | bnf: | 2 | created: 20171211224933273 3 | modified: 20180114202739667 4 | tags: Syntax 5 | title: Expression 6 | type: text/vnd.tiddlywiki 7 | 8 | An ''Expression'' consists of one or more [[operands|Operand]] with [[operators|Operator]] acting on them. 9 | 10 | {{Operand}} 11 | 12 | {{Operator}} -------------------------------------------------------------------------------- /tiddlers/wiki/Extending Formulas.tid: -------------------------------------------------------------------------------- 1 | created: 20171213021420297 2 | modified: 20180114000749649 3 | tags: Developer 4 | title: Extending Formulas 5 | type: text/vnd.tiddlywiki 6 | 7 | <<< 8 | ''Warning'': The internal code of the Formulas may still change in a way that breaks extensions. Be prepared to maintain your additions if necessary. 9 | <<< 10 | 11 | !Defining new functions 12 | 13 | Functions are loaded from tiddlers with `module-type: formula-function` at startup. 14 | 15 | Each function is assigned as a field of the module's `exports` object. 16 | 17 | Formula-Functions are usually expressed as JavaScript functions accepting some [[Value Objects|Value Object]] as arguments and returning a [[Value Object]] as a result. Functions may throw (string) exceptions if there is a problem. 18 | 19 | Formula-Functions that behave differently based on the arguments are expressed as objects with the following fields: 20 | 21 | |Property|Meaning|h 22 | |select|Function taking one argument, "operands", that returns the function to be used. The selection is usually based on the number of arguments.| 23 | |construct|| 24 | |min_args|Optional minimum number of arguments. Defaults to zero.| 25 | |min_args|Optional maximum number of arguments. Defaults to unlimited.| 26 | 27 | Either select or construct must be defined. 28 | 29 | See the existing function tiddlers for a starting point: 30 | 31 | <$list filter="[prefix[$:/plugins/ebalster/formula/functions/]]"> 32 | <$link>{{!!title}}
33 | 34 | 35 | In the future, conventions for value conversion may change. Currently, all values are encapsulated in `V_***` objects, and must be converted to usable data using `as***` methods. This is being reconsidered. 36 | 37 | 38 | !Defining new operators 39 | 40 | Operators are defined as objects with a small number of properties, and are loaded from tiddlers with `module-type: formula-operator` at startup. 41 | 42 | Internally, all operators are converted to functions by the formula compiler. 43 | 44 | ``` 45 | 10*3+4^2*2 46 | ``` 47 | 48 | is equivalent to 49 | 50 | ``` 51 | add(multiply(10,3), multiply(pow(4,2), 2)) 52 | ``` 53 | 54 | Each function is assigned as a field of the module's `exports` object. 55 | 56 | Formula-Operators are expressed as objects with the following properties: 57 | 58 | |Property|Meaning|h 59 | | `arity`|Required. The number of operands the operator uses. 1 means unary, 2 means binary. Other numbers are not supported at the moment.| 60 | | `operator`|Required. The operator's symbol, expressed as a string. Should include only symbolic characters, and no spaces.| 61 | | `function`|Required. The function to convert the operator into. Should be a directly-defined formula-function taking `arity` arguments.| 62 | | `precedence`|Required for binary operators. Determines order of operations.| 63 | | `associativity`|Optional. Assign `"right"` to evaluate a binary operator right-to-left rather than left-to-right (the default).| 64 | | `position`|Required for unary operators. `"pre"` for prefix operators, `"post"` for postfix.| 65 | 66 | Prefix unary operators are applied first, in reverse order, followed by postfix unary operators in forward order, followed by binary operators. The predefined binary operators use this order: 67 | 68 | |Category|Operators|Precedence|Associativity|h 69 | |Exponents|`^`|30|right*| 70 | |Multiplication|`* /`|20|| 71 | |Addition|`+ -`|10|| 72 | |Concatenation|`&`|4|| 73 | |Comparison|`= < <= > >= <>`|0|| 74 | 75 | ^^* Right-associativity is not supported yet, but will be in the future.^^ 76 | 77 | 78 | See the existing operators for a starting point: 79 | 80 | <$list filter="[prefix[$:/plugins/ebalster/formula/operators/]]"> 81 | <$link>{{!!title}}
82 | -------------------------------------------------------------------------------- /tiddlers/wiki/Filter.tid: -------------------------------------------------------------------------------- 1 | created: 20171212071049935 2 | modified: 20171222230242839 3 | tags: Syntax 4 | title: Filter 5 | type: text/vnd.tiddlywiki 6 | 7 | A ''Filter'' in a [[Formula]] follows the [[same rules and syntax as ordinary filters|https://tiddlywiki.com/#Filter%20Expression]]. The result is interpreted as an array of [[Data|Datum]]. 8 | 9 | Various [[Functions]] such as `sum` and `textjoin` are made to deal with arrays. -------------------------------------------------------------------------------- /tiddlers/wiki/Formula Plugin.tid: -------------------------------------------------------------------------------- 1 | created: 20171212014005571 2 | modified: 20180204014302949 3 | tags: 4 | title: Formula Plugin 5 | type: text/vnd.tiddlywiki 6 | 7 | \define example(what, code) $what$`$code$`$code$ 8 | 9 | !Welcome! 10 | 11 | This wiki demonstrates the ''Formula'' plugin for TiddlyWiki (version {{$:/plugins/ebalster/formula!!version}}). 12 | 13 | The plugin is designed to give TiddlyWiki the ability to process numbers and other data just like popular spreadsheet software, with the additional flexibility of functional programming for those who need it. 14 | 15 | It's a work in progress so please report any issues you find, preferably [[here on GitHub|https://github.com/EvanBalster/TiddlyWikiFormula/issues]].
(This wiki is running TiddlyWiki <>.) 16 | 17 | 18 | !Get the Plugin 19 | 20 | <<< 21 | Drag-and-drop this to your wiki: 22 | 23 | {{$:/plugins/ebalster/formula||$:/core/ui/Components/plugin-info}} 24 | <<< 25 | 26 | !Features! 27 | 28 | 29 | 30 | <> 31 | <> 32 | <> 33 | < 12 =)">> 34 | <> 35 | <$macrocall $name=example what=variables code="(= <> =)"/> 36 | <> 37 | <formulas" "(= round(5*sum([tag[Expenses]get[value]]), 2) =)">> 38 | <> 39 | <> 40 | <> 41 | <> 42 |
coderesult
43 | 44 | (Precision set to <> decimal places) 45 | 46 | 47 | !Try Me 48 | 49 | {{Try Me}} 50 | 51 | 52 | !Learn More 53 | 54 | * Usage 55 | ** [[Formulas in WikiText]] 56 | ** [[Formulas as Tag Attributes]] 57 | ** [[Syntax]] 58 | ** [[Functions]] 59 | ** [[Operators]] 60 | ** [[FormulaWidget]] 61 | ** [[FormulaVarsWidget]] 62 | ** [[FormulaMacro]] 63 | ** [[range Operator]] 64 | ** [[Condition Plugin]] (if, else and else-if) 65 | * Under the hood 66 | ** [[ChangeLog]] 67 | ** [[Extending Formulas]] 68 | ** [[Design|Formula Plugin/Design]] 69 | ** [[Source Code]] 70 | * Demos & Fun Stuff 71 | ** [[Demo: Conway's Game of Life]] (naturally) 72 | ** [[Auto-Map]] 73 | ** [[Demo: Starburst]] 74 | ** [[Harmonic Lattice]] 75 | ** [[Real Projective Line]] 76 | ** [[Demo: Tabulator]] 77 | ** [[Spreadsheet Prototype]] 78 | 79 | 80 | !Contributions & Feedback 81 | 82 | * [[TiddlyWikiFormula GitHub|https://github.com/EvanBalster/TiddlyWikiFormula]] 83 | * [[TiddlyWiki Mailing List|https://groups.google.com/forum/#!topic/tiddlywiki/bfInUWhAtzo]] 84 | 85 | This plugin is written by [[Evan Balster]]. -------------------------------------------------------------------------------- /tiddlers/wiki/Formula Plugin/Design.tid: -------------------------------------------------------------------------------- 1 | created: 20171212015720773 2 | modified: 20180115044910079 3 | title: Formula Plugin/Design 4 | type: text/vnd.tiddlywiki 5 | 6 | These are some design decisions involved in ''Formulas''' development. 7 | 8 | First and foremost, this plugin is designed to follow the [[Philosophy of Tiddlers|https://tiddlywiki.com/#Philosophy%20of%20Tiddlers:%5B%5BPhilosophy%20of%20Tiddlers%5D%5D]] outlined on the TiddlyWiki homepage. 9 | 10 | 11 | !!Formulas are First-Class Entities 12 | 13 | Formulas are meant to be a first-class computation idiom on the level of transclusion, macros and variables. For this reason, formulas are computed by a dedicated widget rather than a macro. 14 | 15 | In addition to being used in WikiText, formulas should be possible to use as attributes for widgets and tags. This allows for dynamic generation of SVG images without relying on the `$wikify` widget. 16 | 17 | 18 | !!Compatibility with Existing Mechanisms 19 | 20 | Formulas support TiddlyWiki's major mechanisms for fetching information — Variables, Transclusion and Filters — in addition to other formulas. Fields should be possible to transclude into both formulas and WikiText with the same result. 21 | 22 | Formulas ''do not'' support macros — yet. This is a good candidate for later addition. 23 | 24 | Formulas ''do not'' support WikiText, because the result of WikiText processing is an HTML DOM (which is outside the scope of what they do). 25 | 26 | 27 | !!Familiarity 28 | 29 | Formulas are designed to be as similar as possible to the familiar syntax used in TiddlyWiki. [[Transclusion]]s, [[Variable]]s and [[Filter]]s follow TiddlyWiki's existing syntax and behaviors. [[Datum]] values are interpreted using a subset of WikiText rules. 30 | 31 | Formulas are otherwise designed to look and behave similar to their analogs in popular spreadsheet software Microsoft Excel and Google Sheets. 32 | 33 | 34 | !!Extensibility 35 | 36 | New functions may be added to Formulas by defining modules of type `formula-function`. 37 | 38 | New operators may be added to Formulas by defining modules of type `formula-operator`. 39 | 40 | Formulas' internal Value type may encapsulate non-numeric data, and currently supports strings and arrays in a limited fashion. The plugin could be extended for special use-cases like text processing, complex-number math or linear algebra. -------------------------------------------------------------------------------- /tiddlers/wiki/Formula.tid: -------------------------------------------------------------------------------- 1 | bnf: "(=" "=)" 2 | created: 20171211225046860 3 | modified: 20180117061451456 4 | tags: Syntax 5 | title: Formula 6 | type: text/vnd.tiddlywiki 7 | 8 | A Formula is written as an [[Expression]] inside "mushroom brackets" `(= =)`. 9 | 10 | Formulas may contain [[Comments]] in `// line` or `/* multiline */` form. 11 | 12 | {{Expression}} -------------------------------------------------------------------------------- /tiddlers/wiki/FormulaMacro.tid: -------------------------------------------------------------------------------- 1 | created: 20171213014257477 2 | modified: 20171213015033840 3 | title: FormulaMacro 4 | type: text/vnd.tiddlywiki 5 | 6 | !Introduction 7 | 8 | The ''Formula Macro'' is an alternative to the [[Formula Widget|FormulaWidget]] that can be [[used in tag attributes|Formulas as Tag Attributes]]. 9 | 10 | The macro is somewhat less efficient than the widget because it can't store the compiled formula. There are no formatting options at this time. 11 | 12 | 13 | !Parameters 14 | 15 | ;formula 16 | :The formula to evaluate. Same as in [[FormulaWidget]]. 17 | 18 | 19 | !Examples 20 | 21 | ``` 22 | <> 23 | ``` 24 | 25 | <<< 26 | <> 27 | <<< -------------------------------------------------------------------------------- /tiddlers/wiki/FormulaVarsWidget.tid: -------------------------------------------------------------------------------- 1 | created: 20171216220518577 2 | modified: 20180114191900285 3 | tags: Widget 4 | title: FormulaVarsWidget 5 | type: text/vnd.tiddlywiki 6 | 7 | !Introduction 8 | 9 | The `<$formula-vars>` widget works like TiddlyWiki's `$vars` widget, except each attribute is computed as a formula before being assigned to a variable. 10 | 11 | This offers some advantages over using `$vars` with [[Formulas as Tag Attributes]]. 12 | 13 | 14 | !Attributes 15 | 16 | |Attribute|Description|h 17 | |{attributes not starting with $}|Each attribute name specifies a variable name. The attribute value is evaluated as a formula and the result is assigned to the variable.| 18 | |$numberFormat|A format for numbers in the [[numeral.js|http://numeraljs.com/]] style.
Defaults to variable `<>`.| 19 | |$precision|Numbers will include this many significant digits. If no number is specified, the number will be shown at maximum precision.
Defaults to variable `<>`.| 20 | |$fixed|Numbers will include this many digits after the decimal point.
Overrides toPrecision. Defaults to variable `<>`.| 21 | |$dateFormat|A format string for dates that works like the one in TiddlyWiki's `<>` macro.
Defaults to variable `<>`.| 22 | |$noRebuild|__Experimental__. Prevents full DOM rebuild when variables change. This can boost performance substantially but will cause certain elements not to refresh.| 23 | 24 | 25 | !Examples 26 | 27 | ``` 28 | <$formula-vars 29 | catch="14+8" 30 | fahrenheit="6^3+5^3+4^3+3^3+2^3+11"> 31 | 32 | * Catch-<> 33 | * Fahrenheit <> 34 | 35 | 36 | ``` 37 | 38 | <<< 39 | <$formula-vars 40 | catch="14+8" 41 | fahrenheit=6^3+5^3+4^3+3^3+2^3+11> 42 | 43 | * Catch-<> 44 | * Fahrenheit <> 45 | 46 | 47 | <<< -------------------------------------------------------------------------------- /tiddlers/wiki/FormulaWidget.tid: -------------------------------------------------------------------------------- 1 | created: 20171212074056811 2 | modified: 20180114191904361 3 | tags: Widget 4 | title: FormulaWidget 5 | type: text/vnd.tiddlywiki 6 | 7 | !Introduction 8 | 9 | The `<$formula>` widget computes a formula and returns its result as WikiText. 10 | 11 | 12 | !Attributes 13 | 14 | |Attribute|Description|h 15 | |formula|The formula string to be evaluated.| 16 | |outputType|ContentType of the formula result. Defaults to WikiText.| 17 | |outputMode|Parse mode used on the formula result: `inline` (the default) or `block`.| 18 | |numberFormat|A format for numbers in the [[numeral.js|http://numeraljs.com/]] style.
Defaults to variable `<>`.| 19 | |precision|Numbers will include this many significant digits. If no number is specified, the number will be shown at maximum precision.
Defaults to variable `<>`.| 20 | |fixed|Numbers will include this many digits after the decimal point.
Overrides toPrecision. Defaults to variable `<>`.| 21 | |dateFormat|A format string for dates that works like the one in TiddlyWiki's `<>` macro.
Defaults to variable `<>`.| 22 | |debug|Whether to include debug information in the output. (Defaults to 0.)| 23 | 24 | 25 | !Examples 26 | 27 | ``` 28 | <$formula formula="2 * sum([tag[Expenses]get[value]])" toFixed=2/> 29 | ``` 30 | 31 | <<< 32 | <$formula formula="2 * sum([tag[Expenses]get[value]])" toFixed=2/> 33 | <<< -------------------------------------------------------------------------------- /tiddlers/wiki/Formulas as Tag Attributes.tid: -------------------------------------------------------------------------------- 1 | created: 20171212223658588 2 | modified: 20180204012916975 3 | tags: Usage 4 | title: Formulas as Tag Attributes 5 | type: text/vnd.tiddlywiki 6 | 7 | Formulas can currently be used as attributes in HTML tags, widgets and by using the [[Formula Macro|FormulaMacro]]. 8 | 9 | ``` 10 | > 12 | height=<> 13 | viewBox="0 0 100 100"> 14 | > /> 15 | 16 | ``` 17 | 18 |
19 | > 21 | height=<> 22 | viewBox="0 0 100 100"> 23 | > /> 24 | 25 |
26 | 27 | 28 | !!Direct Syntax 29 | 30 | A direct syntax is also possible, but requires modifications to the TiddlyWiki core. It's shorter, avoids "gotchas" with quotes in formulas, and updates faster than the macro version. 31 | 32 | ``` 33 | 37 | 38 | 39 | ``` 40 | 41 |
42 | 46 | 47 | 48 |
49 | 50 | <<< 51 | To enable direct formulas-as-attributes syntax, drag-and-drop this "mod" plugin to your wiki, along with the modloader plugin: 52 | 53 | {{$:/plugins/ebalster/attribute-modules||$:/core/ui/Components/plugin-info}} 54 | 55 | {{$:/plugins/ebalster/modloader||$:/core/ui/Components/plugin-info}} 56 | 57 | This is written as a "mod" for TiddlyWiki 5.1.15 and not guaranteed to work in all future updates. Official support in the TiddlyWiki core is being explored. 58 | <<< -------------------------------------------------------------------------------- /tiddlers/wiki/Formulas as an Attribute Type.tid: -------------------------------------------------------------------------------- 1 | created: 20171216011600256 2 | modified: 20171229191746223 3 | tags: [[Planned Feature]] 4 | title: Formulas as an Attribute Type 5 | type: text/vnd.tiddlywiki 6 | 7 | Add support for the formula syntax as a tag or widget attribute. As compared to the [[FormulaMacro]] this should improve performance and avoid "gotchas" with quoting. 8 | 9 | This is now discussed in [[Formulas as Tag Attributes]]. 10 | 11 | 12 | !!Implementation 13 | 14 | Need to introduce a new Attribute Type. Files to modify: 15 | 16 | * [[$:/core/modules/utils/parseutils.js]] 17 | * [[$:/core/modules/widgets/widget.js]] 18 | * [[$:/core/modules/parsers/wikiparser/wikiparser.js]] (doc only) -------------------------------------------------------------------------------- /tiddlers/wiki/Formulas in WikiText.tid: -------------------------------------------------------------------------------- 1 | created: 20171212021257085 2 | modified: 20171212201719101 3 | title: Formulas in WikiText 4 | type: text/vnd.tiddlywiki 5 | 6 | Formulas are created with a "mushroom bracket" syntax: 7 | 8 | ``` 9 | (= 2 =) 10 | (= add(2, 3) =) 11 | (= "That's all, folks!" =) 12 | ``` 13 | 14 | Values in tiddler fields can be replaced by formulas using the same notation, allowing formulas to be [[transcluded|Transclusion]] into other formulas. 15 | 16 | See [[Syntax]] for more about this notation. 17 | 18 | 19 | !!Formatting Numbers 20 | 21 | The `<$formula>` widget includes attributes to control how numbers are formatted back into text. The variables `<>` and `<>` can be defined to control number formatting in WikiText formulas, as well as any `<$formula>` widgets where these are left unspecified. 22 | 23 | For example, an application calculating dollars and cents might define a fixed display precision of two decimal points: 24 | 25 | ``` 26 | \define formulaFixed() 2 27 | 28 | (= sum([tag[Expenses]get[value]]) =) 29 | ``` 30 | 31 | This will produce a nice round result, like 3.52, as opposed to the raw floating-point value which could be something like 3.5199999999999996. 32 | 33 | 34 | !Examples 35 | 36 | ``` 37 | (= sum([tag[Expenses]get[value]]) =) 38 | ``` 39 | 40 | (= multiply(2, sum([tag[Expenses]get[value]])) =) -------------------------------------------------------------------------------- /tiddlers/wiki/Formulas.tid: -------------------------------------------------------------------------------- 1 | created: 20171229211746845 2 | modified: 20171229211815989 3 | tags: 4 | title: Formulas 5 | type: text/vnd.tiddlywiki 6 | 7 | !>> [[Formula Plugin]] 8 | 9 | This page has been renamed. -------------------------------------------------------------------------------- /tiddlers/wiki/Function Adder.tid: -------------------------------------------------------------------------------- 1 | caption: Add Funcs 2 | created: 20171228045958921 3 | modified: 20180114193351920 4 | tags: $:/tags/SideBar 5 | title: Function Adder 6 | type: text/vnd.tiddlywiki 7 | 8 | <$tiddler tiddler="$:/temp/function-adder"> 9 | 10 | |!Title|<$edit-text field="title-tmp"/>| 11 | |!Name(s)|<$edit-text field="names"/>| 12 | |!Parameters|<$edit-text field="params"/>| 13 | |!Param abbrev.|<$edit-text field="params-short"/>| 14 | |!Return Type|<$edit-text field="return-type"/>| 15 | |!Summary|<$edit-text field="summary" size=40/>| 16 | |!Categories|<$edit-text field="categories"/>| 17 | 18 | <$button>Create 19 | <$action-createtiddler 20 | $basetitle={{!!title-tmp}} 21 | tags="BuiltInFunction" 22 | names={{!!names}} 23 | params={{!!params}} 24 | params-short={{!!params-short}} 25 | return-type={{!!return-type}} 26 | summary={{!!summary}} 27 | categories={{!!categories}}/> 28 | 29 | 30 | <<< 31 | {{!!summary}} 32 | <<< -------------------------------------------------------------------------------- /tiddlers/wiki/Function Call.tid: -------------------------------------------------------------------------------- 1 | bnf: ::= "(" ")" 2 | created: 20171212035346404 3 | modified: 20171215044300209 4 | tags: Syntax 5 | title: Function Call 6 | type: text/vnd.tiddlywiki 7 | 8 | A ''Function Call'' is written as a [[function name|Functions]] followed by a parenthesized list of parameters, each of which is an [[Expression]]: 9 | 10 | ``` 11 | multiply(2.5, {{Apples!!number}}) 12 | ``` 13 | 14 | Functions with zero arguments, like `pi`, may omit the parentheses. -------------------------------------------------------------------------------- /tiddlers/wiki/Function.tid: -------------------------------------------------------------------------------- 1 | created: 20180114194229835 2 | modified: 20180204014009693 3 | title: Function 4 | type: text/vnd.tiddlywiki 5 | 6 | A ''Function'' declared inside a formula uses this syntax: 7 | 8 | ``` 9 | function([,...]):() 10 | ``` 11 | 12 | The function can be treated as a value and passed around normally or given a name using [[LET|LetConstruct]]. It can be called like a normal function (by putting parentheses after it). 13 | 14 | Functions must be called with the correct number of arguments and cannot be overloaded. 15 | 16 | When [[local variables|LocalVariable]] declared outside the function are used inside it, the values are [[captured|https://en.wikipedia.org/wiki/Closure_(computer_programming)]] and will be usable even if the function is called elsewhere. 17 | 18 | Functions defined in formulas are different from the [[built-in functions|BuiltInFunction]] provided by formulas. -------------------------------------------------------------------------------- /tiddlers/wiki/HTML Render Checker.tid: -------------------------------------------------------------------------------- 1 | created: 20180113235712368 2 | modified: 20180113235951840 3 | tags: 4 | title: HTML Render Checker 5 | type: text/vnd.tiddlywiki 6 | 7 | <$wikify text={{Harmonic Lattice}} output=html name=html> 8 |
<$text text=<>/>
-------------------------------------------------------------------------------- /tiddlers/wiki/Harmonic Lattice.tid: -------------------------------------------------------------------------------- 1 | created: 20171215221052525 2 | modified: 20180125035834703 3 | tags: 4 | title: Harmonic Lattice 5 | type: text/vnd.tiddlywiki 6 | 7 | \define lattice-range() 1,$(lattice-depth)$ 8 | 9 | \define slider(field) <$edit-text field="$field$" type=range/> 10 | 11 | \define redline() 12 | > y1=<> x2=<> y2=2000 style="stroke-width: 1; stroke:#FFDDAA; opacity:.3;"/> 13 | > cy=<> r=4 style="fill:#FFEEEA; opacity:.1"/> 14 | > cy=<> r=2 style="fill:#FFFDFB; opacity:.3"/> 15 | > cy=<> r=1 style="fill:#FFFEFD; opacity:.6"/> 16 | \end 17 | 18 | \define number_ball() 19 | > cy=<> r=5 style="fill:#444444; stroke:#555555; opacity: 1;"/> 20 | 21 | > y=<> text-anchor=middle fill=white><>/<> 22 | 23 | \end 24 | 25 | <$tiddler tiddler="Harmonic Lattice/State"> 26 | 27 | <$formula-vars $noRebuild=true lattice-depth="3+floor(50 * {{!!lattice-depth}}%^2)"> 28 | 29 | Meet the "harmonic lattice". 30 | 31 | |!Interpolation|linear|<>|log|{{!!interpolate}}%| 32 | |!Elevation|min|<>|max|{{!!minormax}}%| 33 | |!Lattice Depth|3|<>|53|1-<$text text=<> />| 34 | |!Show Grid|<$checkbox field="octaveList" checked="[range[-60,60,12]]" unchecked=""/> Octaves — <$checkbox field="semitoneList" checked="[range[-60,60,1]]" unchecked=""/> Semitones (equal)|<|<|<| 35 | |!$noRebuild|<$checkbox field="noRebuild" checked=true unchecked=false/> (this will improve performance)|<|<|<| 36 | 37 | 38 | 39 | 40 | <$list variable=n filter={{!!semitoneList}}> 41 | <$formula-vars $noRebuild={{!!noRebuild}} 42 | x="mix(50*2^(<>/12)-150,3*<>,{{!!interpolate}}%)" 43 | y="mix(160-160*.5^(<>/12),3*<>,{{!!interpolate}}%)" 44 | > 45 | > x2=<> style="stroke-width: .5; stroke:#222222;"/> 46 | > y2=<> style="stroke-width: .5; stroke:#222222;"/> 47 | 48 | 49 | <$list variable=n filter={{!!octaveList}}> 50 | <$formula-vars $noRebuild={{!!noRebuild}} 51 | x="mix(50*2^(<>/12)-150,3*<>,{{!!interpolate}}%)" 52 | y="mix(160-160*.5^(<>/12),3*<>,{{!!interpolate}}%)" 53 | > 54 | > x2=<> style="stroke-width: .5; stroke:#444444;"/> 55 | > y2=<> style="stroke-width: .5; stroke:#444444;"/> 56 | 57 | 58 | <$vars lattice="[range]"> 59 | <$list variable="den" filter=<> > 60 | <$list variable="num" filter=<> > 61 | <$if value=<>, <>)=1">>> 62 | <$formula-vars $noRebuild={{!!noRebuild}} 63 | x="""mix( 64 | 50*(<>/<>)-150, 65 | 36*log2(<>/<>), 66 | {{!!interpolate}}%)""" 67 | y="""mix( 68 | 160-160*(1/mix(max(<>,<>), min(<>,<>), {{!!minormax}}%)), 69 | 36*log2(mix(max(<>,<>), min(<>,<>), {{!!minormax}}%)), 70 | {{!!interpolate}}%)""" 71 | > 72 | <> 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /tiddlers/wiki/Harmonic Lattice/State.tid: -------------------------------------------------------------------------------- 1 | created: 20171229233125420 2 | interpolate: 96 3 | lattice-depth: 58 4 | minormax: 0 5 | modified: 20200429023347826 6 | norebuild: true 7 | octavelist: [range[-60,60,12]] 8 | semitonelist: [range[-60,60,1]] 9 | title: Harmonic Lattice/State 10 | type: text/vnd.tiddlywiki -------------------------------------------------------------------------------- /tiddlers/wiki/IFS Function.tid: -------------------------------------------------------------------------------- 1 | created: 20171214064509307 2 | list: 3 | modified: 20180114193336605 4 | tags: BuiltInFunction 5 | title: IFS Function 6 | type: text/vnd.tiddlywiki 7 | 8 | The `IFS` function accepts an even number of arguments, where each pair of arguments is a test followed by a result. The function returns the result after first test that evaluates to TRUE. 9 | 10 | ``` 11 | IFS(test1, result1, test2, result2, test3, result3 ...) 12 | ``` -------------------------------------------------------------------------------- /tiddlers/wiki/LetConstruct.tid: -------------------------------------------------------------------------------- 1 | created: 20180114193132342 2 | modified: 20180204013714838 3 | tags: Syntax 4 | title: LetConstruct 5 | type: text/vnd.tiddlywiki 6 | 7 | A ''Let Expression'' allows one or more [[local variables|LocalVariable]] to be created and used inside it. As a rule of thumb, this is useful when some computed value needs to be used in more than one place. 8 | 9 | Its syntax is: 10 | 11 | ``` 12 | let(=[,=...]):() 13 | ``` 14 | 15 | Where `` is an alphanumeric name for the new variable, `` is an [[expression|Expression]] that computes the variable. One or more variables can be defined. Each variable can use the variables that come before it in its expression. 16 | 17 | `` is an expression produces the result of the `let` construct, and can use any of the local variables. Local variables are //not// available inside called functions or imported formulas. 18 | 19 | LET expressions may be used in any [[Parenthesized Expression]] or [[Function]] (in the body). Values bound by LET behave exactly like function arguments. 20 | 21 | 22 | !!Examples 23 | 24 | Compute x^^5^^: 25 | 26 | ``` 27 | let(x=<>, x2=x*x):(x2*x2*x) 28 | ``` -------------------------------------------------------------------------------- /tiddlers/wiki/LetStatement.tid: -------------------------------------------------------------------------------- 1 | created: 20180114193132342 2 | modified: 20180114194914236 3 | tags: Syntax 4 | title: LetStatement 5 | type: text/vnd.tiddlywiki 6 | 7 | A ''Let Statement'' comes before an [[Expression]], and allows one or more [[local variables|LocalVariable]] to be created. Its syntax is: 8 | 9 | `let(x=<>,x2=x*x):(3*x2-2*x*x2)` 10 | 11 | ``` 12 | let(= [, = ...]):() 13 | ``` 14 | 15 | Where `` is an alphanumeric name for the new variable, `` is an [[expression|Expression]] that computes the variable. One or more variables can be defined. Each variable can use the variables that come before it in its expression. 16 | 17 | The final expression after the `;` produces the result of the formula, and can use any of the local variables. Local variables are //not// available inside called functions or imported formulas. 18 | 19 | Let statements may be used inside a [[Parenthesized Expression]] or [[Function]] (in the body). 20 | 21 | 22 | !!Examples 23 | 24 | Compute 25 | 26 | ``` 27 | let x=<>, x2=x*x; 28 | ``` -------------------------------------------------------------------------------- /tiddlers/wiki/LocalVariable.tid: -------------------------------------------------------------------------------- 1 | created: 20180114193928228 2 | modified: 20180204013806582 3 | tags: Syntax 4 | title: LocalVariable 5 | type: text/vnd.tiddlywiki 6 | 7 | A ''Local Variable'' is a variable that is declared in the enclosing expression through either a [[let assignment|LetConstruct]] or a [[function parameter|Function]]. 8 | 9 | These variables behave differently than TiddlyWiki's `<>`. They will only be available in the piece of formula code where they appear, //not// in any transcluded formulas. 10 | 11 | Local variables can be captured by a [[Function]]. -------------------------------------------------------------------------------- /tiddlers/wiki/Mod-Loader Plugin.tid: -------------------------------------------------------------------------------- 1 | created: 20180121183031138 2 | modified: 20180204013036981 3 | tags: Plugin 4 | title: Mod-Loader Plugin 5 | type: text/vnd.tiddlywiki 6 | 7 | {{$:/plugins/ebalster/modloader/about}} -------------------------------------------------------------------------------- /tiddlers/wiki/Number Literal.tid: -------------------------------------------------------------------------------- 1 | bnf: ::= | "." | "." | "." 2 | created: 20171212073427107 3 | modified: 20171212073734287 4 | tags: Syntax 5 | title: Number Literal 6 | type: text/vnd.tiddlywiki 7 | 8 | A ''Number'' in Formulas may consists of at least one digit and an optional decimal point. `12`, `.001`, `13.5`, `1` and `50000.` are all valid numbers. 9 | 10 | Exponential notation, NaN and infinities are not currently supported. -------------------------------------------------------------------------------- /tiddlers/wiki/NumberValue.tid: -------------------------------------------------------------------------------- 1 | created: 20171214034846179 2 | modified: 20171214035301602 3 | tags: ValueType 4 | title: NumberValue 5 | type: text/vnd.tiddlywiki 6 | 7 | A ''Number Value'' is a [[Value]] expressing a number. A formula with a number result will be converted into a string by the [[FormulaWidget]]. 8 | 9 | Internally, Number Values are 64-bit floating-point numbers. -------------------------------------------------------------------------------- /tiddlers/wiki/Operand.tid: -------------------------------------------------------------------------------- 1 | bnf: | | | | | | 2 | created: 20171210081748019 3 | modified: 20180211214016104 4 | tags: Syntax 5 | title: Operand 6 | type: text/vnd.tiddlywiki 7 | 8 | An ''Operand'' may be: 9 | 10 | |Operand type|example|h 11 | |[[Parenthesized Expression]]|`(2+4)`| 12 | |[[Function Call]]|`add(2, 2)`| 13 | |[[Transclusion]]|`{{Apples!!count}}`| 14 | |[[Variable]]|`<>`| 15 | |[[Filter]]|`[tag[Expenses]get[value]]`| 16 | |[[Number Literal]]|`123.456` or `4` or `.001`| 17 | |[[String Literal]]|`"kittens"` or `'kittens'`| 18 | |[[Array Literal]]|`{1, 2, 3}`| 19 | |[[Regular Expression Literal]]|`/kittens/g`| 20 | |[[Cell Reference]]|`B3`| 21 | |[[Let Expression|LetConstruct]]|`let(x=2):(x+x)`| 22 | |[[Function]]|`function(x):(x*x)`| 23 | |[[Local Variable|LocalVariable]]|`myvar`| -------------------------------------------------------------------------------- /tiddlers/wiki/Operator.tid: -------------------------------------------------------------------------------- 1 | bnf: ??? 2 | created: 20180114202315432 3 | modified: 20180114202407429 4 | tags: Syntax 5 | title: Operator 6 | type: text/vnd.tiddlywiki 7 | 8 | An ''Operator'' is a symbol that goes before, after or between two [[Operands]] and performs a calculation on them. Operators regard a special order of operations. 9 | 10 | See [[Operators]] for more information. -------------------------------------------------------------------------------- /tiddlers/wiki/Operators.tid: -------------------------------------------------------------------------------- 1 | created: 20171213015724889 2 | modified: 20180114203013212 3 | tags: Reference 4 | title: Operators 5 | type: text/vnd.tiddlywiki 6 | 7 | \define t_num() [[number|NumberValue]] 8 | \define t_str() [[string|StringValue]] 9 | \define t_arr() [[array|ArrayValue]] 10 | \define t_bool() [[boolean|BooleanValue]] 11 | 12 | !Introduction 13 | 14 | ''Operators'' let you write concise math functions with automatic prededence. For example, the formula: 15 | 16 | `2+2` 17 | 18 | Evaluates to 4. 19 | 20 | 21 | !Operators 22 | 23 | |Operator|Result|Function|h 24 | |`+a`|<>|Returns the argument.| 25 | |`-a`|<>|Negates the argument.| 26 | |`a+b`|<>|Adds numbers `a` and `b`.| 27 | |`a-b`|<>|Subtracts `b` from `a`.| 28 | |`a*b`|<>|Multiplies numbers `a` and `b`.| 29 | |`a/b`|<>|Divides `a` by `b`.| 30 | |`a^b`|<>|Raises base `a` to exponent `b`.| 31 | |`a=b`|<>|Compare `a` with `b`.| 32 | |`a<>b`|~|~| 33 | |`a>b`|~|~| 34 | |`a=b`|~|~| 37 | |`a%` |<>|Divides `a` by 100.| 38 | |`a&b`|<>|Appends `a` and `b` as strings.| -------------------------------------------------------------------------------- /tiddlers/wiki/Parenthesized Expression.tid: -------------------------------------------------------------------------------- 1 | bnf: ::= "(" ")" 2 | created: 20171213015115229 3 | modified: 20171213015508987 4 | title: Parenthesized Expression 5 | type: text/vnd.tiddlywiki 6 | 7 | A ''Parenthesized Expression'' is an [[Expression]] in parentheses: 8 | 9 | ``` 10 | (2^20 - 10^6) 11 | ``` -------------------------------------------------------------------------------- /tiddlers/wiki/PercentageValue.tid: -------------------------------------------------------------------------------- 1 | created: 20171214035031819 2 | modified: 20180114203250734 3 | tags: RemovedFeature 4 | title: PercentageValue 5 | type: text/vnd.tiddlywiki 6 | 7 | ''Percentage Value'' is no longer a meaningful concept in the formula plugin. It may be imitated using the `%` operator and percentage formatting in `numberFormat` (see [[FormulaWidget]]). -------------------------------------------------------------------------------- /tiddlers/wiki/Performance Notes.tid: -------------------------------------------------------------------------------- 1 | created: 20171229044704323 2 | modified: 20171229044831933 3 | tags: 4 | title: Performance Notes 5 | type: text/vnd.tiddlywiki 6 | 7 | * Lots of widgets execute twice when they don't need to. 8 | * Variable-related widgets initiate re-rendering of children because there's no selectivity for variables. 9 | * Re-rendering $macrocall is really expensive. -------------------------------------------------------------------------------- /tiddlers/wiki/Planned Changes.tid: -------------------------------------------------------------------------------- 1 | created: 20171222192325797 2 | modified: 20180211193507379 3 | tags: 4 | title: Planned Changes 5 | type: text/vnd.tiddlywiki 6 | 7 | !! Major changes 8 | 9 | Features 10 | 11 | * Language-level foreach function or list comprehension? (as opposed to map) 12 | * Series computations 13 | ** Dedicated: `series(i in [range[0,10]]):(x=2):(x=x*x+1):(x)` (too complicated?) 14 | ** Chaining for: `for(i in [range[0,10]], x in series):(if(i=0):(2):(x*x+1)))` 15 | * Hashmap type ("dict"?) 16 | ** Construction 17 | *** `dict(a=1, b=2, c=3)` 18 | ** Access 19 | *** `myDict.label & myDict[myString]` 20 | ** Importing as locals? 21 | * Syntactic support for arrays 22 | ** Excel style literal `{1, 2, 3}` 23 | *** 2D array support?? (meh) 24 | ** Access 25 | *** `myArray[1]` (1-based?) 26 | *** Consider conflict with filter syntax 27 | **** eg. `[tag[A]][otherArray[1]]` 28 | **** Maybe require parens in these cases. 29 | * Backtrace of LET definitions on error 30 | 31 | Architecture 32 | 33 | * Core-friendly support for formulas as attributes 34 | * Less distinction between lambda and builtin functions 35 | ** Same call mechanism 36 | ** Coercion wrapper node? 37 | * Less distinction between local/widget variables 38 | ** Use bare identifier for both locals and stack-vars (giving locals priority) 39 | ** Add "set" in addition to "let" ? 40 | ** `<>` syntax can be non-capturing version for SETs. 41 | ** Proper transclusion implementation 42 | * Expressions may use local variables 43 | ** No brackets required 44 | ** Override TiddlyWiki variables? (Necessary for proper transcludes) 45 | 46 | Changes 47 | 48 | * Smarter comparison of arrays 49 | 50 | Formatting 51 | 52 | * Add global format settings with clear defaults 53 | 54 | <<< 55 | Done 56 | 57 | * Regular expression literals (and coercion) 58 | * Attribute-Modules as a mod/patch plugin 59 | * Support closures in functions? 60 | * LET construct 61 | * Functions 62 | <<< -------------------------------------------------------------------------------- /tiddlers/wiki/Pomodoro Timer.tid: -------------------------------------------------------------------------------- 1 | created: 20180107215224430 2 | modified: 20180107233617512 3 | tags: [[Timer Plugin]] Demo 4 | title: Pomodoro Timer 5 | type: text/vnd.tiddlywiki 6 | 7 | \define formulaFixed() 0 8 | 9 | <$tiddler tiddler="$:/temp/pomo-timer"> 10 | 11 |

12 | <$if value={{!!time-end}}>Time Left: {{!!time-left}} 13 | <$else>Timer Off 14 |

15 | 16 | Pomodoros logged: {{!!block-count}} 17 | 18 | <$button>Start (25 min) 19 | <$action-setfield time-end=(= to_tw_date(add_minutes(now(), 25)) =) /> 20 | 21 | <$button>Start (1 min) 22 | <$action-setfield time-end=(= to_tw_date(add_minutes(now(), 1)) =) /> 23 | 24 | <$button>Cancel 25 | <$action-setfield time-end="" /> 26 | 27 | 28 | 29 | <$timer time={{!!time-end}}> 30 | <$action-setfield time-end="" /> 31 | <$action-setfield block-count=(= {{!!block-count}}+1 =) /> 32 | 33 | 34 | 35 | <$if value={{!!time-end}}> 36 | <$timer interval=1> 37 | <$action-setfield time-left=(= floor(minutes(now(), tw_date({{!!time-end}}))) & ":" & modulo(floor(seconds(now(), tw_date({{!!time-end}}))), 60) =) /> 38 | 39 | -------------------------------------------------------------------------------- /tiddlers/wiki/Real Projective Line.tid: -------------------------------------------------------------------------------- 1 | created: 20171221064018661 2 | modified: 20180114192733571 3 | tags: Explorable 4 | title: Real Projective Line 5 | type: text/vnd.tiddlywiki 6 | 7 | <$importvariables filter="[[Real Projective Line/Macros]]"> 8 | 9 | <$tiddler tiddler="Real Projective Line/State"> 10 | 11 |
12 | 13 | !The Real Projective Line 14 | 15 | The ''Real Projective Line'' is a way to visualize all the real numbers as a continuous "loop". We do this by stitching the ends together at a "point at infinity": 16 | 17 | 18 | 19 | <$formula-vars $noRebuild 20 | unfold="{{!!unfold}}/100" 21 | ang1="2*atan(1 *{{!!unfold}}%)" 22 | strokeWidth="'stroke-width:'&.007*(3-2*{{!!unfold}}%)&';'" 23 | zoom="'scale('&60/(3-2*{{!!unfold}}%)&')'" 24 | inflate="'scale('&(3-2*{{!!unfold}}%)&')'" 25 | > 26 | 27 | > transform=<>> 28 | <> 29 | <$formula-vars $noRebuild 30 | lx1="if(<>=0,-10,0)" 31 | lx2="if(<>=0,+10,0)" 32 | pcr="if(<>=0,0,1/<>)" 33 | pcy="if(<>=0,100,1-1/<>)" 34 | zero="'translate(0, 1) ' & <>" 35 | inf="'translate(0,' & if(<>=0,100,1-2/<>) & ') ' & <>" 36 | pos1="'translate(' & (+1+cos(<>)) & ',' & (1-sin(<>)) & ') ' & <>" 37 | neg1="'translate(' & (-1-cos(<>)) & ',' & (1-sin(<>)) & ') ' & <>" 38 | > 39 | > x2=<> y1=1 y2=1 stroke=#FFFFFF/> 40 | > r=<> stroke=#FFFFFF fill=none/> 41 | <$list variable="n" filter="[[-5]] [[+5]] [[-3]] [[+3]] [[-2]] [[+2]]"> 42 | <$formula-vars $noRebuild angN="2*atan(<>*{{!!unfold}}%)"> 43 | <$formula-vars $noRebuild posN="'translate(' & <>*(+1+cos(<>)) & ',' & 1-<>*sin(<>) & ') ' & <>"> 44 | <$macrocall $name=RPL_orb transform=<> text=<>/> 45 | 46 | 47 | 48 | <$macrocall $name=RPL_orb transform=<> text="0"/> 49 | <$macrocall $name=RPL_orb transform=<> text="+1"/> 50 | <$macrocall $name=RPL_orb transform=<> text="–1"/> 51 | <$macrocall $name=RPL_orb transform=<> text="∞" style="font-size: .14pt;"/> 52 | 53 | 54 | 55 | 56 | <> 57 | 58 | 59 |
60 | 61 | <> 62 | 63 | Drag this slider to transform the number line into the projective line. 64 | 65 |
66 | 67 | 68 | We arrange all the "projective" numbers into a circle, then find the real number by shooting a ray from the apex of the circle, through the projective point, and onto the number line. 69 | 70 | 71 | 72 | 73 | <> 74 | <$formula-vars $noRebuild 75 | theta="PI+PI*2*{{!!orientation}}%" 76 | n="2*tan(.5*PI+PI*{{!!orientation}}%)" 77 | > 78 | <$formula-vars $noRebuild 79 | $fixed=1 80 | degrees="{{!!orientation}}%*180-90" 81 | nshow="if(abs({{!!orientation}}-50)=50,'infinity',tan(.5*PI+PI*{{!!orientation}}%))" 82 | > 83 | <$formula-vars $noRebuild 84 | sin="sin(<>)" 85 | cos="cos(<>)" 86 | x1="-10*<>" y1=-21 87 | x2="+10*<>" y2="19" 88 | > 89 | 90 | > y1=<> x2=<> y2=<> stroke=#333333/> 91 | >,-10) =) y1=(= mix(-1,1,-10) =) 93 | x2=(= mix(0,<>,+10) =) y2=(= mix(-1,1,+10) =) stroke=#666666/> 94 | > cy=<> r=.02 fill=#FFFFFF/> 95 | > cy=1 r=.025 fill=#FFFFFF/> 96 | 97 | <$text text=<>/>° 98 | <$text text=<>/> 99 | 100 | 101 | 102 | 103 | <> 104 | 105 | <> 106 | 107 | 108 |
109 | 110 | <> 111 | 112 | <$button>flip horizontal<$action-setfield orientation=<>/> 113 | 114 | <$button>flip vertical<$action-setfield orientation=<50,150,50)-{{!!orientation}}">>/> 115 | 116 | 117 |
118 | 119 |
120 | Use the slider to move the projective point around. 121 |
122 | 123 | Notice how when you set the orientation to plus or minus 90 degrees, the number becomes infinite — the ray can never hit the number line. 124 | 125 | This numbering system has some fascinating properties. Flipping the projective point left-to-right negates the real number, while flipping vertically results in its reciprocal. 126 | 127 | In projective mathematics, infinity and zero are reciprocals, and infinity isn't positive or negative — it's "just" infinity. 128 | 129 | By turning the projective circle into a sphere, we can model vectors in higher dimensions, or complex numbers. 130 | 131 |
-------------------------------------------------------------------------------- /tiddlers/wiki/Real Projective Line/Macros.tid: -------------------------------------------------------------------------------- 1 | created: 20171223032458726 2 | modified: 20171229225909454 3 | tags: 4 | title: Real Projective Line/Macros 5 | type: text/vnd.tiddlywiki 6 | 7 | \define formulaPrecision() 4 8 | 9 | \define RPL_realLine() 10 | 11 | <$list filter="[range[-5,5]]" variable="x"> 12 | > x2=<> y1=.97 y2=1.03 stroke=#999999/> 13 | 14 | \end 15 | 16 | \define RPL_projLine() 17 | 18 | 19 | 20 | 21 | 22 | \end 23 | 24 | \define RPL_orb(transform, text, style:"") 25 | 26 | 27 | $text$ 28 | 29 | \end 30 | 31 | \define RPL_projLabels() 32 | 0 33 | –1 34 | +1 35 | 36 | \end 37 | 38 | \define RPL_background() 39 | <> 40 | <> 41 | \end 42 | 43 | \define RPL_title(title) 44 | $title$ 45 | \end 46 | 47 | \define RPL_foreground() 48 | <> 49 | \end 50 | 51 | \define slider(field) <$edit-text field="$field$" class="full-slider" type=range/> -------------------------------------------------------------------------------- /tiddlers/wiki/Real Projective Line/State.tid: -------------------------------------------------------------------------------- 1 | created: 20171229225120154 2 | modified: 20200429023310688 3 | orientation: 50 4 | title: Real Projective Line/State 5 | type: text/vnd.tiddlywiki 6 | unfold: 100 -------------------------------------------------------------------------------- /tiddlers/wiki/Refresh Optimizations.tid: -------------------------------------------------------------------------------- 1 | created: 20180117161323673 2 | modified: 20180117171130927 3 | tags: 4 | title: Refresh Optimizations 5 | type: text/vnd.tiddlywiki 6 | 7 | * Add variables to selective refresh 8 | * Selective broadcast of refresh events (rather than all widgets) 9 | * Does each action widget initiate a refresh or do they accumulate? 10 | * Minimize calls to setAttributeNS 11 | 12 | Unrelated: 13 | 14 | * Action widget deserializer/serializer -------------------------------------------------------------------------------- /tiddlers/wiki/RegexTiddler.tid: -------------------------------------------------------------------------------- 1 | created: 20180124060036323 2 | modified: 20180124060100656 3 | tags: 4 | title: RegexTiddler 5 | type: text/vnd.tiddlywiki 6 | 7 | /abcd[ef]g*/gi -------------------------------------------------------------------------------- /tiddlers/wiki/Regular Expression Literal.tid: -------------------------------------------------------------------------------- 1 | created: 20180204013220979 2 | modified: 20180211213809455 3 | tags: Syntax 4 | title: Regular Expression Literal 5 | type: text/vnd.tiddlywiki 6 | 7 | A ''Regular Expression Literal'' expresses a text-matching expression, and uses [[the same syntax as in JavaScript|https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions]]. 8 | 9 | ``` 10 | /hello/ig 11 | ``` 12 | 13 | Regular expressions are a powerful way to search and capture text information, but a full explanation is outside the scope of this document. -------------------------------------------------------------------------------- /tiddlers/wiki/Repack Helper_ attribute-modules.tid: -------------------------------------------------------------------------------- 1 | created: 20171225055116250 2 | modified: 20180123231614314 3 | tags: 4 | title: Repack Helper: attribute-modules 5 | type: text/vnd.tiddlywiki 6 | 7 | Repacking command (use this in the browser console to repack the plugin) 8 | 9 |
$tw.utils.repackPlugin("$:/plugins/ebalster/attribute-modules", (= "[" & textjoin(",",
10 |  TRUE,
11 |  [all[tiddlers]prefix[$:/plugins/ebalster/attribute-modules/]] +[addprefix["]addsuffix["]]) & "]" =));
12 | 
13 | 14 | Version: <$edit-text tiddler="$:/plugins/ebalster/attribute-modules" field="version" /> -------------------------------------------------------------------------------- /tiddlers/wiki/Repack Helper_ condition.tid: -------------------------------------------------------------------------------- 1 | created: 20180115045029295 2 | modified: 20180121190952214 3 | tags: 4 | title: Repack Helper: condition 5 | type: text/vnd.tiddlywiki 6 | 7 | Repacking command (use this in the browser console to repack the plugin) 8 | 9 |
$tw.utils.repackPlugin("$:/plugins/ebalster/condition", (= "[" & textjoin(",",
10 |  TRUE,
11 |  [prefix[$:/plugins/ebalster/condition/]addprefix["]addsuffix["]]) & "]" =));
12 | 
13 | 14 | Version: <$edit-text tiddler="$:/plugins/ebalster/condition" field="version" /> -------------------------------------------------------------------------------- /tiddlers/wiki/Repack Helper_ formula.tid: -------------------------------------------------------------------------------- 1 | created: 20171213045849235 2 | modified: 20180117065625304 3 | tags: 4 | title: Repack Helper: formula 5 | type: text/vnd.tiddlywiki 6 | 7 | Repacking command (use this in the browser console to repack the plugin) 8 | 9 |
$tw.utils.repackPlugin("$:/plugins/ebalster/formula", (= "[" & join(",",
10 |  [prefix[$:/plugins/ebalster/formula/]addprefix["]addsuffix["]]) & "]" =));
11 | 
12 | 13 | Version: <$edit-text tiddler="$:/plugins/ebalster/formula" field="version" /> -------------------------------------------------------------------------------- /tiddlers/wiki/Repack Helper_ modloader.tid: -------------------------------------------------------------------------------- 1 | created: 20180121190933311 2 | modified: 20180121191001681 3 | tags: 4 | title: Repack Helper: modloader 5 | type: text/vnd.tiddlywiki 6 | 7 | Repacking command (use this in the browser console to repack the plugin) 8 | 9 |
$tw.utils.repackPlugin("$:/plugins/ebalster/modloader", (= "[" & textjoin(",",
10 |  TRUE,
11 |  [prefix[$:/plugins/ebalster/modloader/]addprefix["]addsuffix["]]) & "]" =));
12 | 
13 | 14 | Version: <$edit-text tiddler="$:/plugins/ebalster/modloader" field="version" /> -------------------------------------------------------------------------------- /tiddlers/wiki/Repack Helper_ timer.tid: -------------------------------------------------------------------------------- 1 | created: 20180106071137168 2 | modified: 20180106071232220 3 | tags: 4 | title: Repack Helper: timer 5 | type: text/vnd.tiddlywiki 6 | 7 | Repacking command (use this in the browser console to repack the plugin) 8 | 9 |
$tw.utils.repackPlugin("$:/plugins/ebalster/timer", (= "[" & textjoin(",",
10 |  TRUE,
11 |  [prefix[$:/plugins/ebalster/timer/]addprefix["]addsuffix["]]) & "]" =));
12 | 
13 | 14 | Version: <$edit-text tiddler="$:/plugins/ebalster/timer" field="version" /> -------------------------------------------------------------------------------- /tiddlers/wiki/SWITCH Function.tid: -------------------------------------------------------------------------------- 1 | created: 20171214064708742 2 | list: 3 | modified: 20180114193336624 4 | tags: BuiltInFunction 5 | title: SWITCH Function 6 | type: text/vnd.tiddlywiki 7 | 8 | The `SWITCH` function takes a test value, followed by some pairs of case values and result values, and an optional default value. The function returns the result after the first case value equal to the test value. If no case value equals the test value, the function returns the default value (or undefined if none was provided). 9 | 10 | ``` 11 | SWITCH(test, case1, result1, case2, result2, ... [default]) 12 | ``` 13 | 14 | For example, we can display the name of the current weekday with this formula: 15 | 16 | ``` 17 | switch(weekday(now), 18 | 1, "Sun", 2, "Mon", 3, "Tue", 4, "Wed", 19 | 5, "Thu", 6, "Fri", 7, "Sat", 20 | "ERROR") 21 | ``` 22 | 23 | (= switch(weekday(now), 24 | 1, "Sun", 2, "Mon", 3, "Tue", 4, "Wed", 25 | 5, "Thu", 6, "Fri", 7, "Sat", 26 | "ERROR") =) -------------------------------------------------------------------------------- /tiddlers/wiki/Soda-Pop.tid: -------------------------------------------------------------------------------- 1 | created: 20171211021325886 2 | modified: 20171211182702670 3 | tags: Expenses 4 | title: Soda-Pop 5 | type: text/vnd.tiddlywiki 6 | value: 1.49 7 | 8 | -------------------------------------------------------------------------------- /tiddlers/wiki/Source Code.tid: -------------------------------------------------------------------------------- 1 | created: 20171209232942077 2 | modified: 20171221193518936 3 | tags: 4 | title: Source Code 5 | type: text/vnd.tiddlywiki 6 | 7 |
8 |
Core
9 | <$list filter="[all[system]] [all[shadows]] +[prefix[$:/plugins/ebalster/formula/]sort[title]!regexp[functions/]!regexp[operators/]!regexp[filters/]]"> 10 |
<$link>{{!!title}}
11 | 12 |
Functions
13 | <$list filter="[all[system]] [all[shadows]] +[prefix[$:/plugins/ebalster/formula/]sort[title]regexp[functions/]]"> 14 |
<$link>{{!!title}}
15 | 16 |
Operators
17 | <$list filter="[all[system]] [all[shadows]] +[prefix[$:/plugins/ebalster/formula/]sort[title]regexp[operators/]]"> 18 |
<$link>{{!!title}}
19 | 20 |
Filters
21 | <$list filter="[all[system]] [all[shadows]] +[prefix[$:/plugins/ebalster/formula/]sort[title]regexp[filters/]]"> 22 |
<$link>{{!!title}}
23 | 24 | 25 |
-------------------------------------------------------------------------------- /tiddlers/wiki/Spreadsheet Prototype.tid: -------------------------------------------------------------------------------- 1 | created: 20171214072113031 2 | modified: 20180212024731438 3 | tags: 4 | title: Spreadsheet Prototype 5 | type: text/vnd.tiddlywiki 6 | 7 | \define ss_cols() A B C D E F G H I J 8 | \define ss_rows() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 9 | \define ss_cell() $(c)$$(r)$ 10 | 11 | <$tiddler tiddler="Spreadsheet/Data"> 12 | 13 | Click on cells to pop up an editor. Formulas currently need to be written in `(= =)` but cells may be referred to by their names, such as `A2`. Ranges aren't supported yet. 14 | 15 | <$vars popupState=<> popupCell=<> > 16 | 17 | <$reveal type="popup" state=<> > 18 |
19 | 20 | <$set name="cell" filter="[titleget[text]]"> 21 | ''<>'': <$edit-text tag=input index=<> size=30 /> 22 | <$button class="tc-btn-invisible">{{$:/core/images/save-button}}<$action-setfield $tiddler=<> text=""/> 23 | 24 | 25 |
26 | 27 | 28 | 29 | <$list variable=c filter=<> > 30 | <$list variable=r filter=<> > 31 | 32 | 33 | <$list variable=c filter=<> > 37 | 38 | 39 | 40 |
<>
<> 34 | <$button popup=<> style="width:100%;margin:0;padding:6px;display:block;background:none;border:none;cursor:pointer;"><$action-setfield $tiddler=<> text=<>/> <$formula formula=<>/> 35 | 36 |
41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | [[Data Tiddler|Spreadsheet/Data]] -------------------------------------------------------------------------------- /tiddlers/wiki/Spreadsheet/Data.tid: -------------------------------------------------------------------------------- 1 | created: 20171214072454047 2 | modified: 20180212024751231 3 | tags: 4 | title: Spreadsheet/Data 5 | type: application/json 6 | 7 | { 8 | "A1": "13.41", 9 | "B1": "(=A1=)", 10 | "C1": "=sum(A1, B1)", 11 | "D1": "", 12 | "C2": "=C1", 13 | "D2": "", 14 | "B4": "2015-10-02 18:04:30.231" 15 | } -------------------------------------------------------------------------------- /tiddlers/wiki/Startup Module Inspector.tid: -------------------------------------------------------------------------------- 1 | created: 20180120054605112 2 | modified: 20180120055617413 3 | tags: 4 | title: Startup Module Inspector 5 | type: text/vnd.tiddlywiki 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | <$list filter="[all[shadows]module-type[startup]]"> 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
ModuleBeforeAfterSync
<$link>{{!!title}}(= regexextract1({{!!text}}, "^.*exports\\s*\\.\\s*before(.*)$(?m)", "—", 1) =)(= regexextract1({{!!text}}, "^.*exports\\s*\\.\\s*after(.*)$(?m)", "—", 1) =)(= regexextract1({{!!text}}, "^.*exports\\s*\\.\\s*synchronous(.*)$(?m)", "—", 1) =)
-------------------------------------------------------------------------------- /tiddlers/wiki/String Literal.tid: -------------------------------------------------------------------------------- 1 | bnf: ::= '"' '"' 2 | created: 20171212073742019 3 | modified: 20171222223456068 4 | tags: Syntax 5 | title: String Literal 6 | type: text/vnd.tiddlywiki 7 | 8 | A ''String Literal'' in Formulas is a quoted piece of text. `'single quotes'` or `"double quotes"` may be used. 9 | 10 | The backslash `\` may be used to "escape" characters that are difficult to include in the string normally: 11 | 12 | |Escape Code|Result|h 13 | |`\\`|`\`| 14 | |`\'`|`'`| 15 | |`\"`|`"`| 16 | |`\n`|Line break.| 17 | |`\r`|Carriage return.| 18 | |`\t`|Horizontal tab.| 19 | |`\v`|Vertical tab.| 20 | |`\f`|Form Feed.| 21 | |`\b`|Backspace.| 22 | |`\0`|Null character.| 23 | |`\u1234`|Unicode character #1234. (Any 4-digit hexadecimal value may be used.)| 24 | 25 | Strings may be concatenated with other values using the `&` [[operator|Operators]], resulting in a string. -------------------------------------------------------------------------------- /tiddlers/wiki/StringValue.tid: -------------------------------------------------------------------------------- 1 | created: 20171214035303251 2 | modified: 20171214035634805 3 | tags: ValueType 4 | title: StringValue 5 | type: text/vnd.tiddlywiki 6 | 7 | A ''String Value'' is a [[Value]] holding some text. A formula with a String result will be returned directly by the [[FormulaWidget]]. 8 | 9 | String Values are written in `'single quotes'` or `"double quotes"`. The quotes are not included in the string. -------------------------------------------------------------------------------- /tiddlers/wiki/StyleSheet.css: -------------------------------------------------------------------------------- 1 | pre, code, .tc-edit-texteditor 2 | { 3 | font-family: Consolas, Monaco, monospace; 4 | font-size: 10pt; 5 | line-height: 15pt; 6 | } 7 | 8 | .tiny-monospace 9 | { 10 | font-family: Consolas, Monaco, monospace; 11 | font-size: 8pt; 12 | line-height: 120%; 13 | } 14 | 15 | .full-slider 16 | { 17 | width: 600px; 18 | } 19 | 20 | td.func_name 21 | { 22 | width: 100px; 23 | text-align: right; 24 | } -------------------------------------------------------------------------------- /tiddlers/wiki/StyleSheet.css.meta: -------------------------------------------------------------------------------- 1 | created: 20171210195326531 2 | modified: 20171229211337845 3 | tags: $:/tags/Stylesheet 4 | title: StyleSheet 5 | type: text/css 6 | -------------------------------------------------------------------------------- /tiddlers/wiki/Syntax Design Resources.tid: -------------------------------------------------------------------------------- 1 | created: 20171224010916150 2 | modified: 20171224011102457 3 | tags: 4 | title: Syntax Design Resources 5 | type: text/vnd.tiddlywiki 6 | 7 | * [[Excel Function List|https://support.office.com/en-us/article/Excel-functions-alphabetical-b3944572-255d-4efb-bb96-c6d90033e188]] 8 | * [[Google Sheets Function List|https://support.google.com/docs/table/25273?hl=en]] 9 | * [[Syntax Across Languages|http://rigaux.org/language-study/syntax-across-languages.html]] by Rigaux -------------------------------------------------------------------------------- /tiddlers/wiki/Syntax.tid: -------------------------------------------------------------------------------- 1 | created: 20171212021244580 2 | modified: 20180117061401956 3 | title: Syntax 4 | type: text/vnd.tiddlywiki 5 | 6 | {{Formula}} 7 | 8 | !!See also 9 | 10 | * [[BNF Grammar]] -------------------------------------------------------------------------------- /tiddlers/wiki/Ten-Sodas.tid: -------------------------------------------------------------------------------- 1 | created: 20171212010911028 2 | modified: 20180106152746992 3 | tags: Expenses 4 | title: Ten-Sodas 5 | type: text/vnd.tiddlywiki 6 | value: (= 10 * {{Soda-Pop!!value}} =) 7 | 8 | Ten sodas are worth ${{!!value}} -------------------------------------------------------------------------------- /tiddlers/wiki/Timer Plugin.tid: -------------------------------------------------------------------------------- 1 | created: 20180107215241247 2 | modified: 20180107223350559 3 | title: Timer Plugin 4 | type: text/vnd.tiddlywiki 5 | 6 | ''Timer Plugin'' (version {{$:/plugins/ebalster/timer!!version}}). 7 | 8 | It can trigger ActionWidgets at regular intervals or at a specific point in time. 9 | 10 | 11 | !Get the Plugin 12 | 13 | <<< 14 | Drag-and-drop this to your wiki: 15 | 16 | {{$:/plugins/ebalster/timer||$:/core/ui/Components/plugin-info}} 17 | <<< -------------------------------------------------------------------------------- /tiddlers/wiki/Transclusion.tid: -------------------------------------------------------------------------------- 1 | bnf: ::= "{{" "}}" | "{{" "!!" "}}" | "{{!!" "}}" 2 | created: 20171212040008526 3 | modified: 20171212210816950 4 | tags: Syntax 5 | title: Transclusion 6 | type: text/vnd.tiddlywiki 7 | 8 | ''Transclusion'' in a Formula or Datum follows the [[same rules and syntax as in WikiText|https://tiddlywiki.com/#Transclusion%20in%20WikiText:%5B%5BTransclusion%20in%20WikiText%5D%5D]]*. The transcluded text is treated as a [[Datum]], rather than WikiText. 9 | 10 | ^^* Filtered Transclusion is not currently supported.^^ -------------------------------------------------------------------------------- /tiddlers/wiki/Try Me.tid: -------------------------------------------------------------------------------- 1 | created: 20171210222937878 2 | modified: 20180114085231317 3 | title: Try Me 4 | type: text/vnd.tiddlywiki 5 | 6 | \define sumExpression() sum( $(sumFilter)$ ) 7 | 8 | Use this area to try out some formulas. 9 | 10 | ;Formula: 11 | :`(=` <$edit-text tag="input" size=60 tiddler="Eval-Tester/Expression"/> `=)` 12 | 13 | ;Result: 14 | :<$formula formula={{Eval-Tester/Expression}} toFixed={{Eval-Tester/toFixed}} toPrecision={{Eval-Tester/toPrecision}}/> 15 | 16 | 17 | Try these: 18 | 19 | <<< 20 | ``` 21 | sum([tag[Expenses]get[value]]) 22 | "Sum(" & [tag[Expenses]get[value]] & ") = " & sum([tag[Expenses]get[value]]) 23 | {{Soda-Pop!!value}}*5 24 | 20 + 3^3 * 1000 25 | "$" & {{Candy-Bar!!value}} 26 | "This is ''bold text''!" 27 | map(function(s):('Bought a '&s&'...'), [tag[Expenses]]) 28 | ``` 29 | <<< 30 | 31 | -------------------------------------------------------------------------------- /tiddlers/wiki/UnitTest/Functions/nth/sorted-return.tid: -------------------------------------------------------------------------------- 1 | created: 20171219214111425 2 | modified: 20171221001250666 3 | tags: UnitTest 4 | title: UnitTest/Functions/nth/sorted-return 5 | type: text/vnd.tiddlywiki 6 | 7 | (= nth([tag[Expenses]!sort[]], 3)="Candy-Bar" =) -------------------------------------------------------------------------------- /tiddlers/wiki/Unpack a Plugin.tid: -------------------------------------------------------------------------------- 1 | created: 20190725225737511 2 | modified: 20190725231616700 3 | tags: 4 | title: Unpack a Plugin 5 | 6 | The following code will unpack a plugin by making 'regular' tiddlers out of each shadow tiddler contained in the plugin. 7 | 8 | <$wikify name="state" text="""<$macrocall $name="qualify" title="$:/state/controlpanel/unpackplugin" />""" > 9 | <$select tiddler=<> field="target"> 10 | <$list filter='[all[]type[application/json]has[plugin-type]sort[title]] -[[$:/core]]'> 11 | 12 | 13 |

14 | 15 | ''Target'': {{{[get[target]]}}}
16 | <$button class="tc-btn-invisible tc-tiddlylink"> 17 | <$list filter="[get[target]plugintiddlers[]]"> 18 | <$action-deletefield jhsfjh/> 19 | 20 | Unpack! 21 |
22 | ''[{{{[get[target]]}}}]plugintiddlers[]'':
23 | <$reveal type="nomatch" state=<> text="show"> 24 | <$button set=<> setTo="show" class="tc-btn-invisible tc-tiddlylink">Show Plugin Tiddlers 25 | 26 | <$reveal type="match" state=<> text="show"> 27 | <$button set=<> setTo="hide" class="tc-btn-invisible tc-tiddlylink">Hide Plugin Tidders 28 |
    <$list filter="[get[target]plugintiddlers[]]"> 29 |
  • <$link>{{!!title}}
  • 30 |
31 | 32 | -------------------------------------------------------------------------------- /tiddlers/wiki/Value.tid: -------------------------------------------------------------------------------- 1 | created: 20171214035458503 2 | modified: 20180114203221002 3 | tags: Concept 4 | title: Value 5 | type: text/vnd.tiddlywiki 6 | 7 | ''Values'' are generated at every stage of a formula and are used for the internal processing. There are a number of built-in value types, and more can be added by extensions: 8 | 9 | <$list filter="[tag[ValueType]]"> 10 | <$link>{{!!title}}
11 | -------------------------------------------------------------------------------- /tiddlers/wiki/Variable.tid: -------------------------------------------------------------------------------- 1 | bnf: = "<<" ">>" 2 | created: 20171212070706273 3 | modified: 20171212210944553 4 | tags: Syntax 5 | title: Variable 6 | type: text/vnd.tiddlywiki 7 | 8 | ''Variables'' in a [[Formula]] or [[Datum]] follow the [[same rules and syntax as in WikiText|https://tiddlywiki.com/#Variables%20in%20WikiText:%5B%5BVariables%20in%20WikiText%5D%5D]]*. The variable's value is interpreted as a [[Datum]], rather than WikiText. 9 | 10 | ^^* Macros with arguments are not currently supported.^^ -------------------------------------------------------------------------------- /tiddlers/wiki/Widget Architecture.tid: -------------------------------------------------------------------------------- 1 | created: 20171222000814739 2 | modified: 20171222073212005 3 | tags: 4 | title: Widget Architecture 5 | type: text/vnd.tiddlywiki 6 | 7 | These are Evan's notes on Widget design. 8 | 9 | Mainly I'm concerned with avoiding redundant logic. I've noticed that some TiddlyWiki core widgets run `execute` twice, and copying them led to repeating this mistake in my formula plugin. 10 | 11 | 12 | {{Widget Architecture/Commonly Overridden Methods}} 13 | 14 | 15 | {{Widget Architecture/Implementor Utility Methods}} 16 | 17 | 18 | {{Widget Architecture/Functionality}} 19 | 20 | 21 | {{Widget Architecture/DOM}} -------------------------------------------------------------------------------- /tiddlers/wiki/Widget Architecture/Commonly Overridden Methods.tid: -------------------------------------------------------------------------------- 1 | created: 20171222014259532 2 | modified: 20171222014300656 3 | tags: 4 | title: Widget Architecture/Commonly Overridden Methods 5 | type: text/vnd.tiddlywiki 6 | 7 | !!Commonly overridden methods 8 | 9 | 10 | <$details summary="render(parent, nextSibling)"> 11 | 12 | Render this widget into the DOM. 13 | 14 | Default: 15 | 16 | ``` 17 | this.parentDomNode = parent; 18 | this.execute(); 19 | this.renderChildren(parent, nextSibling); 20 | ``` 21 | 22 | Called by: 23 | 24 | * `Widget.renderChildren` (from parent) 25 | * `Widget.refreshSelf` (from self) 26 | * `Widget.invokeActionString` (uncommon, for action fields) 27 | 28 | 29 | 30 | <$details summary="execute()"> 31 | 32 | Compute the internal state of the widget 33 | 34 | Default: 35 | 36 | ``` 37 | this.makeChildWidgets(); 38 | ``` 39 | 40 | Called by: 41 | 42 | * `Widget.render` (default implementation) 43 | * `.refresh` (some implementations) 44 | 45 | 46 | 47 | <$details summary="refresh(changedTiddlers) : bool"> 48 | 49 | "Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering" 50 | 51 | Default: 52 | 53 | ``` 54 | this.refreshChildren(changedTiddlers); 55 | ``` 56 | 57 | Called by: 58 | 59 | * `Widget.refreshChildren` (from parent) 60 | 61 | -------------------------------------------------------------------------------- /tiddlers/wiki/Widget Architecture/DOM.tid: -------------------------------------------------------------------------------- 1 | created: 20171222014403570 2 | modified: 20171222014404669 3 | tags: 4 | title: Widget Architecture/DOM 5 | type: text/vnd.tiddlywiki 6 | 7 | !!DOM 8 | 9 | 10 | <$details summary="nextSibling(), previousSibling(), parent"> 11 | 12 | Get relatives in DOM. 13 | 14 | 15 | 16 | <$details summary="findNextSiblingDomNode(firstIndex), findFirstDomNode() TODO"> 17 | 18 | DOM searching? 19 | 20 | -------------------------------------------------------------------------------- /tiddlers/wiki/Widget Architecture/Functionality.tid: -------------------------------------------------------------------------------- 1 | created: 20171222014351538 2 | modified: 20171222014457642 3 | tags: 4 | title: Widget Architecture/Functionality 5 | type: text/vnd.tiddlywiki 6 | 7 | !! Functionality 8 | 9 | <$details summary="getVariable, setVariable, hasVariable, substituteVariableParameters"> 10 | Var stuff; Doc later 11 | 12 | Note: getVariable gets from the PARENT widget. 13 | 14 | <$details summary="evaluateMacroModule(name, actualParams, defaultValue)"> 15 | Var stuff; Doc later 16 | 17 | <$details summary="getStateQualifier"> 18 | Var stuff; Doc later 19 | 20 | 21 | <$details summary="addEventListeners(listeners), addEventListener(type, handler)"> 22 | 23 | "Add a list of event listeners from an array `[{type:,handler:},...]`" 24 | 25 | "Add an event listener". The handler argument can be a method name on this widget or a function to be called with `this`=this widget. 26 | 27 | 28 | 29 | 30 | <$details summary="dispatchEvent(event)"> 31 | 32 | "Dispatch an event to a widget. If the widget doesn't handle the event then it is also dispatched to the parent widget. 33 | 34 | Event has a field `type` which is a string. Returns whether the event was //not// handled. 35 | 36 | 37 | 38 | 39 | <$details summary="invokeActions(triggeringWidget,event) : bool"> 40 | 41 | "Invoke the action widgets that are descendents of the current widget." 42 | 43 | Returns whether event was handled. 44 | 45 | 46 | 47 | 48 | <$details summary="invokeActionString(actions,triggeringWidget,event,variables) : bool"> 49 | 50 | "Invoke the action widgets defined in a string" 51 | 52 | Returns whether event was handled. 53 | 54 | 55 | 56 | 57 | <$details summary="allowActionPropagation()"> 58 | 59 | "Invoke the action widgets defined in a string" 60 | 61 | -------------------------------------------------------------------------------- /tiddlers/wiki/Widget Architecture/Implementor Utility Methods.tid: -------------------------------------------------------------------------------- 1 | created: 20171222014321635 2 | modified: 20171222073336784 3 | tags: 4 | title: Widget Architecture/Implementor Utility Methods 5 | type: text/vnd.tiddlywiki 6 | 7 | !!Implementor Utility Methods 8 | 9 | 10 | <$details summary="Widget(parseTreeNode, options)"> 11 | 12 | Constructor. Calls `initialize`. 13 | 14 | 15 | 16 | 17 | <$details summary="initialize(parseTreeNode, options)"> 18 | 19 | Common init code. Call from constructor. 20 | 21 | 22 | 23 | 24 | <$details summary="computeAttributes()"> 25 | 26 | "Compute the current values of the attributes of the widget. Returns a hashmap of the names of the attributes that have changed" 27 | 28 | Called by: 29 | 30 | * Implementations only 31 | 32 | 33 | 34 | 35 | <$details summary="makeChildWidgets(parseTreeNodes), makeChildWidget(parseTreeNode)"> 36 | 37 | Turn the parse tree nodes into child widgets. Recursive. 38 | 39 | 40 | 41 | 42 | <$details summary="renderChildren(parent, nextSibling)"> 43 | 44 | "Render children into the DOM." 45 | 46 | Broadcasts `render` to children with the same args. 47 | 48 | 49 | 50 | <$details summary="removeChildDomNodes"> 51 | 52 | "Remove any DOM nodes created by this widget or its children." 53 | 54 | Un-renders children. 55 | 56 | 57 | 58 | <$details summary="refreshSelf() TODO"> 59 | 60 | "Rebuild a previously rendered widget." 61 | 62 | ``` 63 | var nextSibling = this.findNextSiblingDomNode(); 64 | this.removeChildDomNodes(); 65 | this.render(this.parentDomNode,nextSibling); 66 | ``` 67 | 68 | 69 | 70 | 71 | <$details summary="refreshChildren(Refresh all the children of a widget) : bool"> 72 | 73 | "Refresh all the children of a widget" 74 | 75 | 76 | 77 | 78 | !!! `assignAttributes(domNode, options)` ... 79 | 80 | !!! `hasAttribute(name), getAttribute(name, defaultText)` ... -------------------------------------------------------------------------------- /tiddlers/wiki/Widget Inspector.tid: -------------------------------------------------------------------------------- 1 | created: 20171228034320667 2 | modified: 20171228034458060 3 | tags: 4 | title: Widget Inspector 5 | type: text/vnd.tiddlywiki 6 | 7 | See the inspectors... 8 | 9 | ;[[Widget Variable Inspector]] 10 | : Inspect variable get & set calls. 11 | 12 | ;[[Widget Refresh Inspector]] 13 | : Inspect the internal (this/self) call graphs of each widget. -------------------------------------------------------------------------------- /tiddlers/wiki/Widget Refresh Inspector.tid: -------------------------------------------------------------------------------- 1 | created: 20171222015158308 2 | modified: 20180124064427213 3 | tags: 4 | title: Widget Refresh Inspector 5 | type: text/vnd.tiddlywiki 6 | 7 | \define detectImplement(method) 8 | (= if(regexmatch({{!!text}}, /\.\s*prototype\s*\.\s*$method$\s*=/g),"Y","n") =) 9 | \end 10 | 11 | \define countSelfCalls(method) 12 | (= count(regexextract({{!!text}}, /(this|self)\s*\.\s*$method$\s*\(/g)) =) 13 | \end 14 | 15 | \define allTest(method) 16 | <> <> 17 | \end 18 | 19 | \define widgetShortName(title) 20 | (= mid(regexextract1("$title$", /\/[a-zA-Z0-9_-]+(?=\.)/, "unknown"), 2, 999) =) 21 | \end 22 | 23 | \define inspectorRow() 24 | 25 | <$link><$macrocall $name=widgetShortName title={{!!title}}/> 26 | <> 27 | <> 28 | <> 29 | <> 30 | 31 | 32 | 33 | <$details summary="View Call Tree"> 34 | <$formula outputType="text/plain" formula=""" 35 | textjoin("", true, regexextract( 36 | textjoin("", true, regexextract({{!!text}}, 37 | /(\n[^\n]*prototype\s*\..+\n|[^\n]*(this|self)\s*\.\s*[a-zA-Z0-9_]+\([^\n]*\n)/g)), 38 | /\n[^\n]*prototype\s*\.[^\n]+\n([\t ][^\n]*\n)+/)) 39 | """/> 40 | 41 | 42 | 43 | \end 44 | 45 | Check the number of calls to this.execute, this.refreshSelf, this.computeAttributes and this.renderChildren in each widget implementation. 46 | 47 | Expand the dropdowns to see //all// calls to methods on "this" or "self". Methods without any this-calls are omitted. 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | <$list filter="[all[shadows]module-type[widget]suffix[widgets/widget.js]]"> 58 | <> 59 | 60 | <$list filter="[all[shadows]module-type[widget]!suffix[widgets/widget.js]]"> 61 | <> 62 | 63 |
Widgetexecuterefresh-
Self
compute-
Attributes
render-
Children
64 | 65 | Method implementation 66 | 67 | [[Widget Call Trees]] 68 | 69 | ``` 70 |
71 | <$list filter="[all[shadows+tiddlers]module-type[widget]]"> 72 |
<$link><$macrocall $name=widgetShortName title={{!!title}}/>
73 |
(= regexextract({{!!text}}, "\\.\\s*prototype\\s*\\.\\s*[a-zA-Z0-9_-]+\\s*=") =)
74 | 75 | 76 |
77 | ``` -------------------------------------------------------------------------------- /tiddlers/wiki/Widget Tree Visualizer.tid: -------------------------------------------------------------------------------- 1 | created: 20171228042423876 2 | modified: 20171228045227341 3 | tags: 4 | title: Widget Tree Visualizer 5 | type: text/vnd.tiddlywiki 6 | 7 | Tiddler: <$edit-text tiddler="$:/state/widget-tree-visualizer" field="target" size=40 /> 8 | 9 | Widget tree: 10 | 11 | <$wikify name=tree output=widgettree text={{{ [title{$:/state/widget-tree-visualizer!!target}get[text]] }}} > 12 |

13 | <$formula formula="""
14 | regexreplace(
15 | regexreplace(
16 | regexreplace(
17 |   textjoin("", true, regexextract(<>,
18 |     "\\n[^\\n]+\"type\":[^\\n]+")),
19 |   "[ \\t]{1,4}", " "),
20 |   '"type": "', ""),
21 |   '",?', "")
22 | """/>
23 | 
24 | -------------------------------------------------------------------------------- /tiddlers/wiki/Widget Variable Inspector.tid: -------------------------------------------------------------------------------- 1 | created: 20171227155501239 2 | modified: 20171229232457610 3 | searchterm: (g|s)etVariable 4 | tags: 5 | title: Widget Variable Inspector 6 | type: text/vnd.tiddlywiki 7 | 8 | \define countVarSets() 9 | (= count(regexextract({{!!text}}, ".\\s*setVariable\\s*\\(")) =) 10 | \end 11 | 12 | \define countVarGets() 13 | (= count(regexextract({{!!text}}, ".\\s*getVariable\\s*\\(")) =) 14 | \end 15 | 16 | \define specialVarRegex() 17 | ((current|story)Tiddler|namespace|transclusion|tv-[-a-zA-Z_]+) 18 | \end 19 | 20 | \define countSpecialsRegex(getOrSet) 21 | .\\s*$(getOrSet)$Variable\\s*\\(\\s*[\\\'\\\"]$(specialVarRegex)$ 22 | \end 23 | 24 | \define countSpecialGets() 25 | (= count(regexextract({{!!text}}, ".\\s*getVariable\\s*\\(\\s*[\\\'\\\"]$(specialVarRegex)$")) =) 26 | \end 27 | 28 | \define countSpecialSets() 29 | (= count(regexextract({{!!text}}, ".\\s*setVariable\\s*\\(\\s*[\\\'\\\"]$(specialVarRegex)$")) =) 30 | \end 31 | 32 | \define widgetShortName(title) 33 | (= mid(regexextract1("$title$", "/[a-zA-Z0-9_-]+(?=\\.)", "uunknown"), 2, 999) =) 34 | \end 35 | 36 | Locate calls to getVariable and setVariable in all widget implementations. 37 | 38 | Each count is displayed as X/Y where X is the number of operations on these special variables: 39 | 40 | * `currentTiddler` 41 | * `storyTiddler` 42 | * `namespace` 43 | * `transclusion` 44 | * `tv-` prefixed variables 45 | 46 | ;Search Term 47 | :<$radio field="searchterm" value="(g|s)etVariable"> Get+Set 48 | :<$radio field="searchterm" value="getVariable"> Get 49 | :<$radio field="searchterm" value="setVariable"> Set 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | <$list filter="[all[shadows]module-type[widget]regexp:text{!!searchterm}]"> 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 80 | 81 | 82 |
WidgetgetVariablesetVariable
<$link><$macrocall $name=widgetShortName title={{!!title}}/><>/<><>/<>
66 | <$details summary="View Call Tree"> 67 | <$comment "Mine out functions with the calls we're interested in" /> 68 | 69 |

70 | <$text text=(=
71 |   textjoin("", true, regexextract(
72 |     textjoin("", true, regexextract({{!!text}},
73 |       "([^\\n]*prototype\\s*\\.[^\\n]+\\n|[^\\n]*[gs]etVariable[^\\n]*\\n)")),
74 |     "[^\\n]*prototype\\s*\\.[^\\n]+\\n([\\t ][^\\n]*\\n)+"))
75 | =)/>
76 | 
77 | 78 | 79 |
83 | 84 | Method implementation 85 | 86 | [[Widget Call Trees]] -------------------------------------------------------------------------------- /tiddlers/wiki/range Operator.tid: -------------------------------------------------------------------------------- 1 | created: 20171221184734665 2 | modified: 20200429022121272 3 | tags: [[Filter Operators]] [[Negatable Operators]] 4 | title: range Operator 5 | type: text/vnd.tiddlywiki 6 | 7 | The `range Operator` in this plugin has been removed in preference to the one in the TW core. 8 | 9 | See: https://tiddlywiki.com/#range%20Operator -------------------------------------------------------------------------------- /tiddlers/wiki/uplus Function.tid: -------------------------------------------------------------------------------- 1 | categories: operators 2 | created: 20171228051051545 3 | list: 4 | modified: 20180114193336620 5 | names: uplus 6 | params: (a) 7 | params-short: (a) 8 | return-type: * 9 | summary: Result is `a`.
Equivalent to `+a`. 10 | tags: BuiltInFunction 11 | title: uplus Function 12 | type: text/vnd.tiddlywiki 13 | 14 | -------------------------------------------------------------------------------- /tiddlywiki.info: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Basic client-server edition", 3 | "plugins": [ 4 | "tiddlywiki/filesystem", 5 | "tiddlywiki/tiddlyweb" 6 | ], 7 | "themes": [ 8 | "tiddlywiki/vanilla", 9 | "tiddlywiki/snowwhite" 10 | ], 11 | "build": { 12 | "index": [ 13 | "--rendertiddler", 14 | "$:/plugins/tiddlywiki/tiddlyweb/save/offline", 15 | "index.html", 16 | "text/plain" 17 | ], 18 | "externalimages": [ 19 | "--savetiddlers", 20 | "[is[image]]", 21 | "images", 22 | "--setfield", 23 | "[is[image]]", 24 | "_canonical_uri", 25 | "$:/core/templates/canonical-uri-external-image", 26 | "text/plain", 27 | "--setfield", 28 | "[is[image]]", 29 | "text", 30 | "", 31 | "text/plain", 32 | "--rendertiddler", 33 | "$:/plugins/tiddlywiki/tiddlyweb/save/offline", 34 | "externalimages.html", 35 | "text/plain" 36 | ], 37 | "static": [ 38 | "--rendertiddler", 39 | "$:/core/templates/static.template.html", 40 | "static.html", 41 | "text/plain", 42 | "--rendertiddler", 43 | "$:/core/templates/alltiddlers.template.html", 44 | "alltiddlers.html", 45 | "text/plain", 46 | "--rendertiddlers", 47 | "[!is[system]]", 48 | "$:/core/templates/static.tiddler.html", 49 | "static", 50 | "text/plain", 51 | "--rendertiddler", 52 | "$:/core/templates/static.template.css", 53 | "static/static.css", 54 | "text/plain" 55 | ] 56 | } 57 | } -------------------------------------------------------------------------------- /versions/formulas-tiddlywiki-5.1.20.html.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBalster/TiddlyWikiFormula/8bece912976dcafe0ad4d8a55c9422d351f963ae/versions/formulas-tiddlywiki-5.1.20.html.zip -------------------------------------------------------------------------------- /versions/formulas-tiddlywiki-5.1.22.html.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBalster/TiddlyWikiFormula/8bece912976dcafe0ad4d8a55c9422d351f963ae/versions/formulas-tiddlywiki-5.1.22.html.zip -------------------------------------------------------------------------------- /versions/formulas-tiddlywiki-5.1.23.html.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBalster/TiddlyWikiFormula/8bece912976dcafe0ad4d8a55c9422d351f963ae/versions/formulas-tiddlywiki-5.1.23.html.zip --------------------------------------------------------------------------------