How to truncate complex html by lines - javascript

I am trying to truncate complex html by lines in order to be able to display a show more link after a certain number of lines has been reached. I found a great library trunk8.js which truncates by lines..but if falls short when it comes to truncating complex html. So for my particular case I overrode the truncate function so that I can handle complex the using another truncation function which gracefully leaves complex html tags intact. Truncation will work great with html but I am stuck on how to accurately calculate where to put show more more based on the number of lines
As seen in the image above I am trying to truncate to 7 lines but if the user input contains white spaces shown in yellow my calculations will be wrong because I am not accounting for the white spaces. My initial line of thought was that if I can calculate the length of the spaces in yellow for each line and convert it to characters, I can add this offset to the maximum number number of characters, then I can know where to put approximately the show more link. Is this the best approach to this problem and if not ,any suggestions to make my life easier.
This is a plunker of what I have tried so far and I am stuck in my truncateHTML() function in the trunk8.js where I am only now truncating based on the maximum length of the string.

Eureka!! After a couple of google searches and heavy debugging sprints, I stumbled upon a library truncate.js which I customized the truncatedNestednode() function for my needs.
element.appendChild(child);
/** Customized--here **/
var clonedNode = {};
if ($clipNode.length) {
if ($.inArray(element.tagName.toLowerCase(), BLOCK_TAGS) >= 0) {
// Certain elements like <li> should not be appended to.
$element.after($clipNode);
}
else
{ //Removed the commented line to put showmore next to the last line of text
$element.prev().append($clipNode);
//$element.append($clipNode);
}
}
In case someone faced this problem in the past, I have posted my revised plunker here

Related

How to calculate unsaved changes in Code Mirror

I use a CodeMirror for displaying code on the HTML page. I have a version of the code which was saved in BD and when a user edits it in CodeMirror, I want to highlight unsaved changes like Visual Studio Code does:
I know that I can use method: codeMirror.removeLineClass(line, 'gutter', 'my_class'); to add a border that shows that changes were done at the specific line. My problem is in the calculation of the changed lines. I tried to use diff and diff2html packages and calculates changes like this:
var diff = Diff.createTwoFilesPatch('some name', 'some name', cm.state.savedText, cm.getValue());
var diffInfo = Diff2Html.getJsonFromDiff(diff, options);
This approach gives me a diff and I can get changed lines from it:
But this solution has a performance problem - it works slowly if a text contains more than 40 lines, and I will have large texts in CodeMirror.
I also tried to use history (the structure that codeMirror.getDoc().getHistory() returns) and highlight lines that are stored in 'changes' array, but it works only for new lines which were added. This approach doesn't work if the user removes the line.
What is the right way of calculation for such changes?
I was thinking of using the change event and tracking a specific change("+delete",
"+input"), then collect changed lines in special array. But this solution looks painful because in this case, I need to update this array manually if lines were added/deleted in the next iteration.
Is there a simpler way of how to do it?
After some research I've realized that even for big texts (~12 000 lines) approach with calculating the diff still works:
var diff = Diff.createTwoFilesPatch('some name', 'some name', cm.state.savedText, cm.getValue());
var diffInfo = Diff2Html.getJsonFromDiff(diff, options)
It takes ~30ms to calculate the diff for big text, and 5-6ms for small ones (~100lines). So for now it seems the most simple way for highlighting updated lines.

Is there a way to cut off a part of a decimal in Javascript?

I have a number that increases every second by addition. The problem is that it contains way too many decimals. An example of an output which I do not want would be something like 1.5999999999999999 or 1.600000000001. I have tried using the toFixed method, passing in 2 as it's value, and I am still getting the issue. I have also tried using the Math.round(number * 100) / 100 and am still getting uggly decimals.
How can I get an output that only contains a specified number of decimal points? I want to be able to choose how the number rounds. The function to round should be something like this:
function round(numberToRound, afterDecimals){
//Rounding code which takes into the account the number of decimal values I wish to display should go here
}
Thank you.
I am so sorry, I didn't call the function in the right place. The function works as expected, I just wasn't updating the innerHTML correctly.
Again, I am sorry for overlooking this.

Numbers from inside a string without regex?

