Wrapping a text on arbitrary non-whitespace characters - javascript

I have long namespaces to be displayed in my articles (like MyProject\Sub\Level) and I want them to be wrapped on a backslash character (\) if the window width is insufficient. How can I implement this using CSS or JS/jQuery?

To tell browsers that a line break is permitted after a character, insert the ZERO WIDTH SPACE (ZWSP) character, U+200B, after the character. In HTML markup, you can use the character reference `​', e.g.
MyProject\​Sub\​Level
If you add the characters via scripting, you can enter the character itself, using the string literal \u200b.
Some old browsers (IE 6) used to have problems with this, but now this approach seems to work better than the alternative, the old <wbr> tag (which was well-supported but has now been messed up in new versions of IE).

Use the following css in the element that contains the text:
word-wrap: break-word;
It's a css3 property supported in modern browsers: Google Chrome 6, Internet Explorer 8, Firefox 3, Opera 10 y Safari 5.
Acclaration: It won't break on / character only, it could break on any character of the word according to the stretching of container.

One option is to use the soft-hyphen (­) around the \ characters; the soft-hyphen allows a word to break at a given point, appearing only if the word does, in fact, break at that point.
It also doesn't appear in the text if it's copied and pasted (tested in Chromium 19/Ubuntu 11.04); this approach uses replace() and jQuery's html() method with the following HTML:
<ul>
<li>\some\text\possibly\a\path</li>
<li>\another\path</li>
<li>\something\else\also\quite\long</li>
</ul>​
And CSS:
li {
width: 8em;
border: 1px solid #000;
}​
jQuery:
$('li').html(function(i, h) {
return h.replace(/(\\)/g, '­$1­')
});​
JS Fiddle demo.
Obviously, you don't need to use the soft-hyphen on both sides of the \ character, that was just a demonstration for how it might be used.
An alternative, if you'd rather avoid the appearance of - characters at the break-point, is to use the same approach as above, but instead insert an empty span element, and give it the style display: inline-block;:
jQuery:
$('li').html(function(i, h) {
return h.replace(/(\\)/g, '$1<span></span>')
});​
CSS:
li {
width: 8em;
border: 1px solid #000;
}
li span {
display: inline-block;
}
JS Fiddle demo.
References:
html().
replace().

You could probably follow the example on jQuery - Find and replace text, after body was loaded and have it insert a break following every slash

Related

How to preserve the last carriage return with pre-wrap? [duplicate]

Both of these divs render the same. Why is the leading newline rendered but not the trailing newline (in the second div)? I read the Line Breaking and Word Boundaries section in the CSS3 spec but it doesn't explain this behavior.
.pre {
white-space: pre;
border: 1px solid red;
margin-bottom: 10px;
}
<div class="pre">
hello
world</div>
<div class="pre">
hello
world
</div>
Why? Well, to avoid compatibility problems, apparently.
The W3C says:
In order to avoid problems with SGML line break rules and inconsistencies among extant implementations, authors should not rely on user agents to render white space immediately after a start tag or immediately before an end tag.
and also:
Note that the white space processing rules have already removed any tabs and spaces after the segment break before these checks [on the value of the white-space property] take place.
Now it is not clear exactly which inconsistencies would be introduced if the browsers were allowed to keep the whitespace before the end tag, but there you have it.
Because the last \n won't work. And the property white-space: pre works as it's called. It only adds newline before a word. The last \n is not recognized as a word.

Making line numbers uncopyable

I'm working on adding line number support to Rainbow, a syntax highlighter, but I can't figure out how to make the line numbers uncopyable.
Disabling selection via user-select: none; makes an element unhighlightable, but you can still copy its text by highlighting around it and then copying, which ends up copying the line numbers along with code.
Here is a working example of the problem: http://jsfiddle.net/CjJLv/8/
Any help would be appreciated. Thanks!
Okay, the easiest way in compliant browsers, and, sadly, not reliable cross-browser, is to use generated content (I've removed the various parts where index was being added to textual content in the plug-in, and used the following (at the end of the CSS) to implement un-copyable text:
table.rainbow {
counter-reset: line;
}
table.rainbow tbody tr td:first-child {
counter-increment: line;
}
table.rainbow tr td:first-child::before {
content: counter(line);
}
JS Fiddle demo.
This does, though, have some rather large flaws (the cross-browser unfriendly approach being the biggest), so I'll try for something better...
I would just add a regular list.
if (window.Rainbow) window.Rainbow.linecount = (function(Rainbow) {
Rainbow.onHighlight(function(block) {
var lines = $(block).text().split('\n');
var $lines = $('<ul class="lines"/>');
for (var i = 0, len = lines.length; i < len; i++) {
$lines.append('<li class="line"'+ i +'>'+ i +'</li>');
}
$(block).before($lines);
});
})(window.Rainbow);​
And CSS:
.lines {
float: left;
padding-right: 1.5em;
padding-left: .5em;
}
So now you can select just the code if you highlight carefully.
Demo: http://jsfiddle.net/elclanrs/CjJLv/18/
David Thomas's answer is perfect for line numbers. More generally, if you have other text you don't want to be copied, you can have it as generated content:
<style>#uniqueid::before { content: 'TEXT GOES HERE'; }</style>
<span id="uniqueid"></span>
But it's ugly to have to embed text in your CSS, so you can refine this using CSS attr() to read the text from an attribute in the HTML (as suggested by pimvdb):
<style>[data-nocopy]::before { content: attr(data-nocopy); }</style>
<span data-nocopy="TEXT GOES HERE"></span>
<span data-nocopy="AND HERE"></span>
Demo: http://jsbin.com/fob/1/edit
This works in Firefox, Safari, and Chrome due to 21-year-old(!) bugs in selecting generated content:
https://bugzilla.mozilla.org/show_bug.cgi?id=12460
https://bugs.webkit.org/show_bug.cgi?id=7562
https://bugs.chromium.org/p/chromium/issues/detail?id=80466
But in old IE (< 8) the text will be completely invisible; in newer IE it should be visible but may well be copyable. In general don't use this technique for anything critical, as these bugs might get fixed one day...
And use sparingly, as this can be very user-hostile.
You could display each line number as a sequence of <img>s.

How to show line numbers for a code block using JavaScript?

Here's the thing. I use 'Highlight.js' (a javascript-based automatic syntax highlighter) to syntax-highlight code on my website. But it doesn't support line numbers or zebra-striping (for alternate lines of code).
My code block is wrapped in <pre><code> blocks like this:
<pre><code>
<script type="text/javascript">
// Say hello world until the user starts questioning
// the meaningfulness of their existence.
function helloWorld(world) {
for (var i = 42; --i >= 0;) {
alert('Hello ' + String(world));
}
}
</script>
<style>
p { color: pink }
b { color: blue }
u { color: "umber" }
</style>
</code></pre>
And the output looks like this:
Now I want to show line numbers for the code block dynamically using JavaScript. How do I do that? (Also, if possible, how do I show zebra-striping?)
Thanks.
PS: I don't know JavaScript, so please try to be as clear as possible. I will try my best to understand. Thanks.
You could use an alternate framework such as http://alexgorbatchev.com/SyntaxHighlighter/
Or take a look here and find something that suites.
http://www.1stwebdesigner.com/css/16-free-javascript-code-syntax-highlighters-for-better-programming/
The basic steps would be:
Take the HTML inside the element.
Split by newline characters (\n).
For each string, add a number and a dot in front of it.
Combine the strings again with newline characters.
Set the string as the HTML of the element.
However, this would mess up the syntax highlighting of the syntax highlighter because it most likely won't recognize that the code has line numbers in front. So the syntax highlighter needs to provide the functionality of line numbers for you.
Adding a new answer to an old question.
I wanted to display line numbers in the left margin the way ace.js does.
My solution has some hacky details, but I wanted to share it anyway, because it turns out that absolute-positioned spans within relative-positioned spans work pretty well for this.
Encouraged by the above answers and this answer about relative positioning without taking up space, I used:
var line = 1;
code = code.replace(/^/gm, function() {
return '<span class="line-number-position">​<span class="line-number">' + line++ + '</span></span>';
});
The regular expression /^/gm "replaces" the beginning of each line with the span-within-span.
​ is a zero-width space, because apparently firefox seems to have trouble deciding whether to put a zero-height span at the top or the bottom of the character.
line-number-position and line-number are CSS classes like these:
.line-number-position {
position: relative;
top: 0;
}
.line-number {
position: absolute;
text-align: right;
right: 17px;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
font-size: 12px;
}
Yes, there are some magic numbers in there to match ace formatting, but the point is to put a relative-positioned zero-sized span at the beginning of each line and use it as a reference point to add an absolute-positioned span out in the left margin.
Works on current Chrome, Safari, Firefox, and Opera.

sIFR 3 Leading and Kerning

I am trying to get leading and kerning to work on some sIFR 3 type on a site I'm working on (as described in the wiki: http://wiki.novemberborn.net/sifr3/Styling), but these two parameters seem to have no effect no matter what I do.
I am not using intergers (no 'px' or 'em') just as it requires. I've also tried several different font swf files, just to make sure it's not the font. I don't know why it doesn't work. All of the other css parameters that I assign to .sIFR-root work just fine. Here's a sample of my code using 'leading'.
In sifr_config.js:
sIFR.replace(snl, {
selector: '.section-title h1',
css: ['.sIFR-root { color: #FFFFFF; text-align: center; leading:2; }'],
wmode: 'transparent'
});
In the HTML doc:
<div class="section-title">
<h1>sIFR Text</h1>
</div>
(I've also tried the css code with and without the square brackets, as I've seen it done both ways. Doesn't seem to make a difference).
What am I doing wrong? Any help would be greatly appreciated; thanks!
ETA: Found an less hackish way:
line-height seems to work when added to the CSS for the replaced element (in my example that'd be: .sIFR-active .section-title h1). So I was able to use regular old line-height to fake a margin.
All righty—since this one left everyone speechless, here's what I discovered:
Originally, there were many suggestions for using leading as a replacment for margin-top or padding-top since these will not work with sIFR. This is what I was trying to use it for. I had a single line of text and needed to give it some space up top, so I was trying to do this by increasing the leading (line height) to no avail. I think this worked at one point, but then as I was looking at the change logs for all the revisions of sIFR, I found a note about a "fix" to leading. Apparently the developer considered leading being recognized on single-line text as a bug, so "fixed" it so that leading is only applied when the text is multiple lines. I tested by putting a line-break before my text, and sure enough, leading started to work!
So it seems that now, in order to achieve a top margin on my sIFR header, I have to add unneccessary code one way or another—by wrapping it in a div or span with a top margin, or by adding a line break and using negative leading.
I still have no idea about the kerning, but letter-spacing seems to be working, so…
If anyone has any additional insight to offer, I'm all ears!
Here's what works for me, using sIFR 3 to get a h2 with Serifa font in red with minimal letter spacing and leading. The actual sIFR swf is nothing special, simply created as per the sIFR documentation. As mentioned above, offsetTop and tuneHeight also work for adjusting positioning (shown below although I haven't used them so set to 0).
In sifr.css
.sIFR-active h2.replace {
color: #FF0000;
visibility: hidden;
font-family: arial,helvetica,clean,sans-serif;
font-size: 2.5em;
text-transform:uppercase;
}
in sifr-config.js
sIFR.replace(serifa, {
selector: 'h2.replace',
css: ['.sIFR-root { letter-spacing: -2; leading: -15; kerning:true; color:#FF0000; text-transform:uppercase; font-size:2.5em; }' ],
tuneWidth: '0' , tuneHeight: '0' , offsetTop: '0' });
In html page (for example):
<div class="column grid_4">
<h2 class="replace">Title here</h2>
</div>

Break long text

I have a div which has width of say 200px. It does not show horizontal scroll bar. Now if anyone types any word more than 200px worth, it is simply hidden. I am wondering if its possible to automatically put a newline tag after every word reaches 200px length?
Thank you for your time.
You can achive this using simple CSS using
WORD-BREAK: break-ALL.
<div style="width: 200px; word-break: break-all">Content goes here</div>
Hope this is what you were looking for...
It's a tricky problem, but you should probably read http://www.quirksmode.org/oddsandends/wbr.html.
basically, there is somewhat inconsistent support and the linked article proposes use of:
wbr:after { content: "\00200B" }
in your css, and using the <wbr/> tag in your html
There is a soft-hyphen that lets you define where a word can be broken up (For example, prod-uct-iv-ity) which doesn't display any hyphens, just defines where they could show up if the word has to wrap lines. It is entity ­
If you have mono-spaced font, it'd be easy to count number of characters, and just insert a break-tag. But it's harder to calculate where to put in the break-tag with normal fonts.
For IE, you can set word-break: break-all; which will break words when they reach a certain length...
word-break is good, but it is said not to work in firefox. (haven't tested.)
For firefox, use javascript.
It does work in webkit though.

Categories

Resources