How to add more language in my Highlight.js - javascript

Based on the code sample, how to add new language like c#, php, java, sql, etc. This sample was provided by a man who answered my question last month. I tried to add new languages but not working. Thanks.
const container = document.querySelector('.container');
const removeTextNodes = el =>
[...el.childNodes].forEach(child => child.nodeType !== 1 && el.removeChild(child))
const format = (text, language) => {
switch (language) {
case 'html': return html_beautify(text);
case 'css': return css_beautify(text);
case 'js': return js_beautify(text);
default: return text;
}
}
const preProcess = code => {
removeTextNodes(code.closest('pre'));
const language = [...code.classList].find(cls => /language-/.test(cls));
const [ match, lang ] = language?.match(/language-(\w+)/);
const content = code.innerHTML.trim();
code.innerHTML = format(lang === 'html' ? _.escape(content) : content, lang);
};
const insertCode = (e) => {
e.preventDefault();
const content = e.target.elements.content.value.trim();
const language = e.target.elements.language.value;
if (content) {
const formatted = format(content, language);
const pre = document.createElement('pre');
const code = document.createElement('code');
code.classList.add(`language-${language}`, 'hljs');
code.innerHTML = hljs.highlight(formatted, { language }).value;
pre.append(code);
container.prepend(pre);
}
}
document.forms['add'].addEventListener('submit', insertCode);
document.querySelectorAll('code[class^="language-"]').forEach(preProcess);
hljs.highlightAll();

You can check the loaded languages with
hljs.listLanguages()
If this list doesn't contain the language, you want to use, you can load your language script-wise.
For example i wanted to use latex, so i added this script:
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/latex.min.js"></script>

Related

How to change link (href) when i change language (option) ? | JavaScript

