PHP code line break `\n` causing gap between elements - php

I'm echoing a series of HTML elements using PHP. I'm using \n to cause code line breaks to make the source code more organized and legible.
For some reason, the use of \n in a specific location is causing a mysterious gap between the HTML elements. In firebug, this gap is not showing up as a margin, or padding, but rather just a gap.
Here is the PHP in question:
Note: As you can see, I have removed all of the PHP inside the tags as I'm pretty sure it is not relevant to this problem.
echo '<ul ... >'."\n";
while($row = mysql_fetch_assoc($result_pag_data)) {
echo '<li><a ... >'."\n".
'<img ... >'."\n".
'</a></li>'."\n"; <---- THIS IS THE \n THAT SEEMS TO BE CAUSING THE GAP
}
echo '</ul>'."\n";
Have you ever seen anything like this before, a presentation gap associated with PHP line breaks?
If so, what is the reason for it?
Is it really that important that I use \n in my code?

That's normal. A \n line break has no meaning in HTML, so it's interpreted as a space character. If you don't want that gap, then eliminate the \n, or rewrite the html so it's not relevant:
<li><a ...><img ...></a></li>
As a general rule, tags which can contain text should never have their closing tags on a line by themselves, for this very reason.
Following up on your 'where to put \n' question. This comes down to personal preference, but I tend to format my html like this:
<table>
<tr>
<td><a href="some big long ugly url">
<img ....></a></td>
</tr>
Since <tr> can't contain any text on its own (in valid html), it's ok to put on its own line. But the </a> and </td> are both tags that CAN contain text, so I put them right up against the end of the 'text' (the img tag in this case), so that the Phantom Linebreak Menance (coming soon to a starwars ripoff near you) can't strike.
Note, of course, that my example does have a line break and indentation between the opening <a> and the <img> tag, so that's another place where a "must be right next to each" other layout would cause a gap. If you need a series of things lined up smack dab against each other, than you basically can't use line breaks anywhere in that section of the page.

The whitespace is translated into (empty) HTML text nodes, which take up some space (you can test this by walking the DOM). There is no solution to make these disappear that I know of other than removing the whitespace from your HTML in the first place.
Of course it's not only \n that would cause this behavior; spaces or tabs would do exactly the same as well.

In that particular case the newlines are used to prettify the html source, keep it readable via view-source. That's quite common actually. (Yet redundant.)
As said by the other answers, it does not have meaning normally. Albeit this can be overriden via CSS and the attribute (which we can assume is not the case here):
white-space: pre-line;

You should only output a newline where you in fact want a newline in the output. In HTML, a newline is whitespace, just like the space character.

Related

Replace only on lines which contain no html tags

My knowledge in the RegEx context is still not big enough. The example should demonstrate my problem - I hope. I parse a text and render HTML. Currently, my problem is to set the paragraph markup for each text, paragraph without a markup and a line ending.
An example text:
<h1>Header</h1>\nA simple text with less of words. Yes much more lines.\n<h2>Tests</h2>\nThe solution is still active in his tests.\n
I like to add a simple paragraph <p> markup to each line (before <p> and after </p>), if it is without markup or an empty line, like ''.
The goal of the example below should looks like:
<h1>Header</h1>\n<p>A simple text with less of words. Yes much more lines.</p>\n<h2>Tests</h2>\n<p>The solution is still active in his tests.</p>\n
I'm tried
My current RegEx parse that, but have the problem if I have a line is empty or after an empty line after a tag, like </code>\n.
'#(?![a-z][0-9]).(.*\n)#'
I tried also with negative look for closing the HTML tag like #(?!\>).(.*\n)#.
Online test
https://regex101.com/r/khYWy4/2
Use another tool if you can!
Depending on how you are going to use this, I will recommend that you find a solution which is not based on regex. This task is better solved by iterating the lines in a proper script or program, perhaps the one which generates the html in the first place, and injects the tags you need.
Having said that, I appreciate that sometimes there is no optimal solution.
My attempt to solve yor case
I have updated your example with a substitution which does seem to do what you want.
\n([^<>\n;]+?)\n
Substitute with
\n<p>\1</p>\n
The updated example:
https://regex101.com/r/khYWy4/3
Be aware of a few things here:
I ignore any lines which already contain any html tags.
I ignore any lines which contain a semicolon, to avoid tags in your code block.
Disclaimer!
Depending on what other cases you have may look like, these simple skips were made just to make your example work. I can not guarantee that this will work for a larger set of data.

