Hello Albert,
I've stubled upon an issue -- when AutoSuggestPlugin is included (eval'ed
without importing) via SharedTiddlersPlugin [1], the styles are not applied
-- and made a quick fix for it: added the
refreshStyles("StyleSheetAutoSuggest");
line before the
store.addNotification("StyleSheetAutoSuggest", refreshStyles);
line, which seems to be worth including in the main plugin.
Also, in my tweaked version, I've substituted the "chars" with the
[^\\|\\n\\]] thing, but didn't get what ([^\\x00-\\xff]*) stands for, so
could you point what's the purpose of this piece (so that I can turn it
into some more readable RegExp?
For the reference, I attach my tweaked snapshot of the plugin.
Best regards,
Yakov.
[1] http://yakovl.bplaced.net/TW/STP/STP.html
среда, 16 апреля 2014 г., 0:47:59 UTC+4 пользователь Albert Riedinger
написал:
>
> Today I worked out a temporary solution for pretty links, so it is
> possible now to type "[[SOME_LABEL|" which gives you tiddler title
> suggestions.
> It was a tough nut to crack for a regex newbie like me, but it works :)
>
> Try it out and have fun[1]!
> Albert
>
> [1] http://autosuggest.tiddlyspace.com/#AutoSuggestPlugin
>
--
You received this message because you are subscribed to the Google Groups
"TiddlyWiki" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/tiddlywiki.
For more options, visit https://groups.google.com/d/optout.
/***
|''Name''|AutoSuggestPlugin|
|''Source''|http://autosuggest.tiddlyspace.com/#AutoSuggestPlugin|
|''Version''|0.2.6 Alpha (2014-04-16), tweak 2.0 by YL|
|''Author''|Albert Riedinger|
|''License''|[[Creative Commons BY-SA
3.0|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion''|2.x|
|''Type''|plugin|
|''Requires''|[[jQuery.Caret.min.js]], [[jQuery.AtWho.min.js]]|
|''Optional''|[[jQuery.asuggest.min.js]] with [[jQuery.a-tools.min.js]]|
|''Stylesheet''|[[StyleSheetAutoSuggest]] (shadow)|
|''Documentation''|[[AutoSuggestPluginInfo]]|
|''Description''|provides automatic suggestions for all kind of TW data in edit
mode|
!Usage
* insert {{{autoSuggest}}} in [[ToolbarCommands]] (EditToolbar Slice)
* activate auto suggestion in edit mode
* type in tiddler text field ...
** {{{[[}}} > for tiddler name suggestions
*** {{{[[}}}LABEL{{{|}}} for pretty links
** {{{[[##}}} > for section name suggestions of current tiddler (inserts tiddly
link to chosen section)
** {{{[[::}}} > for slice name suggestions of current tiddler
** {{{[[??}}} > for field name suggestions of current tiddler (inserts wikified
content of chosen field with {{{view}}} macro)
** {{{##}}} > for tag suggestions
** {{{<<}}} > for macro name suggestions
* type in tag input field
** {{{[[}}} > for tiddler name suggestions
** {{{##}}} > for tag suggestions
* if word completion is activated in options, you get inline "office-like" word
completion in tiddler text field (experimental) ...
** press {{{TAB}}} to cycle through suggestions
** press {{{RETURN}}} to accept suggestion
!History
* 0.2.0 > initial working release
* 0.2.1 > option for inserting whitespace after suggestion
* 0.2.2 > {{{##}}} > tag suggestion in tag input field (inserts tiddly link:
{{{[[TAG]]}}})
* 0.2.3
** {{{EXPERIMENTAL}}} implemented word completion with
[[jQuery.asuggest.min.js]] > if activated in options, it provides inline
"office-like" word completion for tiddler names
*** press {{{TAB}}} to cycle through suggestions
*** press {{{RETURN}}} to accept suggestion
*** in a future release it will suggest more: user defined dictionary (tiddler
with word list), (cached) word list from current tiddler etc.
* 0.2.4
** updated [[jQuery.AtWho.min.js]] and [[jQuery.Caret.min.js]]
** {{{[[##}}} > section name suggestions for current tiddler (inserts tiddly
link: {{{[[SECTION_NAME|CURRENT_TIDDLER##SECTION_NAME]]}}})
** {{{[[::}}} > slice name suggestions for current tiddler (inserts slice
link?: {{{[[CURRENT_TIDDLER::SLICE_NAME]]}}})
** {{{[[??}}} > field name suggestions for current tiddler (inserts wikified
field value: {{{<<view FIELD_NAME wikified>>}}})
** preliminary support for diacritic characters (like äöüßáàéè etc.)
* 0.2.5
** {{{[[}}}LABEL{{{|}}} > added support for pretty links
* 0.2.6
** fixed minor regex bug in pretty links matcher
!Options
| Value | Description |h
|>| GENERAL |h
|auto suggest scope (global/local): <<option chkAutoSuggestGlobal>> |if
''checked'' (true) > auto suggestion state will be saved for all tiddlers in a
cookie (see option below)<br>if ''not checked'' (false) > auto suggestion state
will be saved on a per-tiddler-basis in the custom field {{{autosuggest}}}
(''NOT IMPLEMENTED YET'')|
|auto suggest global: <<option chkAutoSuggestGlobalState>> |if ''checked'' auto
suggestion will be activated for all tiddlers (if auto sugesst scope is set to
local, this option will be deactivated)|
|button label<br>(autosuggest activated): <<option txtAutoSuggestBtnAlt>> ||
|button label<br>(autosuggest deactivated): <<option txtAutoSuggestBtn>> ||
|suggestion limit: <<option txtAutoSuggestListLimit>> |limits number of
suggestions in popup list|
|insert whitespace after suggestion: <<option chkAutoSuggestInsertWhitespace>>
|if ''checked'' > whitespace will be inserted after suggestion|
|>| TIDDLERS |h
| ... | ... |
|>| SECTIONS |h
| ... | ... |
|>| SLICES |h
| ... | ... |
|>| FIELDS |h
| ... | ... |
|>| TAGS |h
| ... | ... |
|>| MACROS |h
| ... | ... |
|>| ''{{{EXPERIMENTAL}}}'' |h
|>| WORD COMPLETION |h
|activate word completion: <<option chkAutoSuggestWordComplete>>||
!Code
***/
//{{{
version.extensions.AutoSuggestPlugin = { major: 0, minor: 2, revision: 6, date:
new Date(2014, 04, 16) };
(function($){
// ---------- Options ----------
if (config.options.chkAutoSuggestGlobal === undefined)
config.options.chkAutoSuggestGlobal = true;
if (config.options.chkAutoSuggestGlobalState === undefined)
config.options.chkAutoSuggestGlobalState = false;
if (config.options.txtAutoSuggestBtn === undefined)
config.options.txtAutoSuggestBtn = "autosuggest off";
if (config.options.txtAutoSuggestBtnAlt === undefined)
config.options.txtAutoSuggestBtnAlt = "autosuggest on";
// !!!BUG funktioniert noch nicht
if (config.options.txtAutoSuggestListLimit === undefined)
config.options.txtAutoSuggestListLimit = 8;
if (config.options.chkAutoSuggestInsertWhitespace === undefined)
config.options.chkAutoSuggestInsertWhitespace = false;
if (config.options.chkAutoSuggestWordComplete === undefined)
config.options.chkAutoSuggestWordComplete = false;
config.commands.autoSuggest = {
text: config.options.txtAutoSuggestBtn,
text_alt: config.options.txtAutoSuggestBtnAlt,
tooltip: "activate automatic word suggestion for edit fields",
tooltip_alt: "deactivate automatic word suggestion for edit fields",
suggLimit: config.options.txtAutoSuggestListLimit,
hideReadOnly: true,
handler: function(event, src, title) {
var here = story.findContainingTiddler(src); if (!here) return;
var hereTid = here.id.substr(7);
var txt = {
areas: here.getElementsByTagName("textarea"),
inputs: here.querySelectorAll("input[type=text]") //
does not work with IE > 8
};
var asGlobal = config.options.chkAutoSuggestGlobal;
var asGlobalState = config.options.chkAutoSuggestGlobalState;
if (!txt.areas && !txt.inputs) return;
if (!asGlobalState) {
this.on(txt, src, hereTid);
} else {
this.off(txt, src);
}
return false;
},
on: function(txt, btn, hereTid) {
// get all textareas with edit attribute (txt.areas)
for (i=0; i<txt.areas.length; i++) {
if (txt.areas[i].getAttribute("edit") === undefined)
continue;
// type of field (txt.areas.field)
txt.areas[i].field = txt.areas[i].getAttribute("edit");
//console.log("txt.areas[i]: " + txt.areas + " / field:
"+txt.areas[i].field);
}
// get all input fields with edit attribute (txt.inputs)
for (i=0; i<txt.inputs.length; i++) {
if (txt.inputs[i].getAttribute("edit") === undefined)
continue;
// type of field (txt.inputs.field)
txt.inputs[i].field =
txt.inputs[i].getAttribute("edit");
//console.log("txt.inputs[i]: " + txt.inputs + " /
field: "+txt.inputs[i].field);
}
var t = store.getTiddlers();
// get all tiddler names (tidList)
var tids = [];
for (var i=0; i<t.length; i++) { tids.push(t[i].title); }
var tidList = jQuery.map(tids, function(val) {
return { "name":val };
});
// get sections (sectionList)
// * for current tiddler only (sections for specific
tiddlers is coming in a future release)
var sections = [];
var tidText = store.getTiddlerText(hereTid, "");
var regExpSec = /(?:^|\n)!{1,6}([^\n]*)\n/gm;
do { var s = regExpSec.exec(tidText); if (s) {
sections.push(s[1]); } } while(s);
var sectionList = jQuery.map(sections, function(val) {
return { "tid":hereTid, "name":val };
});
// get slices (sliceList)
// * for current tiddler only (slices for specific
tiddlers is coming in a future release)
var slices = store.calcAllSlices(hereTid);
var sliceList = jQuery.map(slices, function(val, key) {
return { "tid":hereTid, "name":key, "slice":val };
});
// get fields (fieldList)
// * for current tiddler only (fields for specific
tiddlers is coming in a future release)
var fields = {}
var hereTidObj = store.fetchTiddler(hereTid);
store.forEachField(
hereTidObj,
function(hereTidObj, f, v){ fields[f] = v; },
true
);
var fieldList = jQuery.map(fields, function(val, key) {
return { "name":key, "value":val };
});
// get all tags (tagList)
var tags = store.getTags();
var tagList = jQuery.map(tags, function(val) {
return { "name":val[0], "count":val[1] };
});
// get all TiddlyWiki macros (macroList)
var macroList = Object.keys(config.macros);
var tplTidLink = "<li data-value='${name}]]'>${name}</li>";
var tplSectionLink = "<li
data-value='[[${name}|${tid}##${name}]]'>${name}</li>";
var tplSlice = "<li
data-value='[[${tid}::${name}]]'>${name}<br><small>${slice}</small></li>";
var tplField = "<li data-value='<<view ${name}
wikified>>'>${name}<br><small>${value}</small></li>";
var tplTagLink = "<li data-value='[[${name}]]'>${name} <small
style='float:right;padding-left:2rem'>${count}</small></li>";
// callbacks for AtWho listeners
// default callbacks
var cbAll = {
before_insert: function(value, $li) {
if
(config.options.chkAutoSuggestInsertWhitespace) value = value + " ";
return value;
}
};
// custom callbacks
// default matcher
var cbMatch = {
matcher: function(flag, subtext,
should_start_with_space) {
var match, regexp;
// YL question: why the flag is not defined (flag = "[[")
flag =
flag.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
if (should_start_with_space)
flag = "(?:^|\\s)" + flag;
/* YL tweak */ regexp = new
RegExp(flag+"([^\\|\\n\\]]*)$|"+flag+"([^\\x00-\\xff]*)$", "gi");
// YL question: what's the purpose of the second part and that \\x00-\\xff
thing?
match = regexp.exec(subtext);
if (match)
return match[2] || match[1];
else
return null;
}
};
// !EXPERIMENTAL! matcher for tiddly links AND pretty links
var cbMatchTidLink = {
matcher: function(flag, subtext,
should_start_with_space) {
var match, regexp;
// fixed flag
flag = "[[";
flag =
flag.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
if(should_start_with_space)
flag = "(?:^|\\s)" + flag;
/* YL tweak */ regexp = new RegExp(flag+ "([^\\|\\n\\]]*)$|"+
flag+"[^\\|\\n\\]]+\\|([^\\|\\n\\]]*)$", "gi");
match = regexp.exec(subtext);
if (match)
return match[2] || match[1];
else
return null;
}
};
// merge all callbacks
var cb = $.extend({}, cbMatch, cbAll);
var cbTidLink = $.extend({}, cbMatchTidLink, cbAll);
// !!! TODO:
// * specify fields (text, tags etc.)
$(txt.areas)
.atwho({ at: "", callbacks: cbTidLink, tpl: tplTidLink,
data: tidList, limit: this.suggLimit })
.atwho({ at: "[[##", callbacks: cb, tpl:
tplSectionLink, data: sectionList, limit: this.suggLimit })
.atwho({ at: "[[::", callbacks: cb, tpl: tplSlice,
data: sliceList, limit: this.suggLimit })
.atwho({ at: "[[??", callbacks: cb, tpl: tplField,
data: fieldList, limit: this.suggLimit })
.atwho({ at: "##", callbacks: cb, tpl: tplTagLink,
data: tagList, limit: this.suggLimit })
.atwho({ at: "<<", callbacks: cb, data: macroList,
limit: this.suggLimit });
$(txt.inputs)
.atwho({ at: "[[", callbacks: cb, tpl: tplTidLink,
data: tidList, limit: this.suggLimit })
.atwho({ at: "##", callbacks: cb, tpl: tplTagLink,
data: tagList, limit: this.suggLimit });
// activating word completion
// TODO:
// * check if autosuggest is installed
if (config.options.chkAutoSuggestWordComplete) {
$(txt.areas).asuggest(tids, {
"minChunkSize": 1,
"stopSuggestionKeys": [$.asuggestKeys.RETURN]
});
}
// log AtWho matches for debugging
//$(txt.areas).on("matched.atwho", function(event, flag, query)
{
// console.log(event, "matched: " + flag + " / result: " +
query);
//});
$(btn).html(this.text_alt);
$(btn).attr("title", this.tooltip_alt);
config.options.chkAutoSuggestGlobalState = true;
},
off: function(txt, btn) {
$(txt.areas).atwho("destroy");
$(txt.inputs).atwho("destroy");
$(btn).html(this.text);
$(btn).attr("title", this.tooltip_alt);
config.options.chkAutoSuggestGlobalState = false;
}
};
//}}}
/***
!!Hijacking config.commands.editTiddler.handler
***/
//{{{
config.commands.editTiddler.handler_AUTOSUGGEST =
config.commands.editTiddler.handler;
config.commands.editTiddler.handler = function(event, src, title) {
var asHere = story.findContainingTiddler(src);
var asHereTid = asHere.id.substr(7);
// invoke original editTiddler command
config.commands.editTiddler.handler_AUTOSUGGEST.apply(this, arguments);
var asGlobalState = config.options.chkAutoSuggestGlobalState;
var txt = {
areas: asHere.getElementsByTagName("textarea"),
inputs: asHere.querySelectorAll("input[type=text]") // does not
work with IE > 8
};
if (!txt.areas && !txt.inputs) return;
// find autoSuggest command button
var btn = $(story.getTiddler(title)).find(".command_autoSuggest");
if (asGlobalState === true) config.commands.autoSuggest.on(txt, btn,
asHereTid);
};
//}}}
/***
!!Shadow Tiddler for Styles
***/
//{{{
config.shadowTiddlers.StyleSheetAutoSuggest =
"/*{{{*/\n" +
".atwho-view
{\n\tposition:absolute;\n\ttop:0;\n\tleft:0;\n\tdisplay:none;\n\tmargin-top:18px;\n\tbackground:white;\n\tborder:1px
solid #DDD;\n\tborder-radius:3px;\n\tbox-shadow:0 0 5px
rgba(0,0,0,0.1);\n\tmin-width:120px;\n\tz-index:10;\n}\n" +
".atwho-view .cur {\n\tbackground:#3366FF;\n\tcolor:white;\n}\n" +
".atwho-view .cur small {\n\tcolor:white;\n}\n" +
".atwho-view strong {\n\tcolor:#3366FF;\n}\n" +
".atwho-view .cur strong {\n\tcolor:white;\n\tfont:bold;\n}\n" +
".atwho-view ul {\n\t/* width:100px;
*/\n\tlist-style:none;\n\tpadding:0;\n\tmargin:auto;\n}\n" +
".atwho-view ul li {\n\tdisplay:block;\n\tpadding:5px
10px;\n\tborder-bottom:1px solid #DDD;\n\tcursor:pointer;\n\t/* border-top:1px
solid #C8C8C8; */\n}\n" +
".atwho-view small
{\n\tfont-size:smaller;\n\tcolor:#777;\n\tfont-weight:normal;\n}\n" +
"/*}}}*/";
/* YL tweak */ // refresh at once: otherwise the styles are not applied when
shared via SharedTiddlersPlugin
refreshStyles("StyleSheetAutoSuggest");
store.addNotification("StyleSheetAutoSuggest", refreshStyles);
})(jQuery);
//}}}