I am using marked.js to present a code editor. I want to embed an input box whenever content wrapped in {% %}. and the correct value to that input box, is the content between. for example, {% I love husky %}, will indicate I love husky to be correct answer.
<script>
// Set options
// `highlight` example uses `highlight.js`
marked.setOptions({
renderer: new marked.Renderer(),
highlight: function(code, language) {
const validLanguage = hljs.getLanguage(language) ? language : 'plaintext';
return hljs.highlight(validLanguage, code).value
.replace(/&/g, '&');
},
pedantic: false,
gfm: true,
breaks: false,
sanitize: false,
smartLists: true,
smartypants: false,
xhtml: false,
});
</script>
to parse content into element:
function rego(element, content) {
element.innerHTML = marked(content.trim());
element.querySelectorAll('p').forEach(pt => {
pt.innerHTML = marked(pt.innerHTML.replace('>', '>').replace('<', '<'));
});
codeInput(element, element.innerHTML);
MathJax.typesetPromise([element]);
}
Apply regex to replace {% %} in braces to input box:
function codeInput(code, raw) {
code.innerHTML = raw.replace(/\{\%(.*)\%\}/g, a => `<input autocomplete="off" class="what" value="${a.slice(2, -2).trim()}" />`);
code.querySelectorAll('input.what').forEach(input=>{
if(input.value){
input.data = input.value;
input.value = null;
}
});
}
it works most of the time, however in code block quote, which sometimes marked highlight will mess it up, for example, when content is this:
```py
print({% 1 %})
```
highlight will capture 1 because it is integer type and parse something like:
<pre><code class="language-py">print({% <span class="hljs-number">1</span> %})</code></pre>
which looks like (there is an input box successfully parsed between print( and 1" />)):
print(1" />)
is there a way I can configure marked.js highlight.js to avoid highlighting content between {% %}
thanks very much.
Related
I'm using https://www.npmjs.com/package/angular2-notifications this package to get notification it works fine but it works at ts file like;
saveUser(user){
//some process then notification will work.
this.notif.success(
'Yeahhh successfull create notification',
{
timeOut: 3000,
showProgressBar: true,
pauseOnHover: false,
clickToClose: true,
maxLength: 50
}
)
}
works fine but I'm using translate (i18n) and want to give these parameters by the language.And the package says it has a html function but I tried and couldn't do that which is
Thank you
I guess img can't be seen , it was the code of html
this.notif.html(`<p translate > {{ 'City' | translate }} Success</p>`)
You can use the TranslateService to get your translation values.
First import the service.
import {TranslateService} from '#ngx-translate/core';
Then inject and use it like so:
export class YourComponent {
constructor(translate: TranslateService) {
translate.get('CITY').subscribe((res: string) => {
console.log(res);
//=> 'Whatever your translation is for "city"'
});
}
}
Further documentation can be found here.
How will i18next affect rendring in React performance wise? And further, what about its interpolation mechanism vs the way react renders dynamic variables?
Given the following
/locales/{language}/common.json:
{
"hello-world": "Hello, World",
"interpolated": "Hello, {{ name }}"
}
Example with i18next
// Import i18n config and translate function
const Example = function(ownProps) {
{ t } = ownProps;
return (
<div>
<h1>{ t('interpolated', { name: "World" }) }</h1>
<h1>{ t('hello-world') }</h1>
</div>
);
};
export default translate('common', { i18n })(Example);
Example without i18next
const Example = function() {
let name = "World";
return (
<div>
<h1>Hello, World</h1>
<h1>Hello, { name }</h1>
</div>
);
};
export default Example;
How much difference for the lookups:
t('interpolated', { name: "World" }) vs Hello, { name }
t('hello-world') vs Hello, World
Maybe everything is optimized now but this repo used to show some performance problems.
https://github.com/beheh/react-i18next-performance
I would like to transfer javascript generated view to an xmlView.
This works great and I can add it to the shell:
var headItem = new sap.ui.unified.ShellHeadItem({
icon: "sap-icon://upload-to-cloud",
id: "network-icon",
customData: [
new sap.ui.core.CustomData({
key: "color",
value: "{= ${appValues>/isOnline} ? 'is-online' : 'is-offline' }",
writeToDom: true
})
]
});
What do I need to do to add this to an XML View:
<u:ShellHeadItem
id="network-icon"
icon="sap-icon://upload-to-cloud"
tooltip="Network status"/>
I tried to add it in the viewController, but it does not update the DOM.
onInit: function() {
var oNetworkIcon = this.getView().byId("network-icon");
oNetworkIcon.setModel(sap.ui.getCore().getModel("appValues"));
oNetworkIcon.addCustomData(new sap.ui.core.CustomData({
key: "color",
value: "{= ${/isOnline} ? 'is-online' : 'is-offline' }",
writeToDom: true
}));
//if you happen to know how to add a class
oNetworkIcon.addStyleClass("blub");
},
Try this:
<u:ShellHeadItem
id="network-icon"
icon="sap-icon://upload-to-cloud"
tooltip="Network status">
<u:customData>
<core:CustomData key="color" value="{= ${/isOnline} ? 'is-online' : 'is-offline' }" writeToDom="true" />
</u:customData>
</u:ShellHeadItem>
I am aware that the OP is asking for a way to write the data into the DOM.
But for those who need to access the extra data of a control through JS only:
This method is more streamlined and easier to read:
<mvc:View xmlns:mvc="sap.ui.core.mvc"
xmlns:customData="http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1"
xmlns:unified="sap.ui.unified">
<unified:ShellHeadItem id="network-icon"
icon="sap-icon://upload-to-cloud"
tooltip="Network status"
customData:color="{= ${/isOnline} ? 'is-online' : 'is-offline' }" />
</mvc:View>
You can access this extra data like so:
var myData = this.byId("network-icon").data("color");
Documentation: Custom Data - Attaching Data Objects to Controls (See "Use in XML Views").
I am trying to use metalsmith-in-place to do some in-place templating on files in subdirectories of my source dir. It doesn't work. Template tags are not replaced by the frontmatter.
My build script:
var Metalsmith = require('metalsmith'),
inplace = require('metalsmith-in-place'),
nunjucks = require('nunjucks');
Metalsmith(__dirname)
.source('./source')
.use(inplace({
engine: 'nunjucks',
pattern: '*.html',
directory: 'source/deeper'
}))
.destination('./build')
.build(function(err) {
if (err) {
console.log(err);
}
else {
console.info('Built it.');
}
});
My template:
metalsmith_debug$ cat source/deeper/index.html
---
title: My pets
---
{{title}}
My output:
metalsmith_debug$ cat build/deeper/index.html
{{title}}
It works on files in source; but I need it to work on subdirectories.
A couple of changes:
build.js:
var Metalsmith = require('metalsmith');
var inplace = require('metalsmith-in-place');
// var nunjucks = require('nunjucks');
Metalsmith(__dirname)
.source('./source')
.use(inplace({
engine: 'nunjucks',
pattern: '**/*.html' // modified pattern
// directory: 'source/deeper' // Not needed
}))
.destination('./build')
.build(function(err) {
if (err) {
console.log(err);
}
else {
console.info('Built it.');
}
});
You don't need to require nunjucks within the build file, metalsmith-in-place uses consolidate, this will require it where necessary. (Line can be removed)
Modify pattern within inplace to **/*.html. For more information see Globbing patterns.
directory isn't needed within inplace. (Line can be removed)
... and a minor change to source/deeper/index.html:
---
title: My pets
---
{{ title }}
Added space around the placeholder {{ title }} - Nunjucks seems to think this is important.
Should work now for you, let me know if not.
The accepted answer is outdated now, because metalsmith-in-place switched to use the jstransformer framework instead of consolidate.
I've written an article on how to use the in-place plugin to pair Nunjucks with Metalsmith:
Making Metalsmith to work with Nunjucks
Here's the minified working example:
const Metalsmith = require('metalsmith');
const inPlace = require('metalsmith-in-place');
Metalsmith(__dirname)
.source('./src')
.destination('./build')
.use(inPlace({
pattern: '**/*.njk',
engineOptions: {
path: __dirname + '/src'
}
}))
.build(function (error) {
if (error) {
throw error;
}
})
;
Your pattern in the inplace configuration should most likely be **/*.html rather than just *.html
I'm creating some icon font rules for using in my site. Using Sass I wanted to list all the icons in a list variable and use #each to loop through them all.
Code looks like this:
$icons:
wifi 600,
wifi-hotspot 601,
weather 602;
#each $icon in $icons {
.icon-#{nth($icon, 1)},
%icon-#{nth($icon, 1)} {
content: "\#{nth($icon, 2)}";
}
}
The problem is the backslash on the content: line. I need it for the character encoding, but it escapes the variable interpolation, outputting CSS that looks like this:
.icon-wifi {
content: "\#{nth($icon, 2)}";
}
Adding one more backslash like this: content: "\\#{nth($icon, 2)}"; outputs this CSS:
.icon-wifi {
content: "\\600";
}
Is there a way to get the Sass to output CSS with only a single backslash while keeping the variable interpolation?
I got this to work by messing with the interpolation
sassmesiter demo
// ----
// Sass (v3.4.21)
// Compass (v1.0.3)
// ----
$icons:
wifi 600,
wifi-hotspot 601,
weather 602;
#each $icon in $icons {
.icon-#{nth($icon, 1)},
%icon-#{nth($icon, 1)} {
content: #{'"\\' + nth($icon, 2) + '"'}; // <------ See this line
}
}
compiles to
.icon-wifi {
content: "\600";
}
.icon-wifi-hotspot {
content: "\601";
}
.icon-weather {
content: "\602";
}
If you include the backslash in the actual variable, then when the sass generates the css, it will actually generate the calculated unicode character instead of outputting the unicode in the css output. This still usually works but it's hard to debug if something is going wrong and it is a bit more prone to cause issues in the browser in rendering the icon.
To output the actual unicode in the generated CSS, you can do this:
#function icon($character){
#return unquote('\"') + unquote(str-insert($character,'\\', 1)) + unquote('\"');
}
$icon-thing: "e60f";
.icon-thing:before {
content: icon($icon-thing); //outputs content: "\e60f";
}
You can add the backslash to the parameter in the $icons variable. That is,
$icons: wifi "\600", wifi-hotspot "\601", weather "\602";
#each $icon in $icons {
.icon-#{nth($icon, 1)}, %icon-#{nth($icon, 1)} {
content: "#{nth($icon, 2)}";
}
}
Generated CSS:
.icon-wifi {
content: "\600";
}
.icon-wifi-hotspot {
content: "\601";
}
.icon-weather {
content: "\602";
}
Use unquote and double slash
$var:123 → content:"\e123"
content:#{unquote('\"')+("\\")+("e")+$var+unquote('\"')};
If you are using Gulp to compile your Sass files, installing this Gulp plugin is probably the easiest way to get around the issue:
https://www.npmjs.com/package/gulp-sass-unicode
var sass = require('gulp-sass');
var sassUnicode = require('gulp-sass-unicode');
gulp.task('sass', function(){
gulp.src('style.scss')
.pipe(sass())
.pipe(sassUnicode()) // <-- This is the bit that does the magic
.pipe(gulp.dest( "css/" ));
});
There is no need to make any code alterations in your Sass files. Write out your Sass code how you want and the unicode characters are decoded back into regular escaped strings in the output CSS automatically.
Input SCSS
$testContent: "\f26e";
#test {
content: $testContent;
}
Output CSS
#test {
content: "\f26e";
}
Unfortunately, these solutions were not entirely working for me but I was finally able to get it working with SASS maps
//node-sass 4.11.0
//libsass 3.5.4
$hexes: (
checkmark: \2714
);
#function out-content($var) {
#return unquote("\"#{ $var }\"");
}
#each $mod, $code in $hexes {
.#{$mod}-after {
&:after {
content: out-content($code);
}
}
}
//output
//.checkmark-after:after {
//content: "\2714";
//}