Constructing a web-reading aid: row selector - javascript

I've been trying to make a row-marking script to help me read text online. When I read books I always use a ruler or paper. Online, I don't have this option and usually get lost in text.
W - move div up
S - move div down
JS fiddle for my current effort (S = down, W = up)
The best thing I could come up with is to have equal row height for all text-elements, but makes styling quite hard. Also, I would like to be able to run it in the console to enable it on any website (or install it as a add-on).
Is there some better way to design a tool like this, that makes it more capable and adaptive to unknown content?
I can of course select text and I do that a lot. Usually, it results in me selecting only some words-> attention goes to that word, which is kind of what I want to avoid.
I could also use a secondary window, which I do sometimes. But it's a bit wobbly and as soon as you click it disappears.
A div that follows mouse-pointer is a possibility, but it's too shaky and feels like something got stuck on your finger.
EDIT: I updated the fiddle with the changes. I kept the javascript because without it you won't be able to move the ruler to the lower parts of the text.
Updated reading-ruler

Instead of JavaScript you could set a position: fixed for the .ruler. It will stay in the same place all the time so you can read the text with the .ruler element below it.
Here is the jsFiddle. http://jsfiddle.net/RxDpP/1/

Related

Javascript retrieve linebreaks from dom [duplicate]

I need to add line breaks in the positions that the browser naturally adds a newline in a paragraph of text.
For example:
<p>This is some very long text \n that spans a number of lines in the paragraph.</p>
This is a paragraph that the browser chose to break at the position of the \n
I need to find this position and insert a <br />
Does anyone know of any JS libraries or functions that are able to do this?
The only solutuion that I have found so far is to remove tokens from the paragraph and observe the clientHeight property to detect a change in element height. I don't have time to finish this and would like to find something that's already tested.
Edit:
The reason I need to do this is that I need to accurately convert HTML to PDF. Acrobat renders text narrower than the browser does. This results in text that breaks in different positions. I need an identical ragged edge and the same number of lines in the converted PDF.
Edit:
#dtsazza: Thanks for your considered answer. It's not impossible to produce a layout editor that almost exactly replciates HTML I've written 99% of one ;)
The app I'm working on allows a user to create a product catalogue by dragging on 'tiles' The tiles are fixed width, absolutely positioned divs that contain images and text. All elemets are styled so font size is fixed. My solution for finding \n in paragraph is ok 80% of the time and when it works with a given paragrah the resulting PDF is so close to the on-screen version that the differences do not matter. Paragraphs are the same height (to the pixel), images are replaced with high res versions and all bitmap artwork is replaced with SVGs generated server side.
The only slight difference between my HTML and PDF is that Acrobat renderes text slightly more narrowly which results in line slightly shorter line length.
Diodeus's solution of adding span's and finding their coords is a very good one and should give me the location of the BRs. Please remember that the user will never see the HTML with the inserted BRs - these are added so that the PDF conversion produces a paragraph that is exactly the same size.
There are lots of people that seem to think this is impossible. I already have a working app that created extremely accurate HTML->PDF conversion of our docs - I just need a better solution of adding BRs because my solution sometimes misses a BR. BTW when it does work my paragraphs are the same height as the HTML equivalents which is the result we are after.
If anyone is interested in the type of doc i'm converting then you can check ou this screen cast:
http://www.localsa.com.au/brochure/brochure.html
Edit: Many thanks to Diodeus - your suggestion was spot on.
Solution:
for my situation it made more sense to wrap the words in spans instead of the spaces.
var text = paragraphElement.innerHTML.replace(/ /g, '</span> <span>');
text = "<span>"+text+"</span>"; //wrap first and last words.
This wraps each word in a span. I can now query the document to get all the words, iterate and compare y position. When y pos changes add a br.
This works flawlessly and gives me the results I need - Thank you!
I would suggest wrapping all spaces in a span tag and finding the coordinates of each tag. When the Y-value changes, you're on a new line.
I don't think there's going to be a very clean solution to this one, if any at all. The browser will flow a paragraph to fit the available space, linebreaking where needed. Consider that if a user resizes the browser window, all the paragraphs will be rerendered and almost certainly will change their break positions. If the user changes the size of the text on the page, the paragraphs will be rerendered with different line break points. If you (or some script on your page) changes the size of another element on the page, this will change the amount of space available to a floating paragraph and again - different line break points.
Besides, changing the actual markup of your page to mimic something that the browser does for you (and does very well) seems like the wrong approach to whatever you're doing. What's the actual problem you're trying to solve here? There's probably a better way to achieve it.
Edit: OK, so you want to render to PDF the same as "the screen version". Do you have a specific definitive screen version nominated - in terms of browser window dimensions, user stylesheets, font preferences and adjusted font size? The critical thing about HTML is that it deliberately does not specify a specific layout. It simply describes what is on the page, what they are and where they are in relation to one another.
I've seen several misguided attempts before to produce some HTML that will exactly replicate a printed creative, designed in something like a DTP application where a definitive absolute layout is essential. Those efforts were doomed to failure because of the nature of HTML, and doing it the other way round (as you're trying to) will be even worse because you don't even have a definitive starting point to work from.
On the assumption that this is all out of your hands and you'll have to do it anyway, my suggestion would be to give up on the idea of mangling the HTML. Look at the PDF conversion software - if it's any good it should give you some options for font kerning and similar settings. Playing around with the details here should get you something that approximates the font rendering in the browser and thus breaks lines at the same places.
Failing that, all I can suggest is taking screenshots of the browser and parsing these with OCR to work out where the lines break (it shouldn't require a very accurate OCR since you know what the raw text is anyway, it essentially just has to count spaces). Or perhaps just embed the screenshot in the PDF if text search/selection isn't a big deal.
Finally doing it by hand is likely the only way to make this work definitively and reliably.
But really, this is still just wrong and any attempts to revise the requirements would be better. Keep going up one step in the chain - why does the PDF have to have the exact same ragged edge as some arbitrary browser rendering? Can you achieve that purpose in another (better) way?
Sounds like a bad idea when you account for user set font sizes, MS Windows accessibility mode, and the hundreds of different mobile devices. Let the browser do it's thing - trying to have exact control over the rendering will only cause you hours of frustration.
I don't think you'll be able to do this with any kind of accuracy without embedding Gecko/WebKit/Trident or essentially recreating them.
Maybe an alternative: do all line-breaks yourself, instead of relying on the browser. Place all text in pre tags, and add your own linebreaks. Now at least you don't have to figure out where the browser put them.

contentEditable insert br when new line occurs

A contentEditable has automatic word wrapping, creating a new line when you reach the width of the editable area. This is great but I am parsing the contents of this afterwards and I need it to add a <br> when it does this. I have tried everything I can think of and I can't achieve this. Any help greatly received.
This is not possible, the word wrapping point is 'browser discretion' and as such susceptible to font size differences, fonts not being installed, font render engines, anti-aliasing settings etc. etc. The line-wrap point is, so to speak, 'not your problem' from the browser's perspective, and as such it doesn't give this info away.
Theoretically you could rebuild the content word-for-word in JS in a dynamically sized and similarly styled div, and monitor for when the height changes - that's where the newlines occur. It'd be a crap load of crappy code to achieve a dodgy result though.
I can't help but feel like you're asking for an XY-solution here - if you need newlines at the given point, let the end user give them when he wants to. Simply adding overflow:auto;white-space:nowrap to the editable element forces them to. Example here.

Building a DOS-feel script. How to make the command line?

I always had the idea to make a textarea based program, that gets the last line and uses it as a command. So it looks like some cool DOS-like program.. But in fact is simple textarea -> AJAX -> PHP -> textarea again. Textarea based version works great, but has alot of drawbacks. Mostly related to not getting the right command and possible vulnerabilities to the script.
So, my idea is to use a output container and command line totally separately. I found a good example of what I want, but I cannot figure out, how it is actually made. The main idea is that the hole thing feels like one block of text and you can highlight it:
But you actually cant delete the prompt (c:>) or the already outputted text above.. Since the command line is an actual input.
I don't understand, how this effect is being achieved. You can see the above examples source code, it is basically:
<div id="black_wrapper">
<div id="outputted_code"></div>
<span id="prompt">c:\></span><span id="commandline"></span><span id="blinker"></span>
<input type="text" name="actual_commandline" value="" />
</div>
And the JavaScript behind it is: http://pastebin.com/pjbd9Y7k
How can I merge the spans line with the input, so it works like one line, but you cannot manipulate the span#prompt or span#blinker contents?
It is very hard to find any help on www for such localized problems. I can see some CSS in the example-link above..however my knowledge of CSS tells me, that it has nothing to do with that layout.
Also, I drew out exactly what I'm thinking to do, as it is very hard to explain these types of technical questions:
Red = General wrapper, not much function
Blue = Prompt area, very static
Green = Writing area, expands its width when typing, pushing the blinker more to the right
Purple = Blinker container, simple gif animation that looks like this:
Note: I'm not actually ripping-off that example site, but well only that command-line layout. Any hint, link code or idea is welcome. It can be totally alternative, but should achieve the goal, thanks :)
Edit: The question got solved thanks to Joe. However, since the original idea might interest somebody in the future.. I will include a small picture, of what my script looks like. Maybe this inspires some of you someday :)
What he's doing is hiding a textbox off-screen. The actual command line is just an element styled to have 1 line's worth of height. When you click this command line, the textbox takes focus.
The C:\> and _ sandwich the textarea, so your text appears in between, thus increasing the width on the command line element as you type, and pushing the _ to the right, giving the illusion that it moved on its own.
http://jsfiddle.net/YeR3L/1/

