There is a string that may contain nicknames given by #nickname. Nickname can be inputed by user with typo by concatenation with previous word, like
Hello my inst is#nickname
Also nickname word can be situated at the beginning of the new paragraph, hence just using split(' ') wouldn’t work.
What I want ultimately do is to after user inputs, highlight nicknames in string by covering them with <span> setting some styles and adding onclick link to instagram with that account.
Solution I’ve made so far:
<script>
window.onload=function()
{
var text = "Hello #buf world #text";
text = Synt(text);
var a = addP(document.body,text,30,30,"black",20);
a.innerHTML=text;
}
function Synt(a)
{
if(a.search('#')==-1)
return a;
else
{
var regex = /#/gi, result, indices = [];
while ( (result = regex.exec(a)) ) {
indices.push(result.index);
}
var a1 = (' ' + a).slice(1);
var ar = a.split('');
for(var i=0;i<indices.length;i++)
{
var r=[];
var rr=0;
for(var j=indices[i];j<a.length&&(isLetter(a[j])||a[j]=='.'||a[j]=='_'||rr==0);rr++,j++)
r[rr]=a[j];
r=r.join('');
a1 = a1.replace(r,'<span style="color:blue">'+r+'</span>');
}
return a1;
}
}
function isLetter(str) {
return str.length === 1 && str.match(/[a-z|0-9]/i);
}
function addP(par,text,left,top,color='black',size='17px', fun=0)
{
var p = document.createElement('p');
p.style.position = 'absolute';
p.style.color=color
p.style.fontSize=size;
p.style.fontFamily='Arial';
par.appendChild(p);
p.style.left=left;
p.style.top=top;
p.innerText=text;
if(fun)
p.onclick=fun;
return p;
}
</script>
Related
I'm trying to create a script in adobe illustrator that will check if a file name contains "ph" +5 numbers.
If it has been found then it will replace a part of a text with the match from the file name.
This is what I have so far I just can't get it to work, the text is replaced with "null"
var doc = app.activeDocument;
var name = doc.name;
var match = name.match(/ph\d{5}/);
for (i = 0; i < doc.textFrames.length; i++)
{
doc.textFrames[i].contents = doc.textFrames[i].contents.replace(/ph00000/gi, match);
}
I'd try this:
var doc = app.activeDocument;
var match = doc.name.match(/ph\d{5}/);
if (match != null) {
for (i = 0; i < doc.textFrames.length; i++) {
doc.textFrames[i].contents = doc.textFrames[i].contents.replace(/ph00000/gi, match[0]);
}
}
You can encapsulate the text that you want to replace with group constructs, and since you're using String.prototype.replace, you can capture the parenthesized group and pass the callback function as the 2nd argument in your .replace function.
Read more about it here
Example:
const textString = "This is ph54321 or ph12345";
const newString1 = textString.replace(/(ph)\d{5}/gi, function (matches, p1) {
return p1 + "appended"; // "This is phappended or phappended"
});
const newString2 = textString.replace(/ph(\d{5})/gi, function (matches, p1) {
return "BIGPH" + p1; // "This is BIGPH54321 or BIGPH12345"
});
console.log({newString1});
console.log({newString2});
I'm currently building an auto-generated TOC in Javascript. Step 1 is to take the text content of every h1-6, strip punctuation and spaces, replace with dashes, and lowercase it, then add that as the id, which is what I have here:
function TOC() {
let h2s = document.querySelectorAll("h2");
let h3s = document.querySelectorAll("h3");
let h4s = document.querySelectorAll("h4");
let h5s = document.querySelectorAll("h5");
let h6s = document.querySelectorAll("h6");
let headings = [...h2s, ...h3s, ...h4s, ...h5s, ...h6s];
function cleanID(content) {
let trimmed = content.trim();
let removedPunctuation = trimmed.replace(/[^\w\s]|_/g, "").replace(/\s+/g, " ");
let singleSpacesOnly = removedPunctuation.replace(/\s\s+/g, " ");
let spacesToHyphens = singleSpacesOnly.replace(/\W/g, "-");
let cleanedID = spacesToHyphens.toLowerCase();
return cleanedID;
}
headings.forEach((heading) => {
heading.id = cleanID(heading.textContent);
});
}
TOC();
This works fine except when it comes to duplicate IDs. What I'd like to do is increment by 1 for every duplicate of each heading, and append that. So for example, if I had
<h2>Foo</h2>
<h3>Bar</h3>
<h2>Foo</h2>
<h3>Baz</h3>
<h4>Bar</h4>
I'd like for the IDs to be, respectively, foo, bar, foo-2, baz, bar-2.
The obvious doesn't seem to work:
var cleanedIDs = [];
function cleanID(content) {
...
let increment = 0;
if(cleanedIDs.includes(cleanedID) {
cleanedID = `${cleanedID}-${increment++}`;
cleanedIDs.push(cleanedID);
} else {
cleanedIDs.push(cleanedID);
}
}
Would appreciate help working through the logic of it. I've started a pen here.
You can use reduce to keep track of the count inside an Object. Then just change the id property accordingly.
let headings = [...document.querySelectorAll("h3")];
function headingDups (headings) {
return headings.reduce((store, heading) => {
store[heading.textContent] = (store[heading.textContent] || 0) + 1;
if(store[heading.textContent] > 1) {
heading.id = heading.textContent + "-" + store[heading.textContent]
return store;
}
heading.id = heading.textContent;
return store;
}, {});
}
headingDups(headings);
<h3>hello</h3>
<h3>goodbye</h3>
<h3>h3llo</h3>
<h3>hello</h3>
<h3>h3llo</h3>
<h3>goodbye</h3>
I'm making a search function for my website. So far, I've found the string the user searches for in the whole website, and I'm able to print the string and the context of the string. I have achieved this by using $.get on my HTML pages, then stripping the HTML to leave the pure text I want to search in. I then find the index of the string I'm looking for, then use substr to find the context of the input string (a few indexes ahead and behind).
Now, I need to link to the original page when a user clicks on a search result. My research says to use <a> tags, but how do I dynamically insert those into the HTML page with the index I have? And the index I have isn't even the complete page; it's stripped of tags.
These are the relevant parts of my code:
JavaScript:
function getIndicesOf(searchStr, str) { //get the indices of searchStr inside of str
var searchStrLen = searchStr.length;
if (searchStrLen == 0) {
return [];
}
var startIndex = 0, index, indices = [];
str = str.toLowerCase();
searchStr = searchStr.toLowerCase();
while ((index = str.indexOf(searchStr, startIndex)) > -1) {
indices.push(index);
startIndex = index + searchStrLen;
}
return indices;
}
function search() {
obj=document.getElementById("searchButton");
obj.onclick = function() {
var searchInput = document.getElementById('searchBox').value;
var allPageContent = ['chap/telem.php', 'chap/nestor.php', 'chap/aeolus.php', 'chap/calypso.php', 'chap/circe.php', 'chap/cyclops.php', 'chap/eumaeus.php', 'chap/hades.php','chap/ithaca.php', 'chap/lestry.php', 'chap/lotus.php', 'chap/nausicaa.php', 'chap/oxen.php', 'chap/penelope.php', 'chap/proteus.php', 'chap/scylla.php', 'chap/sirens.php', 'chap/wrocks.php']; //contains all text
var allText = '';
for (var i = 0; i < allPageContent.length; i++){
$.get(allPageContent[i], function(data){
var div = document.createElement("div");
div.innerHTML = data;
//allText = div.textContent || div.innerText || ""; //gets the text to search in, stripped of html
alltext = data;
allText = allText.replace(/(\r\n\t|\n|\r\t)/gm," ");
console.log(data);
var indices = getIndicesOf(searchInput, allText); //the variable indices is the array that contains the indices of the searched text in the main text
indices.forEach(findContext);
})
}
localStorage.output = '';
function findContext(currentValue, index) {
if (currentValue <= 16) {
searchContext = "..." + allText.substr(currentValue, 100) + "...";
} else {
searchContext = "..." + allText.substr(currentValue-15, 100) + "...";
}
localStorage.output = localStorage.output + searchContext + "<br /><br />";
}
console.log(localStorage.output);
};
};
HTML:
<script>document.getElementById("output").innerHTML = localStorage.output;</script>
It's a bit confusing what you're trying to achieve, considering your HTML, but replying to this
My research says to use <a> tags, but how do I dynamically insert
those into the HTML page with the index I have?
this would do the trick
var output = document.getElementById("output");
var a = document.createElement("a");
var linkText = document.createTextNode("my linked text");
a.appendChild(linkText);
a.href = "http://example.com";
output.appendChild(a);
I am working on a project that takes text that a user inputs in a text box and returns the most common word.
Javascript:
var bestMode = 1;
var currentMode = 0;
var character;
function Find_Word(){
var words = document.getElementById('words').innerText;
var punctuationless = words.replace(/['!"#$%&\\'()\*+,\-\.\/:;<=>?#\[\\\]\^_`{|}~']/g,"");
var finalString = punctuationless.replace(/\s{2,}/g," ");
var WordList = finalString.split(" ");
return FindMode(WordList);
}
function FindMode(WordList){
for(var i=0; i<WordList.length; i++){
for(var m=i; m<WordList.length; m++){
if(WordList[i] == WordList[m]){
currentMode += 1;
}
if(bestMode<currentMode){
bestMode = currentMode;
character = WordList[i];
}
}
currentMode = 0;
}
}
console.log(bestMode);
HTML:
<html>
<body>
<h1>Most common word used</h1>
<input type="text" id="words" rows="10" columns="30"></input>
<button type="button" id="FindWord" onclick="Find_Word()">Find Word</button>
<script src="CommonWord.js"> </script>
</body>
</html>
What I can't figure out is the correct way to pull text from the text box into a variable as one string. My function Find_Word takes the received string when the button is pressed and strips away punctuation and leaves an array WordList with with each individual word in the string.
After that, I also can't understand how to pass that array into my second function findMode where I iterate through each value of the array to find the most common word. That is saved in the variable bestMode.
It looks as if you are both getting the current text and passing the array correctly (although perhaps you should get the textbox value using the .value property). What problem are you having exactly? I am not sure what FindMode is supposed to do either.
Here is some script that is based on what you posted that sorts "words" according to how often they appear :
(function(w) {
w.Sort_Words = function(words) {
var o = {}, l = [];
for(var i=0; i<words.length; i++) {
if (typeof o[words[i]] === 'undefined') {
o[words[i]] = 0;
l.push(words[i]);
}
o[words[i]] ++;
}
l.sort(function(a, b) { return o[b] - o[a]; });
return l;
};
w.Find_Word = function() {
var text = document.getElementById('words').value;
var words = text.replace(/['!"#$%&\\'()\*+,\-\.\/:;<=>?#\[\\\]\^_`{|}~']/g,"").replace(/\s{2,}/g," ").split(' ');
var sorted = w.Sort_Words(words);
document.getElementById('results').innerText = sorted.length === 0 ?
'You must type at least one word' :
'The most commonly used word was: ' + sorted[0];
};
})(window);
Fiddler: http://jsfiddle.net/4u1mv20h/4/
I have a chat app and I want to use a profanity filter.
I've came up with: http://jsfiddle.net/691nruoL/4/
var chatMessage = "sex it up what the fuck tits lol fuck titsss";
// Potentially an array of hundreds of words coming from a JSON file
var badWords = ['sex', 'fUck', 'dick', 'penis', 'cum', 'tits', 'fuck'];
for (var i = 0; i < badWords.length; i++) {
if (chatMessage.indexOf(badWords[i].toLowerCase()) !== -1) {
chatMessage = chatMessage.replace(badWords[i].toLowerCase(), pushAsterisksForWordLength(badWords[i].length));
}
}
function pushAsterisksForWordLength(asterisksLength) {
var censoredWordArray = [];
for (var i = 0; i < asterisksLength; i++) {
censoredWordArray.push('*');
}
return censoredWordArray.join('');
}
console.log(chatMessage);
How would you optimize it? I feel like with many bad words in the array, it could be quite slow.
Use regexp:
var chatMessage = "sex it up what the fuck tits lol fuck titsss";
var badWords = ['sex', 'fUck', 'dick', 'penis', 'cum', 'tits', 'fuck'];
var regExpSource = badWords.join('|');
var regExpFilter = new RegExp(regExpSource, 'ig');
console.log(regExpFilter.test(chatMessage));
And remove words with asterisks like with:
chatMessage.replace(regExpFilter, function () {
return '****';//Don't matter what that was a word
});
// Prepare for search (just once)
var badWordsRE = new RegExp(badWords.join('|'), "gi");
var asterisks = "";
badWords.forEach(function(word) {
while (word.length > asterisks.length) asterisks += "*";
});
// Search and destroy
chatMessage.replace(badWordsRE, function(word) {
return asterisks.substring(0, word.length);
});
// => "*** it up what the **** **** lol **** ****ss"
Subsitiutes each letter in a "bad" word with an asterisk without looping over the word:
chatMessage.replace(/sex|fuck|tits/gi,function( word ){
return word.replace(/./g,'*')
});
http://jsfiddle.net/691nruoL/5/