What does exactly mean by 'Line feeds' in HTML and PHP? How do they are added in HTML and PHP code?

I was reading PHP Manual and I come across following text paragraph :
Line feeds have little meaning in HTML, however it is still a good
idea to make your HTML look nice and clean by putting line feeds in. A
linefeed that follows immediately after a closing ?> will be removed
by PHP. This can be extremely useful when you are putting in many
blocks of PHP or include files containing PHP that aren't supposed to
output anything. At the same time it can be a bit confusing. You can
put a space after the closing ?> to force a space and a line feed to
be output, or you can put an explicit line feed in the last echo/print
from within your PHP block.
I've following questions related to the text from above paragraph :
What does exactly mean by 'Line feeds' in HTML?
How to add them to the HTML code as well as PHP code and make visible in a web browser? What HTML entities/tags/characters are used to achieve this?
Is the meaning of 'Line feed' same in case of HTML and PHP? If no, what's the difference in meaning in both the contexts?
Why the PHP manual is saying in first line of paragraph itself that? What does PHP Manual want to say by the below sentence?
"Line feeds have little meaning in HTML"
How can it be useful to remove a linefeed that follows immediately after a closing tag ?> when someone is putting in many blocks of PHP or include files containing PHP that aren't supposed to output anything?
Please someone clear my above mentioned doubts by giving answer in simple, lucid and easy to understand language. If someone could accompany the answer by suitable working code examples it would be of great help to me in understanding the concept more clearly.
Thank You.
What does exactly mean by 'Line feeds' in HTML?
It is a general computing term.
The character (0x0a in ASCII) which advances the paper by one line in a teletype or printer, or moves the cursor to the next line on a display.
— source: Wiktionary
How to add them to the HTML code
Press the enter key on your keyboard. Note that (with a couple of exceptions like <pre>) all whitespace characters are interchangeable in HTML. A new line will be treated as a space.
as well as PHP code
Ditto … or you could use the escape sequence \n inside a string literal.
and make visible in a web browser?
The material you quoted is talking about making source code look nice. You generally don't want line feed characters to be visible in a browser.
You could use a <pre> element instead.
Outside of <pre> elements (and the CSS setting they have by default) you can use a space instead of a new line for the same effect in HTML.
What HTML entities/tags/characters are used to achieve this?
… but the advice given in the last sentence of the material you quoted is probably a better approach.
'Lines feed' exactly means a 'New line' both in Html and Php, only the syntax is different.
In case of Html tag, you can use <br> or <br/> tag for a Lines feed. Basically, this tag shows a new line in the output of the Html attribute block, while running through the browser.
You can take the following example for <br> tag:
<html> <body>
<p> To break lines<br>in a text,<br/>use the br element. </p>
</body> </html>
Output:
To break linesin a text,use the br element.
In case of Php, you can use '\n' for a lines feed.
If you are using a string in Php, then instead of writing,
echo "New \nLine";
you can use nl2br() function to get line break, like:
echo nl2br("New \nLine");
Output:
New
Line

Replacing single line breaks with html line breaks only when allowed in context

I'm looking to replace single line breaks (doubles will already be gone) into <br> tags, but only when they are allowed in the context.
For example, consider the below:
<ul>
<li>cat</li>
<li>dog</li>
<li>fish</li>
<li>horse</li>
</ul>
<br> tags are not allowed in many of the areas in the above code, but running the usual simple replacement/addition code such as using nl2br() or running a str_replace() will obviously not follow these context rules.
For the above you would need to follow these rules:
Line breaks BEFORE the starting list tag should be converted
Line breaks AFTER the starting list tag shouldn't be converted
Line breaks BEFORE the starting list item tag shouldn't be converted
Line breaks AFTER the starting list item tag should be converted
Line breaks BEFORE the closing list item tag should be converted
Line breaks AFTER the closing list item tag shouldn't be converted
Line breaks BEFORE the closing list tag shouldn't be converted
Line breaks AFTER the closing list tag should be converted
Is there are current functions / libraries that can do this functionality already? Surely this is a common problem, so I imagine there must be something.
This would be complex to do in PHP. nl2br isn't suitable to preserve HTML in the text you want to process, so you would have to use a DOM parser to do this.
Or you could write your own function that loops through the entire text. Every time it encounters an opening < it should keep a flag, which is reset after a >. When it encounters a newline characters, it can check the flag to see if the character should be preserved or replaced by <br>. This way you can build the result string character by character. Note that invalid markup may easily break such a function.
But I think a simpler, and much better solution is to simply add a small piece of CSS:
white-space: pre-line;
Apply this to the parent of the list (and implicitly to the list and its items too). That will cause the text to behave as normal, with the exception that the text is broken too on newline characters in the text.

