I am working on inserting text to the bottom of certain wordpress posts based on the amount of times a string occurs. I've managed to add the text to the bottom with append but instead I would like to insert at a specific location using indexOf.
here is the original text:
if ($('body').hasClass("single-post")){
var count = 0;
var cSearch = $('body').text();
var words = cSearch.indexOf('Words To Find')
while (words !== -1){
count++;
words = cSearch.indexOf('Words To Find', words + 1);
}
if( count >= 2){
$('.entry-content').append('<br><br>Sample Text');
}
}
Here is how I will get the location I want to insert before:
var insertLocation = cSearch.indexOf('Show what ya');
How can I splice the "Sample Text" into the location specified with insertLocation?
I found a bit about using polyfil for .splice but I'm not sure it works for this. Using it such as:
$(cSearch).splice( insertLocation, -1 ).text( "Sample Text" );
Can someone suggest a way to do this? Thanks!
Try creating variables representing total matches , indexOf() match plus matched text .length , using .slice() to insert original text before second match , new text ti insert , followed by remainder of original text
var text = $("div").text(),
match = "Words To Find",
txt = " Sample Text ",
matches = 0,
n = 0,
// `max` : total number of `matches` before inserting `txt`
max = 2;
while (matches < max) {
if (text.indexOf(match, n) !== -1) {
i = text.indexOf(match, n);
n = i + match.length;
++matches
}
}
// insert `re` after second match of `"Words To find"`
var re = text.slice(0, i + match.length) + txt;
$("div").text(re + text.slice(i));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<body>
<div>Words To Find abc def Words To Find ghi Words To Find</div>
</body>
Related
I am creating a GDocs Apps Script to check my document to see if it is in Standard Pilish. I'd like to have the checker return both the position of the first error and the word that is incorrect. I can get the position of the first error in pi, but since the word list does not necessarily perfectly reflect that positioning.
For example, I used a modified quote from Peter Walder: "Two mathematicians accommodatingly promenade to tavern, quest everything". The error lies in the 8th word in the list, but the 10th position in pi.
This is the script I've landed at, and I originally tried to just words[positionOne] before realizing my counting error.
function pilishTranslate() {
var doc = DocumentApp.getActiveDocument();
var text = doc.getBody().getText();
// Remove quotation marks from the text
text = text.replace(/\"/g, "");
// Replace all non-letter characters with white space
text = text.replace(/[^a-zA-Z\s]/g, " ");
// Split the text into an array of words
var words = text.split(/\s+/);
// Count word length
var wordLengths = words.map(function(word) {
return word.length;
});
// Change 10 character counts to 0
wordLengths = wordLengths.map(function(length) {
return length === 10 ? 0 : length;
});
// Join character counts into single string
var wordLengthsString = wordLengths.join('');
// Create variable for pi
var decimal15 = '314159265358979'
// Find common prefix of strings a and b.
var prefix = function(a,b){
return a && a[0] === b[0] ? a[0] + prefix(a.slice(1), b.slice(1)) : '';
};
// Find index of first difference.
var diff = function(a,b){
return a===b ? -1 : prefix(a,b).length;
};
// actual test case
var tests = [
[wordLengthsString,decimal15],
];
// find first position of error
var positionOne = tests.map(test => diff(test[0], test[1]))
console.log(positionOne);
}
function checkPilish(text) {
// Remove quotation marks from the text
text = text.replace(/\"/g, "");
// Replace all non-letter characters with white space
text = text.replace(/[^a-zA-Z\s]/g, " ");
// Split the text into an array of words
var words = text.split(/\s+/);
// Create variable for pi
var decimal15 = '314159265358979'
let pi_index = 0;
// Loop over words
for (let i = 0; i < words.length; i++) {
// convert word length to Standard Pilish digits
let length_str = String(words[i].length);
if (length_str == '10') {
word_length = '0';
}
// check if this matches the current position in pi
if (decimal15.substr(pi_index, length_str.length) != length_str) {
return [i+1, words[i]];
}
pi_index += length_str.length;
}
return [];
}
console.log(checkPilish("Two mathematicians accommodatingly promenade to tavern, quest everything"));
console.log(checkPilish("Two mathematicians accommodatingly promenade to tavern, quest all"));
I am trying to highlight a specific occurrence of a word in a text using jquery/js. Trying to find out if there are any existing libraries I can use. I read about mark.js but it does not offer the functionality I need.
Example Text: "In a home, there is a room, the room has a door"
Highlight word: "room"
Occurrence: 2
The second "room" in the text needs to be highlights.
Please suggest. Thanks!
Just pass in the specific index of the token (character sequence you are looking for) to a function that takes the string, token, and index as parameters. You can now use the 2nd parameter of indexOf to update the beginning of where the string will be searched from using the last result:
const highlighter = (string, token, index) => {
let n = -1
for (let i = 0; i <= index; i++) {
n = string.indexOf(token, n + 1)
}
return string.slice(0, n) + string.slice(n).replace(token, '<span class="highlight">' + token + '</span>')
}
const text = 'In a home, there is a room, the room has a door.<br>'
const firstRoom = highlighter(text, 'room', 0)
const secondRoom = highlighter(text, 'room', 1)
$('#result').append(firstRoom)
$('#result').append(secondRoom)
.highlight {
background-color: lightblue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="result"></div>
The -1 is important since this function would otherwise miss the first token occurence if it appears at the start of the string.
You could do it like this:
let text = "In a home, there is a room, the room has a door.";
let search = "room";
var n = text.lastIndexOf(search);
text = text.slice(0, n) + text.slice(n).replace(search, "<span class='highlight'>" + search + "</span>");
$("#result").append(text);
.highlight {
color:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="result">
</div>
// To replace all (commented out so it doesn't interfere with the other one)
/*
var p = document.getElementById("text"); // Gets the <p>
var text = p.innerText; // Gets the text it contains
var wordToReplace = "room"; // Which word should be replaced
var newtext = text.replaceAll(wordToReplace, '<span class="highlight">' + wordToReplace + '</span>'); // Replaces the word with the word wrapped in <span> tags, so it will look highlighted
p.innerHTML = newtext; // Change it back
*/
// To replace specific occurences
var paragraph = document.getElementById("text"); // Gets the <p>
var txt = paragraph.innerText; // Gets the text it contains
var textToReplace = 'room' // Word to be replaced
var replace = RegExp(textToReplace, 'g');
var matches = txt.matchAll(replace); // Gets all places where the text matches the word
var replacementPositions = [0, 2]; // Occurences which should be highlighted
var i = 0; // Which match this is; starts at 0
for (const match of matches) { // For each match...
var text = match[0]; // The matching text
var start = match.index; // Start position
var end = match.index + text.length; // End position
if (replacementPositions.includes(i)) { // If it should be replaced (in the replacementPositions array)
var startText = txt.substring(0, start - 1); // Text before match
var endText = txt.substring(start); // Text after match
endText = endText.substring(text.length); // Removes matching text from the text after the match
txt = startText + '<span class="highlight">' + text + '</span>' + endText; // Insert the match back in, wrapped in a <span>
}
i++; // Increment
}
paragraph.innerHTML = txt; // Set the paragraph text back
.highlight {
background-color: yellow;
}
<p id="text">First: room. Another one: room. Last time: room</p>
The first method detects all occurrences of the word and wraps them in a <span>. The <span> has a style that sets the background color of the text, so it looks 'highlighted'.
The second method goes through every occurrence of the word and checks if it should be highlighted. If so, it does some operations that wrap that occurrence in a <span>, like the method above.
Say for example I have the words below
THIS TEXT IS A SAMPLE TEXT
I am given character index 7.
Then I have to return index 1 when I split the sentence into words which is the index of the word that contains the index of character not 5 which matches the word that composes the index of character exactly but not the correct index where character lies.
basically I am trying to return the correct word index of where character lies (when split into words) with character index (when split with characters)
I thought I would reconstruct the word with something like below to find the word at the character
let curString = 'find a word from here';
let initialPositin = 5
let position = initialPositin
let stringBuilder = '';
while(position > -1 && curString.charAt(position) !== ' '){
console.log('run 1')
console.log(position);
stringBuilder = curString.charAt(position) + stringBuilder;
position --;
}
console.log(stringBuilder)
position = initialPositin + 1;
while(position < curString.length && curString.charAt(position) !== ' '){
console.log('run 2')
stringBuilder += curString.charAt(position);
position ++;
}
console.log(stringBuilder);
Then split the sentence into words then find all the index of the word that contains the word that I have constructed. Then go through all the found words and reconstruct the previous words to see if the index of the target character in the reconstruction matches the character position given.
It doesn't really feel efficient. Does anyone have better suggestions?
I prefer javascript but I can try to translate any other language myself
I think you could just count spaces that occurs before given index, something like
let curString = 'find a word from here';
let givenIndex = 9;
let spaceIndex = 0;
for (var i = 0; i < curString.length; i++) {
if(curString.charAt(i) == ' ') {
if (i < givenIndex) {
spaceIndex++;
} else {
// found what we need
console.log(spaceIndex);
}
}
}
Maybe you could build a function that returns the position of all spaces.
Then you can see where the character index fits in that list of space positions.
text = "THIS TEXT IS A SAMPLE TEXT"
indexes = []
current_word = 0
for i in range(0, len(text)):
if text[i] == ' ':
current_word += 1 # After a ' ' character, we passed a word
else:
indexes.append(current_word) # current character belongs to current word
You can build indexes array for once with this piece of code(written in Python3) then you can use it for every indice. If you want to count ' ' characters in indexes array as well, you can simple add them in for loop(in if statement).
I ended up using below code
let content = 'THIS IS A SAMPLE SENTENCE';
let target = 13;
let spaceCount = 0;
let index = 0;
while(index < target) {
if (content.charAt(index) === ' ') {
spaceCount++;
}
index++;
}
let splitContent = content.split(' ');
splitContent[spaceCount] = '#' + value
console.log(splitContent.join(' '))
Worked very nicely
Just like the answer from #miradham this function counts the spaces before the given index, but with builtin functions to count character occurrences.
function wordIndexOfCharacterIndexInString(index, string) {
const stringUpToCharacter = string.slice(0, index)
return (stringUpToCharacter.match(/ /g) || []).length
}
console.log(wordIndexOfCharacterIndexInString(7, "THIS TEXT IS A SAMPLE TEXT"))
I have a script which is almost complete but I can't figure out the last bit here. The script is meant to limit the amount of words that can be entered into a text area and if they go over the word limit these extra words are removed. I have the amount of words beyond the max labeled as overage. For instance, if you were to enter in 102 words, then the overage would be 2. How would I remove those two words from the text area?
jQuery(document).ready(function($) {
var max = 100;
$('#text').keyup(function(e) {
if (e.which < 0x20) {
return;
}
var value = $('#text').val();
var regex = /\s+/gi;
var wordCount = value.trim().replace(regex, ' ').split(' ').length;
if (wordCount == max) {
// Reached max, prevent additional.
e.preventDefault();
} else if (wordCount > max) {
<!--Edited to show code from user3003216-->
<!--Isn't working like this, textarea doesn't update.-->
var overage = wordCount - max;
var words = value.split(' ');
for(var i = 0; i<overage; i++){
words.pop();
}
}
});
});
The easiest way to approach this is just to count the number of words on keypress and go from there. Check whether there are more words than the amount allowed. If so, remove all the excess words: while (text.length > maxWords). Then just replace the value of the text box with the updated text.
fiddle
JavaScript
var maxWords = 10;
$("#myText").keypress(function (event) {
var text = $(this).val().split(" "); // grabs the text and splits it
while (text.length > maxWords) { // while more words than maxWords
event.preventDefault();
text.pop(); // remove the last word
// event.preventDefault() isn't absolutely necessary,
// it just slightly alters the typing;
// remove it to see the difference
}
$(this).val(text.join(" ")); // replace the text with the updated text
})
HTML
<p>Enter no more than 10 words:</p>
<textarea id="myText"></textarea>
CSS
textarea {
width: 300px;
height: 100px;
}
You can easily test whether it works by pasting more than maxWords—in this case, 10—words into the textarea and pressing space. All the extra words will be removed.
You can put below code into your else if statement..
else if (wordCount > max) {
var overage = wordCount - max;
var words = value.split(' ');
for(var i = 0; i<overage; i++){
words.pop();
}
}
And if you want to get your string back from that words, you can use join like below:
str = words.join(' ');
well it would be better to use java script so here you go:
var maxWords = 20;
event.rc = true;
var words = event.value.split(" ");
if (words.length>maxWords) {
app.alert("You may not enter more than " + maxWords + " words in this field.");
event.rc = false;
}
jsFiddle Demo
You can use val to re-value the text-box. The array slice method will allow you to pull the first 100 words out of the array. Then just join them with a space and stick them back in the text-box.
$(document).ready(function($) {
var max = 100;
$('#text').keyup(function(e) {
if (e.which < 0x20) {
return;
}
var value = $('#text').val();
var words = value.trim().split(/\s+/gi);
var wordCount = words.length;
if (wordCount == max) {
// Reached max, prevent additional.
e.preventDefault();
} else if (wordCount > max) {
var substring = words.slice(0, max).join(' ');
$("#text").val(substring + ' ');
}
});
});
While you've already accepted an answer I thought I might be able to offer a slightly more refined version:
function limitWords(max){
// setting the value of the textarea:
$(this).val(function(i,v){
// i: the index of the current element in the collection,
// v: the current (pre-manipulation) value of the element.
// splitting the value by sequences of white-space characters,
// turning it into an Array. Slicing that array taking the first 10 elements,
// joining these words back together with a single space between them:
return v.split(/\s+/).slice(0,10).join(' ');
});
}
$('#demo').on('keyup paste input', limitWords);
JS Fiddle demo.
References:
JavaScript:
Array.prototype.join().
Array.prototype.slice().
String.prototype.split().
jQuery:
on().
val().
I have a string
var string = "mario rossi laureato";
and I have only 15 characters available to write in a td of a table.
so the expected results should be this:
<td id="firstTD">mario rossi</td> //this td has 15 characters available
<td id="secondTD">laureato</td>
fifteenth place intersects the word "laureato", so it's calculated the excess , and takes the previous word.
another example:
var string2 = "hello my name is Paolo"
so the expected results should be this:
<td id="firstTD">hello my name</td> //this td has 15 characters available
<td id="secondTD">is Paolo</td>
fifteenth place intersects the word "is", so it's calculated the excess , and takes the previous word.
Guys any idea about this?
Try this: http://jsfiddle.net/Zh8RR/
// Sample string, to make it easy to see the cut points I've use 1-15 in hex to give us a nice easy way to see the breaks
var string = "1234567 9ABCDE 12345 7 89AB 123456 89ABC E 12 45 789A CD 123";
// Break input string up into words
var parts = string.split(' ');
var sections = [""];
var rows = 0;
// For each word
for (var i = 0; i < parts.length; ++i) {
// If it makes the section too long push it to the next section:
if (sections[rows].length + parts[i].length + 1 > 15) {
rows++;
}
// If we have no text initialise it to be the current word
if(!sections[rows]) {
sections[rows] = parts[i];
} else {
// Otherwise use a space as a separator and concat them.
sections[rows] += " " + parts[i];
}
}
// Write them out to a sample div so we can check.
$('div').html(sections.join("<br />"));
you could do:
var str = "mario rossi laureato";
var strArr = str.match(/.{1,15}/g);
console.log(strArr.length);
for(var s=0,slen=strArr.length; s < slen; s++) {
console.log(strArr[s]);
//create td and append or append strArr[s] to existing td
}