Ebook in iOS using CSS multi-column (calculate range of text in different column)

My first question here. Correct me if I've done anything wrong.
I've found a source here demonstrate how to paginate html using CSS multi-column.
http://groups.google.com/group/leaves-developers/browse_thread/thread/27e4bf5ff3c53113/f137dc01b6d853b7
My question is:
How to calculate the range / location of text in different column (page)?
For example, when changing the font size,
the text in current page will jump to another page.
To solve this, the program should save the current text location,
and move to the correct page (column) after reformatting the web page.
It is also useful for implementing bookmark function.
I think it should be done by javascript, but I'm new to javascript.
Any suggestions and tips are welcomed.
This is a bit of a general question, and very hard to answer, so I'll just try to point you in a direction I might try.
I have no idea how the layout of your page might look or function, but one way you could theoretically do this is by checking the text node of your 'column' whenever you change the font-size (presuming this font size change is implimented by a button click). So, for instance, say you have a div w/ the id #column_1, whenever someone clicks the button ui element you could evaluate the first several characters of #column_1, then search your string to find that text, and load whatever no. of characters you have defined as a 'page' around that text and call your render method to 'turn' to that page. So the flow of your function might look something like this:
zoomControl.click(click event){ //do something when you click the zoom control
var text = findTextofCurrentPage() //get the first bit of text of your current 'page'
renderLargerTextSize() //re-render your 'page' w/ larger text (for user feedback purposes)
renderPageWith(text) //render/navigate to the 'new' page wherein your the text in the variable 'text' can be found
}
Obviously this is a super generic 'idea' of what functions/methods you might use to make this happen, but I think if you dug into JS and say something like JQuery this sort of thing could be done relatively easily.