Form deleting spaces

<form action="class.php" method="POST">
thread link:
<br>
<input type="text" name="thread">
<input type="submit" value="Submit">
</form>
I have this simple form. Upon entering a string starting with many spaces, something like
" test"
my PHP code
echo 'test:'.$_POST['thread'];
will print test: test. It will erase all spaces except one.
Where did all the spaces go and why does this happen?
Specification of HTMLs tells, renderer removes multiple spaces. That is useful in some cases. To avoid that, you can place content of this field in <pre></pre> block. Like that:
echo '<pre>test:'.$_POST['thread'].'</pre>';
The form does not delete spaces. Neither does your PHP code. The spaces are still there in resulting HTML document (generated by your PHP code in response to form submission). They just get rendered as a single space, since in most contexts, any sequence of whitespace characters in HTML content is equivalent to a single space. This is defined in CSS 2.1 spec, in the description of the white-space property.
Thus, to prevent the collapse of spaces, the simple way is to set white-space: pre in CSS. It also prevents line breaks in the content, but this is probably not a problem here. Using the pre element in HTML causes this setting, but it also sets font family to monospace.
So this is just a matter of HTML and CSS, independently of PHP. Example:
<p> Hello world!</p>
<p style="white-space: pre"> Hello world!</p>
You need to convert whitespaces to html entities
$thread = str_replace(' ', ' ', $_POST['thread'])
and now echo 'test:'.$thread will output your text with whitespaces.
This is the most basic thing about HTML. Any whitespace is equivalent and is treated as a single space.
You should never use multiple spaces to try to layout your text in HTML ( like you could do in Word for instance ). You should use css styles like margin or padding instead.
The answers that propose to replace the spaces with & nbsp; are correct, but they leave you on the wrong track.

Spaces doesn't come after nl2br(htmlentities($text))?

I am printing a article with spaces inside the article.
Text inside article has HTML tags also,so i am using htmlentities before echo.
But problem is that display does't show spaces on the browser.
What is the problem with these commands?
Can someone please suggest me a better option?
DB update command:
mysql_real_escape_string($text, $db)
Article display command:
echo nl2br(htmlentities($row_page['text']));
Example: displayed text is pretty ugly
Real text and i am expecting same:
dbus-1/ libcom_err.so.2# libglib-2.0.so.0# liblvm2cmd.so.2.02* libpopt.so.0.0.0*
device-mapper/ libcom_err.so.2.1* libglib-2.0.so.0.2200.5* libm-2.12.so* libproc-3.2.8.so*
firmware/ libcrypt-2.12.so* libgmodule-2.0.so.0#
HTML collapses all whitespace (spaces or newlines or tabs) into a single space. You can work around it by replacing ' ' with ' ', for example:
echo str_replace(' ', ' ', nl2br(htmlentities($row_page['text'])));
But even cleaner is to just have the browser use pre formatted whitespace:
<pre><?php echo htmlentities($row_page['text']); ?></pre>
Or alternatively use CSS for a bit of extra flexibility:
<div style="white-space: pre;"><?php echo htmlentities($row_page['text']); ?></div>
Pre formatted whitespace has some drawbacks, for example you can't have any newlines or indentation in your HTML file when you're using pre, because the browser will render them. But when you really need to control how something is rendered it's the best choice.
Browsers collapse continuous whitespace into a single space. That's the way it works, mainly so you can write source code like this:
<p>
Some very long text nicely indented and readable in source,
so it's easy to write for the author.
</p>
and it will display nicely in a browser like this:
Some very long text nicely indented and readable in source, so it's easy to write for the author.
To use pre-formatted text, wrap that section in a <pre> tag or use the equivalent CSS rule white-space: pre. The way you're escaping HTML makes this rather difficult of course. A markup language like Markdown may be the solution there.

Categories