Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added "MongoDB Query" syntax #2502

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion components.js

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions components.json
Expand Up @@ -704,6 +704,10 @@
"title": "Mizar",
"owner": "Golmote"
},
"mongodb-query": {
"title": "MongoDB Query",
"owner": "airs0urce"
},
"monkey": {
"title": "Monkey",
"owner": "Golmote"
Expand Down
133 changes: 133 additions & 0 deletions components/prism-mongodb-query.js
@@ -0,0 +1,133 @@
(function (Prism) {

var keywords = [
'$eq',
'$gt',
'$gte',
'$in',
'$lt',
'$lte',
'$ne',
'$nin',
'$and',
'$not',
'$nor',
'$or',
'$exists',
'$type',
'$expr',
'$jsonSchema',
'$mod',
'$regex',
'$text',
'$where',
'$geoIntersects',
'$geoWithin',
'$near',
'$nearSphere',
'$box',
'$center',
'$centerSphere',
'$geometry',
'$maxDistance',
'$minDistance',
'$polygon',
'$uniqueDocs',
'$all',
'$elemMatch',
'$size',
'$bitsAllClear',
'$bitsAllSet',
'$bitsAnyClear',
'$bitsAnySet',
'$comment',
'$meta',
'$slice',
'$currentDate',
'$inc',
'$min',
'$max',
'$mul',
'$rename',
'$set',
'$setOnInsert',
'$unset',
'$addToSet',
'$pop',
'$pull',
'$push',
'$pullAll',
'$each',
'$position',
'$slice',
'$sort',
'$bit',
];

var functions = [
'ObjectId',
'Code',
'BinData',
'DBRef',
'Timestamp',
'NumberLong',
'NumberDecimal',
'MaxKey',
'MinKey',
'RegExp',
'ISODate',
'UUID',
];

keywords = keywords.map(function(keyword) {
return keyword.replace('$', '\\$');
});

var keywordsRegex = '(?:' + keywords.join('(?:\\b|:)|') + ')\\b';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will generate a string value like this:

(?:\$foo(?:\b|:)|...|\$bar(?:\b|:)|\$baz)\b

Assuming that it's a bug that the last keyword doesn't get the (?:\b|:) suffix, we can factor out the common pre- and suffixes like this:

\$(?:foo|...|bar|baz)(?:\b|:)\b

Let's talk about the (?:\b|:)\b suffix. It's equivalent to (?:\b|:\b) where the problem is easier to see. The :\b alternative can never be matched. If we have a string "$foo:", then the \b alternative will accept after "$foo".
So we can simplify the whole pattern even further:

\$(?:foo|...|bar|baz)\b

But we know that the \b assertion will always accept because of the way the this pattern is used. It's inserted to create the keyword regex, so we know that what follows looks like this: ["']?$. Since we know that \b always accepts, we can just remove it.

\$(?:foo|...|bar|baz)

^ This is the string we want to generate.
So you can remove the $ prefix in all strings of the keywords array, you can remove the mapping adding a \ character, and this line becomes:

Suggested change
var keywordsRegex = '(?:' + keywords.join('(?:\\b|:)|') + ')\\b';
var keywordsRegex = '\\$(?:' + keywords.join('|') + ')';


Prism.languages['mongodb-query'] = {
'comment': [
{
pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
lookbehind: true
},
{
pattern: /(^|[^\\:])\/\/.*/,
lookbehind: true,
greedy: true
}
],
'property': {
pattern: /(?:[\$_a-z0-9]+|(['"])[\$[\]_a-z0-9.:-]+\1)(?=\s*:)/i,
inside: {
'keyword': RegExp('^([\'"])?' + keywordsRegex + '(?:\\1)?$')
}
},
'string': {
pattern: /(['"]).*?[^\\]\1/i,
greedy: true,
inside: {
url: {
// url pattern
pattern: /https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b[-a-zA-Z0-9()@:%_\+.~#?&//=]*/,
greedy: true
},
entity: {
// ipv4
pattern: /\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the whole string content be an IP address instead of just a substring? E.g. "foo bar 0.0.0.0 baz".

Same for url.

greedy: true
}
}
},
"boolean": /\b(?:true|false)\b/,
'constant': /\b(?:null|undefined)\b/,
'number': /\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/,
'function': RegExp('\\b(?:' + functions.join('|') + ')(?=\\s*\\()'),
'punctuation': /[{}\[\]:,()]/,
};

}(Prism));




1 change: 1 addition & 0 deletions components/prism-mongodb-query.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions examples/prism-mongodb-query.html
@@ -0,0 +1,37 @@
<h2>Query</h2>
<pre><code>
{
'_id': ObjectId('5ec72ffe00316be87cab3927'),
'code': Code('function () { return 22; }'),
'binary': BinData(1, '232sa3d323sd232a32sda3s2d3a2s1d23s21d3sa'),
'dbref': DBRef('namespace', ObjectId('5ec72f4200316be87cab3926'), 'db'),
'timestamp': Timestamp(0, 0),
'long': NumberLong(9223372036854775807),
'decimal': NumberDecimal('1000.55'),
'integer': 100,
'maxkey': MaxKey(),
'minkey': MinKey(),
'isodate': ISODate('2012-01-01T00:00:00.000Z'),
'regexp': RegExp('prism(js)?', 'i'),
'string': 'Hello World',
'numberArray': [1, 2, 3],
'stringArray': ['1','2','3'],
'randomKey': null,
'object': {'a': 1, 'b': 2},
'max_key2': MaxKey(),
'number': 1234,
'invalid-key': 123,
noQuotesKey: 'value',
checkFieldExists: {$exists: true},
age: {$gte: 18, $lte: 90}
}
</code></pre>


<h2>Update</h2>
<pre><code>
{
$inc: {product_available:-1},
$push: {product_bought_by:{customer:"rob",date:"9-Jan-2014"}}
}
</code></pre>
1 change: 1 addition & 0 deletions plugins/show-language/prism-show-language.js
Expand Up @@ -114,6 +114,7 @@
"markup-templating": "Markup templating",
"matlab": "MATLAB",
"mel": "MEL",
"mongodb-query": "MongoDB Query",
"moon": "MoonScript",
"n1ql": "N1QL",
"n4js": "N4JS",
Expand Down
2 changes: 1 addition & 1 deletion plugins/show-language/prism-show-language.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 35 additions & 0 deletions tests/languages/mongodb-query/functions_feature.test
@@ -0,0 +1,35 @@
ObjectId()
ObjectId ()
Code()
BinData()
DBRef()
Timestamp()
NumberLong()
NumberDecimal()
MaxKey()
MinKey()
RegExp()
ISODate()
UUID()

----------------------------------------------------

[
["function", "ObjectId"], ["punctuation", "("], ["punctuation", ")"],
["function", "ObjectId"], ["punctuation", "("], ["punctuation", ")"],
["function", "Code"], ["punctuation", "("], ["punctuation", ")"],
["function", "BinData"], ["punctuation", "("], ["punctuation", ")"],
["function", "DBRef"], ["punctuation", "("], ["punctuation", ")"],
["function", "Timestamp"], ["punctuation", "("], ["punctuation", ")"],
["function", "NumberLong"], ["punctuation", "("], ["punctuation", ")"],
["function", "NumberDecimal"], ["punctuation", "("], ["punctuation", ")"],
["function", "MaxKey"], ["punctuation", "("], ["punctuation", ")"],
["function", "MinKey"], ["punctuation", "("], ["punctuation", ")"],
["function", "RegExp"], ["punctuation", "("], ["punctuation", ")"],
["function", "ISODate"], ["punctuation", "("], ["punctuation", ")"],
["function", "UUID"], ["punctuation", "("], ["punctuation", ")"]
]

----------------------------------------------------

Checks for functions.