Automatic multi-page multi-column flowing text with QtWebkit (HTML/CSS/JS -> PDF)

I have some HTML documents that are converted to PDF, using software that renders using QtWebkit (not sure which version).
Currently, the documents have specific tags to split into columns and pages - so whenever the wording changes, it is a manual time-consuming process to move these tags so that the columns and pages fit.
Can anyone provide a way to have text auto-wrapped into the next column/page (as appropriate) when it reaches the bottom of the current container?
Any HTML, CSS or JS supported by QtWebkit is ok (assuming it works in the PDF converter).
(I have tested the webkit-column-* in CSS3 and it appears QtWebkit does not support this.)
To make things more exciting, it also needs to:
- put a header at the top of each page, with page X of Y numbering;
- if an odd number of pages, add a blank page at the end (with no header);
- have the ability to say "don't break inside this block" or "don't break after this header"
I have put some quick example initial markup and target markup to help explain what I'm trying to do.
(The actual documents are far more complicated than that, but I need a simple proof-of-concept before I attack the real ones.)
Any suggestions?
Update:
I've got a partially working solution using Aaron's "filling up" suggestion - I'll post more details in a bit.
Create a document with a single page and all the text in a single column. Use JavaScript to cut the text into parts.
Use pixel coordinates to locate the paragraph/element that doesn't fit anymore. Move it and everything below to the next col. If a "page" already has two "col" divs, start a new page.
After all pages have been created, count and number the pages. Fix even/odd stuff, etc.
Will take some time but it's automatic.
Another approach would be to add all the content to a "source" div and move items to the col div until it's full and repeat with the next col.
Have a look at Prototype or jQuery; they should give you lots of tools to move stuff around in the document.
[EDIT] Instead of only relying on jQuery functions, I suggest to create one or two objects which keep track of the current page and the current column, etc. These give you stable foundations to stand on from which you can fire the helper methods.

Categories

Resources