When I use the hexo tag plugin, i found that I cannot use space within the parameter of a tag plugin, even I wrap the parameter with double quote. This confuses me a lot.
Originally, I think this may be the bug of a 3rd party tag plugin for hexo
.
But after some investigation, this is the bug of hexo itself.
Nunjucks
Before I start to explain about the detail of this bug.
I indeed speed several hours to dive into the code of Nunjucks
.
Nunjucks
A rich and powerful templating language for JavaScript.
Nunjucks
is an interesting template framework for JavaScript. It has many great features and one of them used by hexo
is the custom tag.
Nunjucks Custom Tag
In Nunjucks
, you can define the custom tag
to integrate it into whole lexical analytics system. So that it will be processed as a Nunjucks
native supported tag.
In order to implement a custom tag
, you need to implement two function:
parse
parse
is used to get the travel through lexically-marked token. So that you will analyze each part of the arguments you want for your specific custom tag
.
For example, if you define a tag like below:
1 | {% mytag "param1" "param2" "param3" %} |
You need to define the parse
function like:
1 | function(parser, nodes, lexer) |
You use the parser.nextToken()
to get each part of your arguments.
For example (here is the pseudo code to explain, more info refer to lexer.js of Nunjucks:
- Node -> { type: TOKEN_WHITESPACE, value: ‘ ‘ }
- Node -> { type: TOKEN_STRING, value: ‘param1’ }
- Node -> { type: TOKEN_WHITESPACE, value: ‘ ‘ }
- Node -> { type: TOKEN_STRING, value: ‘param2’ }
- Node -> { type: TOKEN_WHITESPACE, value: ‘ ‘ }
- Node -> { type: TOKEN_STRING, value: ‘param3’ }
- Node -> { type: TOKEN_BLOCK_END, value: ‘%}’ }
Usually, we travel through each of the lexical node, save them as specific node in nodes
parameter back to Nunjucks
framework, and found the TOKEN_BLOCK_END
to stop our process for any custom tag
Run
Run
is used to process the information you just analyze from the parse
function. Simply speaking, it is used to render the parameters to its expected result for the case of hexo
Hexo implementation issue
Here is the pull request for fix the issue, i would like to talk based on it.
We can see that, current implementation of hexo
:
- simply connect all the parameter together as a string in
parse
function
In fact, i do not understand here, it use a arrayargs
, but use the string+=
to connection all things together, which result in a string. Cannot make sure it is a expected code or the writer think he could use+=
for array elements. - simply split the string with space and ignore all the lexical context in
run
Hexo
simply split all the parameter with space, this is the root cause for non space supported issue. And it pass the arguments into registered function. so we cannot use the space anymore even wrapped in a string literal.
One more detail about my change:
If you want to use the Nunjucks
to pass the result of parse
correctly to run
, you need to follow the internal structure of Nunjucks
. Here my fix need to pass a array to run
, instead of give the value of a nodes.Literal
a simple javascript array object, we need to create a nodes.Array
object, and add each of part of the tag arguments as nodes.Literal
into it. so that Nunjucks
can understand what we really want to pass.
So here i give a fix and hope hexo will merge it ASAP.
In case anyone see the same issue, so I write it down here.
References: