Some ideas and on going development of new plugin called MagicBlock
-
Hi everyone,
After I felt that it's so difficult to write formatted text ( color, css class ...) with a sanitized markdown, I have started writing a new plugin called Magic Block.
A basic idea is a using of
{{
}}
block ( like mediawiki or wordpress ) with parameters like{{.classname#color#BGcolor text of body }}
{{.myClass body }}
will be<span class="myClass">body<span>
{{#red body}}
will be<span style="color:red;"> body <span>
{{#red#000 body}}
will be<span style="color:red;background-color:#000">body</span>
- and also all toghter
{{.classA.classB.classC#red#yello body}}
will act in same manner.
- If you put a link as a
body
, everything will be same as above but{{.myclass http://example.com}}
will be<a href="http://example.com" class="myclass">http://example.com</a>
- Also the magic block supports
{{#red [link](http://example.com)}}
in same way.
- if you just put just a link to the magic block, then real magic will be there so
{{ http://example.com/any.jpg }}
will display a image ( currently with iFramely which means all iframely supported link will work )
Actually I have done until here, and further plan is Macros like
{{macroName(parameter)#red text of body}}
can do any special.- Also this can provide a simple but configurable macro action as a text expander via an admin interface
Right now, codes are messy and no document, no configuration interface but some basic functionalities have been done.
What do you think about these functionality and syntax?
Are those too messy or conflicting with Markdown philosophy?
Or do you have any better idea or any comments?- This is screenshot what current version of MagicBlock can do. ( iframely objects are hided by clicks )
-
Nice suggestion
-
@Zerion Thank you for a reply.
Any other comments? Also any from others?
I would like to optimize a syntax and polices by Collective Intelligence before I go further.
You know, this kind job needs quite sophisticated codes which are difficult to modify basic rules later. -
I have published a very early but working version to npm.
https://www.npmjs.com/package/nodebb-plugin-magicblock
I reveal myself that I'm from C++ and Perl and just started a Javascript ~20 hours ago. So current codes are seemingly in a javascript language but practically built with styles of C and Perl.
As a Bloody Newbie, I have no idea about that a current way is right or if there is better way/style/javascript philosophy/library and so on.I appreciate your comments and any.
-
Now MagicBlock supports both of div and span with simple mark ( ":" and "::")
- Implicit way is ( as it was )
{{.mycls TEXT}}
will be<span class="mycls">TEXT</span>
- but if you put a link or image ( or and tag group even though which is not possible with markdown ), then automatically attr string will make effect that tag group.
{{.mycls [link](example.com)}}
will be automatically
<a href="http://example.com" class="mycls">link</a>
{{#red http://example.com}}
will be simillary
<a href="http://example.com" style="color:red;">http://example.com</a>
- Now explicit way for div, span with
:
,::
is thatanyAttrString:
will wrap contents with<span>
block always so
{{.mycls: [link](http://example.com)}}
will be<span class="mycls"><a ... /a></span>
anyAttrString::
will wrap contents with<div>
block always so
{{.mycls:: [link](http://example.com)}}
will be<div class="mycls"><a ... /a></div>
So you can add
Alert
box orPanel
with bootstrap even with some messy way yet. However a named macros functionality which I'm playing on will help you.{{.panel.panel-success:: {{.panel-heading:: Title}} {{.panel-body:: A Basic Panel}} }}
Now, I'm willing to working on named macros and admin page for configures and custom macros. Do anybody suggest a base example of this( means admin UI, set/get settings )?
By the way, is nobody interested on this plugin except two, really?
- Implicit way is ( as it was )
-
@qgp9 said:
By the way, is nobody interested on this plugin except two, really?
In my opinion it's simply too much. I don't see the use of allowing all those markup. I like the simplicity of markdown and love the boundaries of it (with a few exceptions).
Allowing safe HTML can be nice, but I think most of this community is used to markdown like meHowever since there definitely are people who would benefit from your plugin, keep up the great work
Some words about the code style, since you asked:
- Since you only have a synchronous procedure, it's all fine using js similar to other languages
- Your way of avoiding
code
tags is quite nice thought it could fail when users type CODE manually, couldn't it?- I'm using this code to achieve code-block exclusions. It does not handle
pre
blocks explicitly, but since the markdown standard promises to use acode
tag within eachpre
, it's fine
- I'm using this code to achieve code-block exclusions. It does not handle
- It is common practice to use
CapitalCase
naming only for constructor functions, not for important objects. A common shortcut formodule.exports
isexports = module.exports = {...}
and referencingexports
later on.exports
is also pre-defined like this if you don't overwrite the pre-definedmodule.exports
object. - Since your code is getting quite large, you should consider splitting it into sub-modules (take a brief look at the docs for more info). I'd recommend to use the entry point only for exports needed by the hooks. This is a typical entry-point of mine.
- You should always export as few as possible. In your case only the
parse
function should get exported. Even the options (once implemented) should become a local variable defining default options while one may pass an options object to theparse
function.
-
Just two more:
- You're using a IIFE. This is not necessary for Node.js modules.
- You're using
`
for defining strings at some places. You should be aware that this is an ECMAScript2015 (ES6) feature and this is not supported by Node.js0.12
. Nowadays Node.js0.12
is a bit outdated, nonetheless debian stable still lists0.10.29
. Your choice to (not) support it
If you intend to use ES6 it's common to fully replace
var
withlet
(block-scoped variables).
You can also use a tool called babel to transpile your code to ES5 for supporting at least node.js0.12
(and with high chance0.10.29
, I'm not sure which features of ES5 that does not implement). Combine this with a task-runner (typically grunt or gulp; gulp is more beloved nowadays) and you're fine -
@frissdiegurke,
Thank you for advises.
You threw a lot which will eat my weekend
I'll follow up your list slowly.AND
@frissdiegurke said:
In my opinion it's simply too much. I don't see the use of allowing all those markup. I like the simplicity of markdown and love the boundaries of it (with a few exceptions).
Allowing safe HTML can be nice, but I think most of this community is used to markdown like meActually, I agree with your opinion and that was my dilemma also.
My needs were just colored text and a controllable inframely. And I'm using my plugin for only them.
simply{{#red TEXT}}
and{{ URL }}
But after I implemented those small functions, then I also thought somebody may want more exactly same as what you said in the end.
( Even now I'm back and thinking how admin can limit usages of users to keep clean by length? limit of functional?.. it's so ironic )
-
Using :: will break plugin spoiler ?
-
@exodo nodebb-plugin-ns-spoiler uses
:{3,}
within the regex' so::
should not break it -
@frissdiegurke said:
@exodo nodebb-plugin-ns-spoiler uses
:{3,}
within the regex' so::
should not break itI am already late!!
Let me explain even more.
Every syntax of MagicBlock include::
works only in the block{{ .. }}
so it will not effect even some other plugin which use::
.
More over, which means that MagicBlock will not effect any other plugin which doesn't use{{
or}}
except when user intend it.Please let me know if I missed any other case.
But, other plugins can make effects to MagicBlock..
Yes, I need to consider that case. -
Cool (Need more than 8 characters)
-
I have followed up your comments except only two.
https://github.com/qgp9/nodebb-plugin-magicblock/issues/1
It seems that I'm a quite good student, doesn't it?@frissdiegurke said:
- Since your code is getting quite large, you should consider splitting it into sub-modules (take a brief look at the docs for more info). I'd recommend to use the entry point only for exports needed by the hooks. This is a typical entry-point of mine.
This, I have to take, but I may need some time.
@frissdiegurke said:
- Your way of avoiding
code
tags is quite nice thought it could fail when users type CODE manually, couldn't it?- I'm using this code to achieve code-block exclusions. It does not handle
pre
blocks explicitly, but since the markdown standard promises to use acode
tag within eachpre
, it's fine
- I'm using this code to achieve code-block exclusions. It does not handle
If I understood your code correctly, it deals/parses each part of before/between/after
code
blocks separately. Am I right?
I like this idea, but in my case, I want to handlecode
block in a MagicBlock something like{{#red some `codeblock` is here}}
and thesplitting
approach will not work.
I may be able to solve the problem with a random string instead of just___CODE___
and check if that string is in contents before parsing even though it consume additional time. -
@qgp9 said:
I have followed up your comments except only two.
https://github.com/qgp9/nodebb-plugin-magicblock/issues/1
It seems that I'm a quite good student, doesn't it?It does
@qgp9 said:
@frissdiegurke said:
- Your way of avoiding
code
tags is quite nice thought it could fail when users type CODE manually, couldn't it?- I'm using this code to achieve code-block exclusions. It does not handle
pre
blocks explicitly, but since the markdown standard promises to use acode
tag within eachpre
, it's fine
- I'm using this code to achieve code-block exclusions. It does not handle
If I understood your code correctly, it deals/parses each part of before/between/after
code
blocks separately. Am I right?
I like this idea, but in my case, I want to handlecode
block in a MagicBlock something like{{#red some `codeblock` is here}}
and thesplitting
approach will not work.
I may be able to solve the problem with a random string instead of just___CODE___
and check if that string is in contents before parsing even though it consume additional time.You're right, it does work that way.
I have a better idea: Since your script gets executed (you should add apriority
option to the parse hooks btw. to ensure this) after the markdown parser, you can use a string that may never pass the markdown parser, e.g.<<code>>
since<
gets passed as<
except for real HTML-tags for sure. - Your way of avoiding
-
@frissdiegurke said:
I have a better idea: Since your script gets executed (you should add a
priority
option to the parse hooks btw. to ensure this) after the markdown parser, you can use a string that may never pass the markdown parser, e.g.<<code>>
since<
gets passed as<
except for real HTML-tags for sure.You are just a genius.
-
I also think the code quality suffers a lot from inline functions. I've trained me to use global functions (even below all exports) and reference them where they need to be exported.
I try to keep my files like this (it's just about structure; keeping
'
instead of"
and dropping;
is up to you):"use strict"; // define dependencies to other modules let x = require("x"); // and local ones separated by one empty line let y = require("./y"); // constants const XYZ = "XYZ"; // "global" variables (as few as possible) let myVar = null; /*======================== Exports ========================*/ // exports (variables first) exports.lastText = null; // if possible demonstrate the variable type, even if it gets overwritten without being read once exports.options = {}; // exports (functions last) exports.parse = parse; exports.init = function (cb) { cb(); } // simple one-liner are ok in my opinion /*==================== Initial Workflow ====================*/ // procedure on module-load (if any, as few as possible); if exceeds ~5 lines, it should become a function console.log(parse(XYZ)); // just for demonstration purpose return; // The function definitions are independent of procedural workflow. /*======================= Functions =======================*/ function someUtil(text) { exports.lastText = text; } // one-liner are ok in my opinion function parse(text) { someUtil(text); return text.replace(/X/g, function () { return "<<X>>"; }); }
This way there is no module whose dependencies and exports I cannot see on the top of the file (and thus on first page of screen in most cases).
The exports are primarily sorted as stated above (variables/functions), secondarily by logical connection.
The order of the function definitions might as well be sorted by logical connection but is basically irrelevant since you can jump to ones definition with most IDEs via the reference within the exports section.
Following this structure you also don't need to referenceexports
within your functions except you want to modify/read variables within. Function calls go withoutexports
access.Except the separation lines (
/*=== ... ===*/
) I don't recommend the usage of any comments. Documentation is great of course (but as long you keep the functions short it's not required)This is just a recommendation of what I've learned to use within the last year (in retrospective my code was not quite readable before)
And of course I'd also be thankful for any kind of code quality recommendations of other people
Feel free to criticize my schema. -
An upvote is not just enough!
I have been trying to catch your style and realize that it's quite reasonable and clean ( but I need more practical understanding , maybe by reading of your plugin and module. )
I really think that we need to elevate this coding style and policy at some point. I read several plugins and some of them seem to need to be guided like mine. ( I don't blame those plugins, one of my motto is that "something is not better than nothing ( of course not always ) )
-
@qgp9 lol I need 3 upvoted it's good to have upvotes it gives u reputation!!!!