diff --git a/changes.txt b/changes.txt index eb16b64..9070001 100644 --- a/changes.txt +++ b/changes.txt @@ -1,5 +1,6 @@ JUSH 1.10.0-dev: Optionally display title with function summary and parameters +Link PHP methods Link SQLite PRAGMA Link PostgreSQL variables Ability to link custom words (e.g. function or table names) diff --git a/jush.js b/jush.js index 5fc685f..44ec4aa 100644 --- a/jush.js +++ b/jush.js @@ -34,6 +34,7 @@ var jush = { highlight: function (language, text) { this.last_tag = ''; + this.last_class = ''; return '' + this.highlight_states([ language ], text.replace(/\r\n?/g, '\n'), !/^(htm|tag|xml)$/.test(language))[0] + ''; }, @@ -65,6 +66,10 @@ var jush = { highlight(); }, + create_link: function (link, s, attrs) { + return '' + s + ''; + }, + keywords_links: function (state, s) { if (/^js(_write|_code)+$/.test(state)) { state = 'js'; @@ -81,7 +86,7 @@ var jush = { s = s.replace(links2, function (str) { for (var i=arguments.length - 4; i > 0; i--) { if (arguments[i]) { - var link = (/^http:/.test(url[i]) ? url[i] : url[0].replace(/\$key/g, url[i])); + var link = (/^http:/.test(url[i]) || !url[i] ? url[i] : url[0].replace(/\$key/g, url[i])); switch (state) { case 'php': link = link.replace(/\$1/g, arguments[i].toLowerCase()); break; case 'php_new': link = link.replace(/\$1/g, arguments[i].toLowerCase()); break; // toLowerCase() - case sensitive after # @@ -103,7 +108,7 @@ var jush = { if (jush.api[state]) { title = jush.api[state][(state == 'js' ? arguments[i] : arguments[i].toLowerCase())]; } - return '' + arguments[i] + '' + (arguments[arguments.length - 3] ? arguments[arguments.length - 3] : ''); + return jush.create_link(link, arguments[i], (title ? ' title="' + jush.htmlspecialchars_quo(title) + '"' : '')) + (arguments[arguments.length - 3] ? arguments[arguments.length - 3] : ''); } } }); @@ -114,7 +119,7 @@ var jush = { if (/<[^>]*$/.test(s.substr(0, offset))) { return str; // don't create links inside tags } - return '' + str + ''; + return jush.create_link(jush.custom_links[state][0].replace('$&', encodeURIComponent(str)), str, '" class="jush-custom"'); }); } return s; @@ -175,9 +180,9 @@ var jush = { js_one: { php: php, 1: /\n/, 3: /(<)(\/script)(>)/i }, js_reg: { php: php, esc: /\\/, 1: /\/[a-z]*/i }, //! highlight regexp - php: { php_quo: /"/, php_apo: /'/, php_bac: /`/, php_one: /\/\/|#/, php_doc: /\/\*\*/, php_com: /\/\*/, php_eot: /<<<[ \t]*/, php_new: /(\b)(new|instanceof|extends|class|implements|interface)(\b\s*)/i, php_fun: /()(\bfunction\b|->|::)(\s*)/i, php_php: new RegExp('(\\b)(' + this.php_function + ')(\\s*\\(|$)', 'i'), php_sql: new RegExp('(\\b)(' + this.sql_function + ')(\\s*\\(|$)', 'i'), php_sqlite: new RegExp('(\\b)(' + this.sqlite_function + ')(\\s*\\(|$)', 'i'), php_pgsql: new RegExp('(\\b)(' + this.pgsql_function + ')(\\s*\\(|$)', 'i'), php_mssql: new RegExp('(\\b)(' + this.mssql_function + ')(\\s*\\(|$)', 'i'), php_echo: /(\b)(echo|print)\b/i, php_halt: /(\b)(__halt_compiler)(\s*\(\s*\)|$)/i, php_var: /(\$)([\w\u007F-\uFFFF]+)()/, num: num, php_phpini: /(\b)(ini_get|ini_set)(\s*\(|$)/i, php_http: /(\b)(header)(\s*\(|$)/i, php_mail: /(\b)(mail)(\s*\(|$)/i, 1: /\?>|<\/script>/i }, //! matches ::echo - php_quo_var: { php_quo: /"/, php_apo: /'/, php_bac: /`/, php_one: /\/\/|#/, php_com: /\/\*/, php_eot: /<<<[ \t]*/, php_new: /(\b)(new|instanceof|extends|class|implements|interface)(\b\s*)/i, php_fun: /()(\bfunction\b|->|::)(\s*)/i, php_php: new RegExp('(\\b)(' + this.php_function + ')(\\s*\\(|$)', 'i'), php_sql: new RegExp('(\\b)(' + this.sql_function + ')(\\s*\\(|$)', 'i'), php_sqlite: new RegExp('(\\b)(' + this.sqlite_function + ')(\\s*\\(|$)', 'i'), php_pgsql: new RegExp('(\\b)(' + this.pgsql_function + ')(\\s*\\(|$)', 'i'), php_mssql: new RegExp('(\\b)(' + this.mssql_function + ')(\\s*\\(|$)', 'i'), 1: /}/ }, - php_echo: { php_quo: /"/, php_apo: /'/, php_bac: /`/, php_one: /\/\/|#/, php_com: /\/\*/, php_eot: /<<<[ \t]*/, php_new: /(\b)(new|instanceof|extends|class|implements|interface)(\b\s*)/i, php_fun: /()(\bfunction\b|->|::)(\s*)/i, php_php: new RegExp('(\\b)(' + this.php_function + ')(\\s*\\(|$)', 'i'), php_sql: new RegExp('(\\b)(' + this.sql_function + ')(\\s*\\(|$)', 'i'), php_sqlite: new RegExp('(\\b)(' + this.sqlite_function + ')(\\s*\\(|$)', 'i'), php_pgsql: new RegExp('(\\b)(' + this.pgsql_function + ')(\\s*\\(|$)', 'i'), php_mssql: new RegExp('(\\b)(' + this.mssql_function + ')(\\s*\\(|$)', 'i'), php_echo: /\(/, php_var: /(\$)([\w\u007F-\uFFFF]+)()/, num: num, php_phpini: /(\b)(ini_get|ini_set)(\s*\(|$)/i, 1: /\)|;/, 2: /\?>|<\/script>/i }, + php: { php_quo: /"/, php_apo: /'/, php_bac: /`/, php_one: /\/\/|#/, php_doc: /\/\*\*/, php_com: /\/\*/, php_eot: /<<<[ \t]*/, php_new: /(\b)(new|instanceof|extends|class|implements|interface)(\b\s*)/i, php_met: /()([\w\u007F-\uFFFF]+)(::)/, php_fun: /()(\bfunction\b|->|::)(\s*)/i, php_php: new RegExp('(\\b)(' + this.php_function + ')(\\s*\\(|$)', 'i'), php_sql: new RegExp('(\\b)(' + this.sql_function + ')(\\s*\\(|$)', 'i'), php_sqlite: new RegExp('(\\b)(' + this.sqlite_function + ')(\\s*\\(|$)', 'i'), php_pgsql: new RegExp('(\\b)(' + this.pgsql_function + ')(\\s*\\(|$)', 'i'), php_mssql: new RegExp('(\\b)(' + this.mssql_function + ')(\\s*\\(|$)', 'i'), php_echo: /(\b)(echo|print)\b/i, php_halt: /(\b)(__halt_compiler)(\s*\(\s*\)|$)/i, php_var: /(\$)([\w\u007F-\uFFFF]+)()/, num: num, php_phpini: /(\b)(ini_get|ini_set)(\s*\(|$)/i, php_http: /(\b)(header)(\s*\(|$)/i, php_mail: /(\b)(mail)(\s*\(|$)/i, 1: /\?>|<\/script>/i }, //! matches ::echo + php_quo_var: { php_quo: /"/, php_apo: /'/, php_bac: /`/, php_one: /\/\/|#/, php_com: /\/\*/, php_eot: /<<<[ \t]*/, php_new: /(\b)(new|instanceof|extends|class|implements|interface)(\b\s*)/i, php_met: /()([\w\u007F-\uFFFF]+)(::)/, php_fun: /()(\bfunction\b|->|::)(\s*)/i, php_php: new RegExp('(\\b)(' + this.php_function + ')(\\s*\\(|$)', 'i'), php_sql: new RegExp('(\\b)(' + this.sql_function + ')(\\s*\\(|$)', 'i'), php_sqlite: new RegExp('(\\b)(' + this.sqlite_function + ')(\\s*\\(|$)', 'i'), php_pgsql: new RegExp('(\\b)(' + this.pgsql_function + ')(\\s*\\(|$)', 'i'), php_mssql: new RegExp('(\\b)(' + this.mssql_function + ')(\\s*\\(|$)', 'i'), 1: /}/ }, + php_echo: { php_quo: /"/, php_apo: /'/, php_bac: /`/, php_one: /\/\/|#/, php_com: /\/\*/, php_eot: /<<<[ \t]*/, php_new: /(\b)(new|instanceof|extends|class|implements|interface)(\b\s*)/i, php_met: /()([\w\u007F-\uFFFF]+)(::)/, php_fun: /()(\bfunction\b|->|::)(\s*)/i, php_php: new RegExp('(\\b)(' + this.php_function + ')(\\s*\\(|$)', 'i'), php_sql: new RegExp('(\\b)(' + this.sql_function + ')(\\s*\\(|$)', 'i'), php_sqlite: new RegExp('(\\b)(' + this.sqlite_function + ')(\\s*\\(|$)', 'i'), php_pgsql: new RegExp('(\\b)(' + this.pgsql_function + ')(\\s*\\(|$)', 'i'), php_mssql: new RegExp('(\\b)(' + this.mssql_function + ')(\\s*\\(|$)', 'i'), php_echo: /\(/, php_var: /(\$)([\w\u007F-\uFFFF]+)()/, num: num, php_phpini: /(\b)(ini_get|ini_set)(\s*\(|$)/i, 1: /\)|;/, 2: /\?>|<\/script>/i }, php_php: { php_quo: /"/, php_apo: /'/, php_bac: /`/, php_one: /\/\/|#/, php_com: /\/\*/, php_eot: /<<<[ \t]*/, php_php: /\(/, php_var: /(\$)([\w\u007F-\uFFFF]+)()/, num: num, 1: /\)/ }, php_sql: { php_quo: /"/, php_apo: /'/, php_bac: /`/, php_one: /\/\/|#/, php_com: /\/\*/, php_eot: /<<<[ \t]*/, php_sql: /\(/, php_var: /(\$)([\w\u007F-\uFFFF]+)()/, num: num, 1: /\)/ }, php_sqlite: { php_quo: /"/, php_apo: /'/, php_bac: /`/, php_one: /\/\/|#/, php_com: /\/\*/, php_eot: /<<<[ \t]*/, php_sqlite: /\(/, php_var: /(\$)([\w\u007F-\uFFFF]+)()/, num: num, 1: /\)/ }, @@ -187,6 +192,7 @@ var jush = { php_http: { php_quo: /"/, php_apo: /'/, php_bac: /`/, php_one: /\/\/|#/, php_com: /\/\*/, php_eot: /<<<[ \t]*/, php_http: /\(/, php_var: /(\$)([\w\u007F-\uFFFF]+)()/, num: num, 1: /\)/ }, php_mail: { php_quo: /"/, php_apo: /'/, php_bac: /`/, php_one: /\/\/|#/, php_com: /\/\*/, php_eot: /<<<[ \t]*/, php_mail: /\(/, php_var: /(\$)([\w\u007F-\uFFFF]+)()/, num: num, 1: /\)/ }, php_new: { php_one: /\/\/|#/, php_com: /\/\*/, 0: /\s*,\s*/, 1: /(?=[^\w\u007F-\uFFFF])|$/ }, //! classes are used also for type hinting and catch + php_met: { php_one: /\/\/|#/, php_com: /\/\*/, 1: /()([\w\u007F-\uFFFF]+)()/ }, php_fun: { php_one: /\/\/|#/, php_com: /\/\*/, 1: /(?=[^\w\u007F-\uFFFF])|$/ }, php_one: { 1: /\n|(?=\?>)|$/ }, php_eot: { php_eot2: /([^'"\n]+)(['"]?)/ }, @@ -365,9 +371,12 @@ var jush = { } } } + if (key == 'php_met') { + this.last_class = (k_link && !/^(self|parent|static)$/.test(link) ? link : ''); + } if (k_link) { s = (m[1] ? '' + this.htmlspecialchars(escape ? escape(m[1]) : m[1]) + '' : ''); - s += '' + this.htmlspecialchars(escape ? escape(m[2]) : m[2]) + ''; + s += this.create_link((/^http:/.test(k_link) ? k_link : this.urls[key].replace(/\$key/, k_link)).replace(/\$val/, link), this.htmlspecialchars(escape ? escape(m[2]) : m[2])); s += (m[3] ? '' + this.htmlspecialchars(escape ? escape(m[3]) : m[3]) + '' : ''); } } @@ -381,6 +390,9 @@ var jush = { this.regexps.sql_eot2 = this.build_regexp(this.tr.sql_eot2); } } else { + if (state == 'php_met' && this.last_class) { + s = this.create_link(this.urls[state].replace(/\$key/, this.last_class) + '.' + s.toLowerCase(), s); + } ret.push(s); for (var i = Math.min(states.length, key); i--; ) { ret.push(''); @@ -468,6 +480,7 @@ jush.urls = { php_phpini: 'http://www.php.net/$key.$val', php_http: 'http://www.php.net/$key.$val', php_mail: 'http://www.php.net/$key.$val', + php_met: 'http://www.php.net/$key', php_halt: 'http://www.php.net/$key.halt-compiler', sql_sqlset: 'http://dev.mysql.com/doc/mysql/en/$key', sqlite_sqliteset: 'http://www.sqlite.org/$key', @@ -634,6 +647,12 @@ jush.links = { 'http://www.php.net/language.oop5.interfaces#language.oop5.interfaces.$val': /^(implements|interface)$/i, 'http://www.php.net/language.operators.type': /^instanceof$/i }, + php_met: { + 'language.oop5.paamayim-nekudotayim': /^(self|parent|static)$/i, + 'reserved.classes#reserved.classes.$val': /^Closure$/i, + 'ref.sqlite#sqlite.class.$val': /^(SQLiteDatabase|SQLiteResult|SQLiteUnbuffered)$/i, + 'class.$val': /^(ArrayAccess|ErrorException|Exception|Iterator|IteratorAggregate|Serializable|Traversable|Cairo|CairoAntialias|CairoContent|CairoContext|CairoException|CairoExtend|CairoFillRule|CairoFilter|CairoFontFace|CairoFontOptions|CairoFontSlant|CairoFontType|CairoFontWeight|CairoFormat|CairoGradientPattern|CairoHintMetrics|CairoHintStyle|CairoImageSurface|CairoLinearGradient|CairoLineCap|CairoLineJoin|CairoMatrix|CairoOperator|CairoPath|CairoPattern|CairoPatternType|CairoPdfSurface|CairoPsLevel|CairoPsSurface|CairoRadialGradient|CairoScaledFont|CairoSolidPattern|CairoStatus|CairoSubpixelOrder|CairoSurface|CairoSurfacePattern|CairoSurfaceType|CairoSvgSurface|CairoSvgVersion|CairoToyFontFace|DateInterval|DatePeriod|DateTime|DateTimeZone|DOMAttr|DOMCharacterData|DOMComment|DOMDocument|DOMDocumentFragment|DOMDocumentType|DOMElement|DOMEntity|DOMEntityReference|DOMException|DOMImplementation|DOMNamedNodeMap|DOMNode|DOMNodeList|DOMNotation|DOMProcessingInstruction|DOMText|DOMXPath|GearmanClient|GearmanException|GearmanJob|GearmanTask|GearmanWorker|Gmagick|GmagickDraw|GmagickException|GmagickPixel|GmagickPixelException|HaruAnnotation|HaruDestination|HaruDoc|HaruEncoder|HaruException|HaruFont|HaruImage|HaruOutline|HaruPage|HttpDeflateStream|HttpInflateStream|HttpMessage|HttpQueryString|HttpRequest|HttpRequestPool|HttpResponse|Imagick|ImagickDraw|ImagickPixel|ImagickPixelIterator|Collator|IntlDateFormatter|Locale|MessageFormatter|Normalizer|NumberFormatter|ResourceBundle|libXMLError|Memcached|MemcachedException|SWFAction|SWFBitmap|SWFButton|SWFDisplayItem|SWFFill|SWFFont|SWFFontChar|SWFGradient|SWFMorph|SWFMovie|SWFPrebuiltClip|SWFShape|SWFSound|SWFSoundInstance|SWFSprite|SWFText|SWFTextField|SWFVideoStream|Mongo|MongoBinData|MongoCode|MongoCollection|MongoConnectionException|MongoCursor|MongoCursorException|MongoCursorTimeoutException|MongoDate|MongoDB|MongoDBRef|MongoException|MongoGridFS|MongoGridFSCursor|MongoGridFSException|MongoGridFSFile|MongoId|MongoMaxKey|MongoMinKey|MongoRegex|MongoTimestamp|MySQLi|OAuth|OAuthException|PDO|PDOException|PDOStatement|Phar|PharData|PharException|PharFileInfo|RarArchive|RarEntry|RarException|Reflection|ReflectionClass|ReflectionException|ReflectionExtension|ReflectionFunction|ReflectionFunctionAbstract|ReflectionMethod|ReflectionObject|ReflectionParameter|ReflectionProperty|Reflector|SimpleXMLElement|SoapClient|SoapFault|SoapHeader|SoapParam|SoapServer|SoapVar|SolrClient|SolrClientException|SolrDocument|SolrDocumentField|SolrException|SolrGenericResponse|SolrIllegalArgumentException|SolrIllegalOperationException|SolrInputDocument|SolrModifiableParams|SolrObject|SolrParams|SolrPingResponse|SolrQuery|SolrQueryResponse|SolrResponse|SolrUpdateResponse|SolrUtils|SphinxClient|AppendIterator|ArrayIterator|ArrayObject|BadFunctionCallException|BadMethodCallException|CachingIterator|Countable|DirectoryIterator|DomainException|EmptyIterator|FilesystemIterator|FilterIterator|GlobIterator|InfiniteIterator|InvalidArgumentException|IteratorIterator|LengthException|LimitIterator|LogicException|MultipleIterator|NoRewindIterator|OuterIterator|OutOfBoundsException|OutOfRangeException|OverflowException|ParentIterator|RangeException|RecursiveArrayIterator|RecursiveCachingIterator|RecursiveDirectoryIterator|RecursiveFilterIterator|RecursiveIterator|RecursiveIteratorIterator|RecursiveRegexIterator|RecursiveTreeIterator|RegexIterator|RuntimeException|SeekableIterator|SimpleXMLIterator|SplDoublyLinkedList|SplFileInfo|SplFileObject|SplFixedArray|SplHeap|SplMaxHeap|SplMinHeap|SplObjectStorage|SplObserver|SplPriorityQueue|SplQueue|SplStack|SplSubject|SplTempFileObject|UnderflowException|UnexpectedValueException|SplBool|SplEnum|SplFloat|SplInt|SplString|SQLite3|SQLite3Result|SQLite3Stmt|Stomp|StompException|StompFrame|streamWrapper|Tidy|TidyNode|TokyoTyrant|tokyotyrantexception|TokyoTyrantIterator|TokyoTyrantQuery|TokyoTyrantTable|XMLReader|XSLTProcessor|ZipArchive|dir)$/i + }, php_fun: { 'http://www.php.net/functions.user-defined': /^function$/i }, php_var: { 'globals': /^GLOBALS$/,