Please, Help me. I know how to translate text from json, but i don't understand how to change "href". How can i change "href" in the link by my switcher? I need to change links to right lang... link 1 for EN. link 2 for GER
My lang switcher
select.locale-switcher(data-lang-switcher='')
option(value='en') EN
option(value='ger') GER
my link
.contacts__item
a.agreement(data-lang="license" href="www.link1.com" LICENSE AGREEMENT
my js
const defaultLocale = "en";
let locale;
let translations = {};
document.addEventListener("DOMContentLoaded", () => {
setLocale(defaultLocale);
bindLocaleSwitcher(defaultLocale);
changeLink()
});
async function setLocale(newLocale) {
if (newLocale === locale) return;
const newTranslations =
await fetchTranslationsFor(newLocale);
locale = newLocale;
translations = newTranslations;
translatePage();
}
async function fetchTranslationsFor(newLocale) {
const response = await fetch(`/lang/${newLocale}.json`);
return await response.json();
}
function translatePage() {
document
.querySelectorAll("[data-lang]")
.forEach(translateElement);
}
function translateElement(element) {
const key = element.getAttribute("data-lang");
const translation = translations[key];
element.innerText = translation;
}
function bindLocaleSwitcher(initialValue) {
const switcher = document.querySelector("[data-lang-switcher]");
switcher.value = initialValue;
switcher.onchange = (e) => {
// Set the locale to the selected option[value]
setLocale(e.target.value);
};
}
I tried by json, by setAttribute, but nothing

How to generate HTML text with a for loop?

I have a list of expenses, I want to create a html code to iterate over all the expenses and show their name. I am not working with the DOM, I literally want to save the html code in a variable, so I can generate a pdf file with it.
This is what I tried:
lets say I have this array
const spents = [{expenseName: "Pizza"},{expenseName: "Home"}]
const testHtml = () => {
for(let i of spents) {
const title = `<h1>${i.expenseName}</h1>`
}
}
testHtml()
This is the result I want, something like:
htmlResult = "<h1>${i.expenseName}</h1> <h1>${i.expenseName}</h1>"
by the way, This is for a react native app.
I think this will work for you.
const spents = [{expenseName: "Pizza"},{expenseName: "Home"}]
const testHtml = () => {
let title = '';
for(let i of spents) {
title += `<h1>${i.expenseName}</h1>`
}
return title;
}
testHtml()
You could use Array.prototype.reduce().
const spents = [{
expenseName: "Pizza"
}, {
expenseName: "Home"
}];
const result = spents.reduce((prev, curr, index) => index === 0 ? curr.expenseName : `<h1>${prev}</h1> <h1>${curr.expenseName}</h1>`, '');
document.body.append(result);

Async JS validation issues for html textarea

I'm trying to replicate the code in this article:
https://depth-first.com/articles/2020/08/24/smiles-validation-in-the-browser/
What I'm trying to do different is that I'm using a textarea instead of input to take multi-line input. In addition to displaying an error message, I also want to display the entry which doesn't pass the validation.
The original validation script is this:
const path = '/target/wasm32-unknown-unknown/release/smival.wasm';
const read_smiles = instance => {
return smiles => {
const encoder = new TextEncoder();
const encoded = encoder.encode(`${smiles}\0`);
const length = encoded.length;
const pString = instance.exports.alloc(length);
const view = new Uint8Array(
instance.exports.memory.buffer, pString, length
);
view.set(encoded);
return instance.exports.read_smiles(pString);
};
};
const watch = instance => {
const read = read_smiles(instance);
document.querySelector('input').addEventListener('input', e => {
const { target } = e;
if (read(target.value) === 0) {
target.classList.remove('invalid');
} else {
target.classList.add('invalid');
}
});
}
(async () => {
const response = await fetch(path);
const bytes = await response.arrayBuffer();
const wasm = await WebAssembly.instantiate(bytes, { });
watch(wasm.instance);
})();
For working with a textarea, I've changed the watch function to this and added a <p id="indicator"> element to the html to display an error:
const watch = instance => {
const read = read_smiles(instance);
document.querySelector("textarea").addEventListener('input', e => {
const { target } = e;
var lines_array = target.value.split('/n');
var p = document.getElementById("indicator");
p.style.display = "block";
p.innerHTML = "The size of the input is : " + lines_array.length;
if (read(target.value) === 0) {
target.classList.remove('invalid');
} else {
target.classList.add('invalid');
}
});
}
I'm not even able to get a count of entries that fail the validation. I believe this is async js and I'm just a beginner in JavaScript so it's hard to follow what is happening here, especially the part where the function e is referencing itself.
document.querySelector("textarea").addEventListener('input', e => {
const { target } = e;
Can someone please help me in understanding this complicated code and figuring out how to get a count of entries that fail the validation and also printing the string/index of the same for helping the user?
There is a mistake in you code to count entries in the textarea:
var lines_array = target.value.split('\n'); // replace /n with \n
You are asking about the function e is referencing itself:
The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables. You can find more informations Mdn web docs - Destructuring object

Converting AVVideoComposition initializer to Nativescript

Looking for some help on porting this objective-c class method to JS/nativescript.. every variation I've tried has resulted in a TypeError: undefined is not a function...
https://developer.apple.com/documentation/avfoundation/avvideocomposition/1389556-init
Which I've tried to write in JS as:
const videoComp = AVVideoComposition.alloc().initWithAssetApplyingCIFiltersWithHandler(asset, (request) => { ... });
//OR
const videoComp = AVVideoComposition.alloc().initAssetApplyingCIFiltersWithHandler(asset, (request) => { ... });
//OR
const videoComp = AVVideoComposition.alloc().initAssetApplyingCIFiltersWithHandlerApplier(asset, (request) => { ... });
//OR
const videoComp = new AVVideoComposition(asset, (request) => { ... });
to name a few. essentially, I am trying to port this code to nativescript/JS:
let blurRadius = 6.0
let asset = AVAsset(url: streamURL)
let item = AVPlayerItem(asset: asset)
item.videoComposition= AVVideoComposition(asset: asset) { request in
let blurred = request.sourceImage.clampedToExtent().applyingGaussianBlur(sigma: blurRadius)
let output = blurred.clampedToRect(request.sourceImage.extent)
request.finish(with: output, context: nil)
}
found in this blog post: https://willowtreeapps.com/ideas/how-to-apply-a-filter-to-a-video-stream-in-ios
It should look something like this with JavaScript / Typescript,
let blurRadius = 6.0;
let asset = AVAsset.assetWithURL(streamURL);
let item = AVPlayerItem.alloc().initWithAsset(asset);
item.videoComposition = AVVideoComposition.videoCompositionWithAssetApplyingCIFiltersWithHandler(asset, request => {
let blurred = request.sourceImage.imageByClampingToExtent().imageByApplyingGaussianBlurWithSigma(blurRadius);
let output = blurred.imageByClampingToRect(request.sourceImage.extent);
request.finishWithImageContext(output, null);
});
Note: The code is untested and merely a translation of given native code. Make use of tns-platform-declarations for IntelliSense support.

Draft.js. How to get all entities data from the ContentState

From official docs I know about 2 methods: get entity by its key and get last created entity. In my case, I also need a method to access all entities from current ContentState.
Is there any method that could perform this? If not, is there a one that can provide all entities keys?
const getEntities = (editorState, entityType = null) => {
const content = editorState.getCurrentContent();
const entities = [];
content.getBlocksAsArray().forEach((block) => {
let selectedEntity = null;
block.findEntityRanges(
(character) => {
if (character.getEntity() !== null) {
const entity = content.getEntity(character.getEntity());
if (!entityType || (entityType && entity.getType() === entityType)) {
selectedEntity = {
entityKey: character.getEntity(),
blockKey: block.getKey(),
entity: content.getEntity(character.getEntity()),
};
return true;
}
}
return false;
},
(start, end) => {
entities.push({...selectedEntity, start, end});
});
});
return entities;
};
How I get the all entities keys:
const contentState = editorState.getCurrentContent()
const entityKeys = Object.keys(convertToRaw(contentState).entityMap)
result:
[0, 1]
then you can call the getEntity(key) method to get the responding entity.
this is how convertToRaw(contentState) looks:
Bao, You will find it inside key called 'blocks'.
convertToRaw(contentState).blocks.map(el=>el.text)
It will give you an array of raw text.
Unfortunatelly your suggested way using convertToRaw doesnt work because it reindexes all keys to ["0", .., "n"], but the real keys differ when you act with the editor. New ones > n will be added and unused will be omitted.
const rawState = convertToRaw(contentState)
const { entityMap } = rawState;
This entityMap will have list of all entities. But this is an expensive conversion. Because, it will convert whole thing to raw. A better way is loop through blocks and check for entity.
You'll have to look at every character:
const { editorState } = this.state; // assumes you store `editorState` on `state`
const contentState = editorState.getCurrentContent();
let entities = [];
contentState.getBlockMap().forEach(block => { // could also use .map() instead
block.findEntityRanges(character => {
const charEntity = character.getEntity();
if (charEntity) { // could be `null`
const contentEntity = contentState.getEntity(charEntity);
entities.push(contentEntity);
}
});
});
Then you could access it via:
entities.forEach((entity, i) => {
if (entity.get('type') === 'ANNOTATION') {
const data = entity.get('data');
// do something
}
})

Categories

Resources