I'm making a bot for a gaming chatroom with some friends, but I've hit an impasse. Is there a reliable way to get numbers from inside a string of text that won't completely break an inexperienced script kiddy's brain? Here's the best I've been able to come up with so far, variables simplified slightly for illustration's sake:
var k = [0];
function dieRoll(m,n) {
for(i = 0; i < m; i++) {
k[i] = Math.floor(Math.random()*n)+1;
}
}
var m = text[5];
var n = text[7];
if (text === 'roll '+m+'d'+n) {
dieRoll(m,n)
console.log(k);
}
The biggest problem as-is is that it's limited to single-digit input.
EDIT: Looping through the text looking for integers is exactly the kind of thing I'm looking for. I don't have much experience with programming, so I probably tend to end up with overly complicated and confusing messes of spaghetti code that would embarrass anyone remotely professional. As for the format of the input I'm looking for, "roll [number of dice]d[highest number on the dice]". For anyone who doesn't know, it's the notation most tabletop rpgs use. For example, "roll 2d6" for two normal six-sided dice.
EDIT: It's not that I'm necessarily against regex, I just want to be able to understand what's going on, so that if and when I need to edit or reuse the code it I can do so without going completely insane.
EDIT: Thank you all very much! split() seems to be exactly what I was looking for! It'll probably take some trial and error, but I think I'll be able to get her working how she's supposed to this weekend (Yes I call my bots 'she').
Basically, you need to look at the format of the input you're using, and identify certain facts about it. Here are the assumptions I've taken based on your question.
1) The "roll" command comes first followed by a space, and
2) After the command, you are provided with dice information in the form xdy.
Here's something that should work given those constraints:
function getRollParameters(inputCommand) {
var inputWords = inputCommand.split(' '); //Split our input around the space, into an array containing the text before and after the space as two separate elements.
var diceInfo = inputWords[1]; //Store the second element as "diceInfo"
var diceDetails = diceInfo.split('d'); //Split this diceInfo into two sections, that before and after the "d" - ie, the number of dice, and the sides.
//assign each part of the dicedetails to an appropriate variable
var dice = diceDetails[0];
var sides = diceDetails[1];
//return our two pieces of information as a convenient object.
return {
"dice": dice,
"sides": sides
};
}
//a couple of demonstrations
console.log(getRollParameters("roll 5d8"));
console.log(getRollParameters("roll 126d2"));
Effectively, we're first splitting the string into the "command", and the "arguments" - the information we want. Then, we split our arguments up using the "d" as a midpoint. That gives us two numbers - the one before and the one after the d. Then we assign those values to variables, and can use them however we like.
This obviously won't deal with more creative or flexible inputs, and isn't tested beyond the examples shown but it should be a decent starting point.

Line wrapping in javascript/appcelerator

How can i determine the number of lines in a <textarea> based on line wrapping ?
( There are no new line characters to be detected. )
Basically, I need a way to programmatically determine the average width of characters in the text area, so I can determine where it wraps (and determine the number of lines in this <textarea>).
This is for an application using Appcelerator
SimpleCoder, a SO member, developed a plugin that tackles this same issue. You can find a description of it as well as a link to the plugin at the article below:
Textarea Line Count
Usage:
var result = $.countLines("#yourTextArea");

Character Counter Super Slow - jQuery

I wrote this:
$('[name=item-title]').live('keyup',function(k){
char_limit=parseInt($('[data-charlimit]').attr('data-charlimit'));
total = char_limit-parseInt($(this).val().length);
$('.charcount span').text(char_limit-parseInt($(this).val().length));
});
But after the first few words it starts going super slow where I'll type and the words will show a millisecond after. If i get to like 250 words it gets nearly 3/4 of a second behind it seems. Any ideas why? To me what i wrote seems fairly minimal...
You're doing a DOM traversal per character and you're not sure why it's slow?
// calculate upper limit once -- it won't change, presumably
var char_limit=parseInt($('[data-charlimit]').attr('data-charlimit'));
$('[name=item-title]').live('keyup',function(k){
// length is already numeric, no need to parse it
var remaining = char_limit - $(this).val().length;
$('.charcount span').text( remaining ); // use the result, note I renamed it
});
If possible, precalculate the char_limit. It won't change during the typing.
Use the total variable in your fourth line, or leave out its calculation completely
Leave out the parseInts except for maybe the first one, they're useless.
This would give you
var char_limit=parseInt($('[data-charlimit]').attr('data-charlimit'));
$('[name=item-title]').live('keyup',function(k){
$('.charcount span').text(char_limit-$(this).val().length);
});
I'm not sure if there are multiple char_limits though, as this would ruin those. It seems that your current $('[data-charlimit]') approach doesn't allow for those anyway.

Categories