- // ==UserScript==
- // @name Sanskrit Tools - Toolbar
- // @namespace stgeorge
- // @description Sanskrit Language Tools - Quick access to Sanskrit dictionary, thesarus, news and other tools, on Firefox and Chrome browsers.
- // @require http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
- // @grant GM_setValue
- // @grant GM_getValue
- // @grant GM_getResourceText
- // @version 2.5
- // @resource lookup http://sanskrit.inria.fr/DICO/grammar.fr.html
- // ==/UserScript==
-
- (function() {
-
- // ===============================================================
- // Grammar stuff.
- // ===============================================================
-
- var SANSKRIT_SITE = 'spokensanskrit.de';
-
- // Options.
- // Set to the level number. 0 -> no logging; higher numbers -> more
- // verbose.
- var OPTION_DEBUG_LEVEL = 0;
-
- // Set to true true to change word completion list
- // to show up below the input field instead of on the side.
- var OPTION_IN_PLACE_MATCH = true;
-
- // Set to true if we want to assume verbs with no family
- // number to be family 1.
- // NOTE: Use this with caution. Often results in errors.
- var OPTION_DEF_GANA_1 = false;
-
- // Set to true to enable Amarakosha lookup.
- var OPT_AMARAKOSHA = false;
-
- // Set to true if we want to use split panes.
- var OPT_SPLIT_PANE = false;
-
- var verbMatch = /(verb)\s*(.*)/;
- var verbRootMatch = /{\s*(.*)\s*}/;
- var verbClassMatch = /\s*([0-9]+)\s*/g;
- var nounMatch = /\b([fmn](?=\.))/g;
- var nounRootMatch = /^\s*(.*)\s*$/;
- var vurl = 'http://sanskrit.inria.fr/cgi-bin/SKT/sktconjug?lex=SH%V%&q=%Q%&t=KH&c=%C%&font=deva';
- var nurl = 'http://sanskrit.inria.fr/cgi-bin/SKT/sktdeclin?lex=SH%V%&q=%Q%&t=KH&g=%G%&font=deva';
- var surl = 'http://sanskrit.uohyd.ernet.in/cgi-bin/scl/SHMT/generate.cgi?dic=amara&word=%Q%';
- var genders = { f: 'Fem', n: 'Neu', m: 'Mas' };
- var gender_names = { f: 'feminine', n: 'neuter', m: 'masculine' };
-
- var initDone = false;
- var paneSplit = false;
- var paneHeight;
-
- function isGrammarSupported() {
- if (document.URL.indexOf(SANSKRIT_SITE) == -1)
- return false;
- if (!initDone) {
- doc = $(GM_getResourceText('lookup'));
- v = $(GM_getResourceText('lookup')).find('[name="v"]:first').val();
- if (v) {
- v = '&v='+v;
- } else {
- v = '';
- }
- vurl = vurl.replace('%V%', v);
- nurl = nurl.replace('%V%', v);
- _debug(1, 'grammar code=' + v);
- _debug(1, 'vurl=' + vurl);
- _debug(1, 'nurl=' + nurl);
- initDone = true;
- }
- return true;
- }
-
- function initGrammarData() {
- }
-
- function buildGrammarUI() {
- fixSuggestBox();
- splitPane();
- setHandlers();
- }
-
- function fixSuggestBox() {
- if (OPTION_IN_PLACE_MATCH) {
- var ans = $('#answer');
- ans.bind('DOMSubtreeModified', function() {
- ans.children().first().attr('align', 'center');
- });
- ans.appendTo($('#tinput').parent());
- }
- }
-
- function splitPane() {
- if (!OPT_SPLIT_PANE)
- return;
- if (paneSplit) return;
- var body = $('body');
- var t = body.children('table').first();
- paneHeight = t.outerHeight(true);
- var t = t.detach();
- $('<div id="lp"></div><div id="rp"></div>').prependTo(body);
- $('#lp,#rp').css({
- 'float': 'left',
- overflow: 'auto',
- height: paneHeight + 'px',
- });
- $('#lp').css({
- width: '45%',
- });
- $('#rp').css({
- marginLeft: '10px',
- width: '54%',
- });
- t.appendTo($('#lp'));
- paneSplit = true;
- }
-
- function setHandlers() {
- $('tr.bgcol2,tr.bgcol7,tr.highlight').each(function() {
- var tr = $(this);
- var ltd = tr.children().first();
- // Each line is of the form:
- // sans_text translit_text grammar_info meaning
- var sans = ltd.next();
- var xlit = sans.next();
- var grmr = xlit.next();
- var links = [];
- // grammar, in turn, can be of the forms:
- // m./f./n./adj. etc (for nouns)
- // verb N (for verbs)
- var a = grmr.text().match(verbMatch);
- var prefix = sans.text() + ';' + xlit.text() + ';' + grmr.text() + ': ';
- if (a && a[1] == 'verb') {
- // For verbs, xlit is of the form xlit_word (xlit_root).
- // We want the root.
- var b = xlit.text().match(verbRootMatch);
- if (!b || !b[1]) return true;
- b[1] = b[1].trim();
- if (b[1].match(/[^A-Za-z]/))
- return true;
- var n;
- // For verbs, see if grammar_info has the gaNA info.
- if (a[2])
- n = a[2].trim().match(verbClassMatch);
- if (!(n && n[0])) {
- // Use a default gaNa if opted.
- if (OPTION_DEF_GANA_1)
- n = ['1'];
- else
- return true;
- }
- var s = sans.text().match(verbRootMatch);
- // At this point, b[1] is the transliterated verb root,
- // s[1] is the devangari verb root, and n the gaNa.
- _debug(2, prefix);
- _debug(2, 'verb');
- _debug(2, b[1]);
- _debug(2, n);
- for (var i = 0; i < n.length; ++i) {
- links.push({
- tooltip: 'Inflections for ' + a[1] + '(' + n[i] + ') ' + s[1],
- url: vurl.replace('%Q%', b[1]).replace('%C%', n[i].trim()),
- sym: '▸',
- target: 'l_grammar',
- });
- }
- } else {
- a = grmr.text().match(nounMatch);
- if (!(a && a[0]))
- return true;
- var b = xlit.text().match(nounRootMatch);
- if (!b || !b[1]) return true;
- b[1] = b[1].trim();
- if (b[1].match(/[^A-Za-z]/))
- return true;
- s = sans.text().match(nounRootMatch);
- // At this point, b[1] is the xlit noun, s[1] is the
- // devanagari noun, and a is one or more lingas.
- _debug(2, prefix);
- _debug(2, 'noun=');
- _debug(2, b[1]);
- _debug(2, a);
- if (a.length > 0) {
- if (OPT_AMARAKOSHA) {
- links.push({
- url: surl.replace('%Q%', sans.text()),
- tooltip: 'Synonyms for ' + b[1] + '. (The thesarus may not have synonyms for all words.)',
- sym: '∗',
- target: 'l_thes',
- });
- }
- for (var i = 0; i < a.length; ++i) {
- links.push({
- url: nurl.replace('%Q%', b[1]).replace('%G%', genders[a[i]]),
- tooltip: 'Inflections for ' + ' noun ' + s[1],
- sym: '▸',
- target: 'l_grammar',
- });
- }
- }
- }
- var html;
- if (links[0]) {
- html = '';
- for (var i in links) {
- l = links[i];
- ltd.attr('valign','top');
- html +=
- '<a data-id="' +i+
- '" class="def stil4" style="#96290e;font-weight:bold;font-size:x-large;" href="' +
- l.url + '" title="' + l.tooltip + '">'+l.sym+'</a>';
- }
- ltd.html(html);
- ltd.attr('align', 'left');
- if (OPT_SPLIT_PANE) {
- ltd.children('a').each(function(k,v) {
- $(this).on('click', function(e) {
- e.preventDefault();
- var url = $(this).attr('href');
- $('#rp').html('<iframe width="100%" border="none" frameborder="0" height="'+paneHeight+'px" src="' + url + '"></iframe>');
- });
- });
- }
- }
- return true;
- });
- }
-
- // ===============================================================
- // Toolbar stuff.
- // ===============================================================
-
- var IGNORES = [
- 'mail.yahoo.com',
- 'groups.yahoo.com',
- 'spokensanskrit.de',
- ];
- var ALLOW_ANCHORS = [
- 'sanskrit.uohyd.ernet.in/cgi-bin/scl/SHMT/generate.cgi',
- ];
- var TOOLBAR_HTML = '\
- <div id="s_toolbar">\
- <div style="float:left; display:inline-block">\
- <ul style="list-style:none;margin:0;padding:0">\
- <li class="st_li">\
- <a title="Doordarshan Sanskrit News/Magazine" class="st_common st_link" href="http://www.youtube.com/user/sanskritanews/videos" target="l_news">\
- वार्ताः</a>\
- </li>\
- <li class="st_li">\
- <a title="\'Sambhaashana Sandesha\' Magazine" class="st_common st_link" href="http://www.sambhashanasandesha.in/" target="l_mag1">सम्भाषण सन्देशः</a>\
- </li>\
- <li class="st_li">\
- <a title="\'Vishva Vani\' Magazine" class="st_common st_link" href="http://www.speaksanskrit.org/vishvavani.shtml" target="l_mag2">विश्ववाणी</a>\
- </li>\
- <li class="st_li">\
- <a title="Books" class="st_common st_link" href="http://www.sanskrit.nic.in/ebook.htm" target="l_books">पुस्तकानि</a>\
- </li>\
- <li class="st_li">\
- <a title="Wikipedia" class="st_common st_link" href="http://sa.wikipedia.org" target="l_wiki">\
- विकिपीडिया</a>\
- </li>\
- <li class="st_li">\
- <a id="l_word" title="Show a random verb" class="st_common st_link" target="l_word">\यदृच्छिकपदम्</a>\
- </li>\
- <li class="st_li st_space">\
- </li>\
- <li class="st_li">\
- <a title="Maheshwara Sutras" class="st_common st_link" href="http://en.wikipedia.org/wiki/Siva_Sutra#Text" target="l_msutra">\
- माहेश्वरसूत्राणि</a>\
- </li>\
- <li class="st_li">\
- <a title="Noun/Verb Expansion" class="st_common st_link" href="http://sanskrit.inria.fr/DICO/grammar.fr.html" target="l_inria">\
- शभ्द, धातुरूपावली</a>\
- </li>\
- <li class="st_li">\
- <a title="Sandhi splitter" class="st_common st_link" href="http://tdil-dc.in/san/sandhi_splitter/index_dit.html" target="l_sandhi">\
- सन्धिः</a>\
- </li>\
- <li class="st_li st_space">\
- </li>\
- <li class="st_li">\
- <div title="Double-clicking a word will automatically launch the dictionary" class="st_common st_option">\
- <input type="checkbox" id="o_auto" class="st_common st_checkbox" title="Double-clicking a word will automatically launch the dictionary"/>\
- <label for="o_auto" class="st_label">Auto-dictionary</label>\
- </div>\
- </li>\
- <li class="st_li st_space">\
- </li>\
- </ul>\
- </div>\
- </div>\
- <a id="a_dict" style="display:none" href="" target="l_dict"></a>\
- </div>';
- var ICON_HTML = '\
- <div id="icon" title="Click to show/hide Sanskrit Toolbar">\u0938\
- </div>';
- var VERBS = [
- 'accept','account','achieve','act','add','admit','affect','afford','agree','aim','allow','answer','appear','apply','argue','arrange','arrive','ask','attack','avoid','base','be','beat','become','begin','believe','belong','break','build','burn','buy','call','can','care','carry','catch','cause','change','charge','check','choose','claim','clean','clear','climb','close','collect','come','commit','compare','complain','complete','concern','confirm','connect','consider','consist','contact','contain','continue','contribute','control','cook','copy','correct','cost','count','cover','create','cross','cry','cut','damage','dance','deal','decide','deliver','demand','deny','depend','describe','design','destroy','develop','die','disappear','discover','discuss','divide','do','draw','dress','drink','drive','drop','eat','enable','encourage','end','enjoy','examine','exist','expect','experience','explain','express','extend','face','fail','fall','fasten','feed','feel','fight','fill','find','finish','fit','fly','fold','follow','force','forget','forgive','form','found','gain','get','give','go','grow','handle','happen','hate','have','head','hear','help','hide','hit','hold','hope','hurt','identify','imagine','improve','include','increase','indicate','influence','inform','intend','introduce','invite','involve','join','jump','keep','kick','kill','knock','know','last','laugh','lay','lead','learn','leave','lend','let','lie','like','limit','link','listen','live','look','lose','love','make','manage','mark','matter','mean','measure','meet','mention','mind','miss','move','need','notice','obtain','occur','offer','open','order','own','pass','pay','perform','pick','place','plan','play','point','prefer','prepare','present','press','prevent','produce','promise','protect','prove','provide','publish','pull','push','put','raise','reach','read','realize','receive','recognize','record','reduce','refer','reflect','refuse','regard','relate','release','remain','remember','remove','repeat','replace','reply','report','represent','require','rest','result','return','reveal','ring','rise','roll','run','save','say','see','seem','sell','send','separate','serve','set','settle','shake','share','shoot','shout','show','shut','sing','sit','sleep','smile','sort','sound','speak','stand','start','state','stay','stick','stop','study','succeed','suffer','suggest','suit','supply','support','suppose','survive','take','talk','teach','tell','tend','test','thank','think','throw','touch','train','travel','treat','try','turn','understand','use','visit','vote','wait','walk','want','warn','wash','watch','wear','win','wish','wonder','work','worry','write'
- ];
-
- var icon;
- var cbs = {
- l_word : function(id) {
- showDict(VERBS[Math.floor(Math.random() * VERBS.length)],
- '&direction=ES'
- );
- }
- };
- var visible = {};
- var numClicks = 0;
- var vdiv = null;
- var allowAnchor = false;
- var selectedText = null;
-
- function isToolbarSupported() {
- for (var i in IGNORES) {
- if (document.URL.indexOf(IGNORES[i]) != -1) {
- return false;
- }
- }
- return true;
- }
-
- function initToolbarData() {
- for (var i in ALLOW_ANCHORS) {
- if (document.URL.indexOf(ALLOW_ANCHORS[i]) != -1) {
- allowAnchor = true;
- break;
- }
- }
- }
-
- function buildToolbarUI() {
- place('s_toolbar', TOOLBAR_HTML, {
- position: 'fixed',
- 'top': 0,
- margin: 0,
- // minHeight: '30px',
- width: '100%',
- zIndex: 2999999999,
- paddingTop: '3px',
- paddingBottom: '3px',
- backgroundColor: 'white',
- borderBottom: '1px solid orange',
- float: 'left',
- display:'none'
- });
- for (var i in cbs) {
- (function(p) {
- $('#'+p).on('click', function(e) {
- e.preventDefault();
- e.stopPropagation();
- var cb = cbs[p];
- cb($(this).attr('id'));
- });
- })(i);
- }
- $('.st_li').css({
- background: 'none',
- border: 0,
- display:'inline',
- padding: 0,
- });
- $('.st_space').css({
- marginLeft:'20px',
- });
- $('.st_common').css({
- float: 'left',
- border: 0,
- margin: 0,
- padding: 0,
- // height: '30px',
- fontSize: '15px',
- verticalAlign:'middle',
- });
- $('.st_link').css({
- textDecoration: 'none',
- fontWeight: 'bolder',
- marginLeft:'5px',
- padding:'5px',
- cursor: 'pointer',
- backgroundColor: '#eeeeee',
- color: 'black',
- });
- $('.st_label').css({
- marginLeft: '5px',
- });
- $('.st_option').css({
- display: 'inline-block',
- margin: '5px'
- });
- $('.st_link').hover(function() {
- $(this).css({color:'orange'});
- }, function() {
- $(this).css({color:'black'});
- });
- $('.st_checkbox').css({
- margin: '5px'
- });
- $('.st_menutrigger').css({
- position: 'relative'
- });
- $('.st_menu').css({
- backgroundColor:'#eee',
- display:'none',
- listStyle: 'none',
- position:'absolute',
- width:'120px',
- // left:'50px',
- 'top': '50px',
- boxShadow: '5px 5px 5px #888888',
- zIndex:'999',
- });
- $('.st_menu li').css({
- width:'100px',
- listStyle: 'none inside',
- });
- place('icon', ICON_HTML, {
- cursor:'pointer',
- 'float':'right',
- padding: '0px 15px 18px',
- fontWeight:'bold',
- backgroundColor: 'transparent',
- color:'red',
- position:'fixed',
- right:0,
- bottom: 0,
- height:'10px',
- width:'10px',
- zIndex:9999
- });
- icon = $('#icon').get(0);
-
- $('#icon').on('click', function(e) {
- var tb = $('#s_toolbar');
- var v = tb.css('display');
- if (v == 'none') {
- tb.css({
- 'display':'block',
- });
- $('body').css('marginTop', '50px');
- GM_setValue('status', 1);
- } else {
- tb.css({
- 'display':'none',
- });
- $('body').css('marginTop', 0);
- GM_setValue('status', 0);
- }
- });
- $('#o_auto').on('change', function(e) {
- GM_setValue('auto', $(this).prop('checked'));
- });
- $('.st_menutrigger').on('click', function(e) {
- e.preventDefault();
- e.stopPropagation();
- var trigger = $(this);
- var tgt = trigger.attr('data-menu');
- var v = visible[tgt];
- if (v)
- $(tgt).css('display', 'none');
- else
- $(tgt).css('display', 'block');
- visible[tgt] = !v;
- });
- $(document).on('click', function(e) {
- $('.st_menu').css('display', 'none');
- for (var i in visible) {
- visible[i] = false;
- }
- });
- document.addEventListener('mouseup', function(e) {
- var node = (e.target || e.srcElement);
- if (e.button != 0 || (node.nodeName == 'A' && !allowAnchor)
- || node.nodeName == 'INPUT') {
- return;
- }
- var n = node;
- while (n) {
- if (n == icon) {
- return;
- }
- if (n.getAttribute) {
- var ce = n.getAttribute('contenteditable');
- if (ce) {
- return;
- }
- }
- n = n.parentNode;
- }
- if (++numClicks == 1) {
- window.setTimeout(function() {
- selectedText = getSelectedText(true);
- if (selectedText != null && selectedText.length > 0) {
- if (selectedText.indexOf(' ') != -1) {
- selectedText = null;
- return;
- }
- if ($('#o_auto').prop('checked')) {
- showDict(selectedText);
- }
- } else {
- hideDict();
- }
- numClicks = 0;
- }, 300);
- }
- }, false);
-
- if (GM_getValue('status', 0))
- show();
- }
-
- function place(id, html, css) {
- $('body').prepend(html);
- $('#'+id).css(css);
- }
-
- function getSelectedText(trim) {
- var text =
- (window.getSelection) ? window.getSelection().toString() :
- (document.getSelection) ? document.getSelection().toString() :
- (document.selection) ? document.selection.createRange().text : null;
- if (trim && text != null)
- text = text.trim();
- return text;
- }
-
- function showDict(text) {
- hideDict();
- var a = $('#a_dict');
- a.on('click', function(e) {
- a.attr('href',
- 'http://spokensanskrit.de/index.php?trans=Translate&tinput='+text);
- });
- a.get(0).click();
- }
-
- function hideDict() {
- if (vdiv) {
- vdiv.close();
- vdiv = null;
- }
- }
-
- // ===============================================================
- // General stuff.
- // ===============================================================
-
- function _debug(level, s) {
- if (level < OPTION_DEBUG_LEVEL)
- console.log(s);
- }
-
- function isMainWindow() {
- return (window.top == window.self);
- }
-
- // Main:
- if (!isMainWindow())
- return;
- if (isGrammarSupported()) {
- initGrammarData();
- buildGrammarUI();
- }
- if (isToolbarSupported()) {
- initToolbarData();
- buildToolbarUI();
- }
- })();