doubledee Posted May 9, 2012 Share Posted May 9, 2012 I am tweaking a function which takes data that was entered into a Form TextArea and wraps each paragraph with <p></p> tags so things are properly marked up. It seems to be working okay, except for two annoying things... 1.) When I go to View ---> Source, I do NOT want to see paragraph after paragraph all on the same line. I tried adding a \n into the preg_replace but it is adding an extra carriage return in the output. 2.) Right now, if my code sees 2 \n's it will convert that to "</ p><p>", which is fine. However it does the same thing if there are 20 \n's which is technically wrong, because maybe someone wanted the extra 18 carriage returns between their paragraphs?! For example, in the line below "I decided to start..." that line should get wrapped in <p></p> and then there should be a <br /><br /> because the User added two *extra* carriage returns, and then the next line "My boss is a jerk..." should get wrapped in <p></p> because it is also a paragraph. I'm sure this one is impossible to do, but the end goal is simple... Regardless of how many carriage returns there are between blocks of text, the blocks of text should first get wrapped in <p> </p> but then any additional line spacing should be preserved. Hope that makes sense?! Here is the code I am working with... $text="I decided to start my own business because I want to be my own boss! My boss is a jerk and never appreciates anything that I do for him, so why put up with the abuse?! He takes me for granted and doesn't appreciate all of my talents. Running my own business will give me a chance to do things as I see fit... Line One Line Two Line Three Line Four Line Eight"; $text2 = htmlentities($text, ENT_QUOTES); function nl2p($string, $line_breaks = true) { // Remove existing HTML formatting to avoid double tags. //^ $string = str_replace(array('<p>', '</p>', '<br>', '<br/>'), '', $string); // Replace Carriage Return with Empty String. // Replace multiple Newlines with closing & opening paragraph tags. // Replace single Newline with break tag. if ($line_breaks == true) { return '<p>'.preg_replace(array("#\r#","#\n{2,}#", "#\n#"), array("","</p><p>", "<br />\n"), $string).'</p>'; }else{ return '<p>'.preg_replace("#\n#", "</p><p>", trim($string)).'</p>'; } } echo nl2p($text2, TRUE); Oh, btw, as you can see, adding a \n after the line break (i.e. "<br />\n") actually added the line break in my Source as I wanted. It is just when you add a \n in between the paragraphs that my code misbehaves (i.e. "</p>\n<p>"). Can these two problems be fixed?? Thanks, Debbie Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/ Share on other sites More sharing options...
doubledee Posted May 9, 2012 Author Share Posted May 9, 2012 Here is my best stab at things, with the part in Red being where I am stuck... return '<p>'.preg_replace(array("#\r#", "#\n{2}#", "#\n{3,}#", "#\n#"), array("", "</p><p>", "</p>insert extra breaks here<p>", "<br />\n"), $string).'</p>'; Maybe this is too fancy for my preg_replace, but hey, we can dream, right?! *LOL* Thanks, Debbie Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344246 Share on other sites More sharing options...
xyph Posted May 9, 2012 Share Posted May 9, 2012 Why does the source code need to be pretty? Most mark-up debuggers will display the DOM in a tree-view for you, and these come with or are plugged directly in to the browser. It's going to be a bunch of extra work to keep 'pretty' as you have to keep track of base indentation, word-wrap, etc. Here's a basic snippet that deals with the linebreaks <?php $string = 'A bunch of text A new paragraph With an extra line break And a bunch more'; # Convert Windows (\r\n) and Mac (\r) to Unix (\n) $string = str_replace(array("\r\n","\r"), "\n", $string); # Grab a linebreak, followed by 0 or more linebreaks afterwards $string = preg_replace_callback('#\n(\n*)#', # Using unlgy create function, in case 5.3 not available create_function('$match', # Start a new paragraph '$return = "</p>\n";'. # Check if our capturing group found any extra linebreaks, and replace those with BRs 'if( !empty($match[1]) ) $return .= str_replace("\n","<br>",$match[1])."\n";'. # Return 'return $return."<p>";' ), $string ); echo '<p>'.$string.'</p>'; ?> The create_function syntax is ugly, but it works pre 5.3, and is better than cluttering your namespace with a one-use function IMO. Produces <p>A bunch of text</p> <p>A new paragraph</p> <br> <p>With an extra line break</p> <br><br><br><br> <p>And a bunch more</p> Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344252 Share on other sites More sharing options...
scootstah Posted May 9, 2012 Share Posted May 9, 2012 You don't actually need all of those paragraph tags for proper markup. Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344255 Share on other sites More sharing options...
doubledee Posted May 9, 2012 Author Share Posted May 9, 2012 Why does the source code need to be pretty? Most mark-up debuggers will display the DOM in a tree-view for you, and these come with or are plugged directly in to the browser. I don't, but I just like pretty code for readability. It's going to be a bunch of extra work to keep 'pretty' as you have to keep track of base indentation, word-wrap, etc. I was just hoping to have each <p> on its on line in the Source versus everything on one enormously long line. Here's a basic snippet that deals with the linebreaks <?php $string = 'A bunch of text A new paragraph With an extra line break And a bunch more'; # Convert Windows (\r\n) and Mac (\r) to Unix (\n) $string = str_replace(array("\r\n","\r"), "\n", $string); # Grab a linebreak, followed by 0 or more linebreaks afterwards $string = preg_replace_callback('#\n(\n*)#', # Using unlgy create function, in case 5.3 not available create_function('$match', # Start a new paragraph '$return = "</p>\n";'. # Check if our capturing group found any extra linebreaks, and replace those with BRs 'if( !empty($match[1]) ) $return .= str_replace("\n","<br>",$match[1])."\n";'. # Return 'return $return."<p>";' ), $string ); echo '<p>'.$string.'</p>'; ?> The create_function syntax is ugly, but it works pre 5.3, and is better than cluttering your namespace with a one-use function IMO. Produces <p>A bunch of text</p> <p>A new paragraph</p> <br> <p>With an extra line break</p> <br><br><br><br> <p>And a bunch more</p> That is some pretty fancy coding there!!! It works pretty well, except that if you have two lines separated by just a carriage return, they are showing up wrapped in paragraph tags. For instance... Line 1 Line 2 Is showing up in code as... <p>Line 1</p> <p>Line 2</p> And outputting as... Line 1 Line 2 When the code should actually be... <p>Line 1<br /> Line 2</p> And the output should be... Line 1 Line 2 I have some questions on you code, but I'll let you respond to my comments first in case things change?! BTW, here is my best guess at things... $text="I decided to start my own business because I want to be my own boss! My boss is a jerk and never appreciates anything that I do for him, so why put up with the abuse?! He takes me for granted and doesn't appreciate all of my talents. Running my own business will give me a chance to do things as I see fit... Line One Line Two Line Three Line Four Line Eight Line Ten"; $text2 = htmlentities($text, ENT_QUOTES); function nl2p($string, $line_breaks = true) { // Remove existing HTML formatting to avoid double tags. //^ $string = str_replace(array('<p>', '</p>', '<br>', '<br/>'), '', $string); // Replace Carriage Return with Empty String. // Replace multiple Newlines with closing & opening paragraph tags. // Replace single Newline with break tag. if ($line_breaks == true) { return '<p>'.preg_replace(array("#\r#", "#\n{3,}#", "#\n{2}#", "#\n#"), array("", "</p><br /><p>", "</p><p>", "<br />\n"), $string).'</p>'; // return '<p>'.preg_replace(array("#\r#","#\n{2,}#", "#\n#"), array("","</p><p>", "<br />\n"), $string).'</p>'; }else{ return '<p>'.preg_replace("#\n#", "</p><p>", trim($string)).'</p>'; } } echo nl2p($text2, TRUE); My code is almost perfect, except if you have 10 carriage returns between two paragraphs, you just get one fixed break <br /> between them since I didn't know how to do a callback or whatever is needed. I can live with my code as-is, but if I could fix this one last thing I suppose it would be nice... Where I use my code and fix this one last thing, or use your code above and address the issues noted makes no difference to me. Thanks for the help!!! Debbie P.S. You code does a much "prettier" job in the View--> Source Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344262 Share on other sites More sharing options...
doubledee Posted May 9, 2012 Author Share Posted May 9, 2012 You don't actually need all of those paragraph tags for proper markup. I do need properly placed <p> tags in order to style things like I want... Debbie Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344263 Share on other sites More sharing options...
scootstah Posted May 9, 2012 Share Posted May 9, 2012 You don't actually need all of those paragraph tags for proper markup. I do need properly placed <p> tags in order to style things like I want... Debbie How do you want to style it? I'm confident you can achieve it using CSS which is a lot less effort. Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344270 Share on other sites More sharing options...
doubledee Posted May 9, 2012 Author Share Posted May 9, 2012 You don't actually need all of those paragraph tags for proper markup. I do need properly placed <p> tags in order to style things like I want... Debbie How do you want to style it? I'm confident you can achieve it using CSS which is a lot less effort. I appreciate your eagerness for an easier way, but that isn't what I want... Just like when I hand-code a webpage, paragraphs need to be wrapped in <p></p> tags. Sentences - within a paragraph - that need extra lines between them are separated by line breaks <br />. Why in the world content typed into an HTML TextArea doesn't come out that way on it's own is besides me, but I want things in that format 1.) Because that is proper semantic markup, and 2.) Because I need <p> tags as hooks for my already established styles. But I don't want to start a debate on that... The code I posted above is basically good enough for my needs, and it marks up the text properly. And Xyph's attempt is equally close. I was just hoping to get that last 10% right in either my version or Xyph's version... Debbie Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344276 Share on other sites More sharing options...
requinix Posted May 9, 2012 Share Posted May 9, 2012 What about nl2bring it, then replacing two consecutive s with a \n? Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344281 Share on other sites More sharing options...
Drummin Posted May 9, 2012 Share Posted May 9, 2012 Just thought I'd see what the big boys have to say about the example I offered. <?php $text="I decided to start my own business because I want to be my own boss! My boss is a jerk and never appreciates anything that I do for him, so why put up with the abuse?! He takes me for granted and doesn't appreciate all of my talents. Running my own business will give me a chance to do things as I see fit..."; function nl2p($text) { $text=str_replace("\n\r\n","</p>\r\r<p>","$text"); $text=str_replace("\n","<br /> ","$text"); $text="<p>" . $text . "</p>"; return($text); } echo nl2p($text); ?> Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344307 Share on other sites More sharing options...
doubledee Posted May 9, 2012 Author Share Posted May 9, 2012 Drummin, Nice try, but you code doesn't wrap a <p></p> around each paragraph... It just adds <br /> where there is a carriage return. nl2br() does that out-of-the-box. I think what I have or Xyph proposed seems to be closest and worth tweaking... Debbie Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344358 Share on other sites More sharing options...
Barand Posted May 9, 2012 Share Posted May 9, 2012 my 0.02 worth function paras($text) { function nl(&$v, $k) { $v = nl2br($v); } $a = explode("\n\n", $text); array_walk($a, 'nl'); return '<p>' . join("</p>\n\n<p>", $a) . '</p>'; } echo paras($text); Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344369 Share on other sites More sharing options...
doubledee Posted May 9, 2012 Author Share Posted May 9, 2012 my 0.02 worth function paras($text) { function nl(&$v, $k) { $v = nl2br($v); } $a = explode("\n\n", $text); array_walk($a, 'nl'); return '<p>' . join("</p>\n\n<p>", $a) . '</p>'; } echo paras($text); That doesn't even run... Debbie Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344373 Share on other sites More sharing options...
Drummin Posted May 10, 2012 Share Posted May 10, 2012 Drummin, Nice try, but you code doesn't wrap a <p></p> around each paragraph... It just adds <br /> where there is a carriage return. nl2br() does that out-of-the-box. I think what I have or Xyph proposed seems to be closest and worth tweaking... Debbie If possible, can some then please explain why I get single line breaks as <br /> and double breaks with <p></p> as shown below but Debbie does not. Is it a doctype issue? Server issue? Something else? <html> <body> <p>I decided to start my own business because I want <br /> to be my own boss! </p> <p>My boss is a jerk and never appreciates anything <br /> that I do for him, so why put up with the abuse?! <br /> He takes me for granted and doesn't appreciate <br /> all of my talents. </p> <p>Running my own business will give me a chance <br /> to do things as I see fit...</p></body> </html> Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344377 Share on other sites More sharing options...
darkfreaks Posted May 10, 2012 Share Posted May 10, 2012 http://php.net/manual/en/function.nl2br.php if you look under this page there are plenty of alt ways to find a break and convert it to a paragraph. Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344381 Share on other sites More sharing options...
kiqeri Posted May 10, 2012 Share Posted May 10, 2012 try using <pre> </pre> it preserves spaces and line breaks Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344390 Share on other sites More sharing options...
kiqeri Posted May 10, 2012 Share Posted May 10, 2012 woops I am off topic. byeeee Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344392 Share on other sites More sharing options...
Barand Posted May 10, 2012 Share Posted May 10, 2012 That doesn't even run... Should do. I ran it before posting and got this result: <p>I decided to start my own business because I want to be my own boss!</p> <p>My boss is a jerk and never appreciates anything that I do for him, so why put up with the abuse?! </p> <p>He takes me for granted and doesn't appreciate all of my talents.Running my own business will give me a chance to do things as I see fit...</p> <p></p> <p>Line One<br /> Line Two<br /> Line Three<br /> Line Four</p> <p></p> <p>Line Eight</p> Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344421 Share on other sites More sharing options...
Drummin Posted May 10, 2012 Share Posted May 10, 2012 Hmm My code gives me <p>I decided to start my own business because I want <br /> to be my own boss! </p> <p>My boss is a jerk and never appreciates anything <br /> that I do for him, so why put up with the abuse?! <br /> He takes me for granted and doesn't appreciate <br /> all of my talents. </p> <p>Running my own business will give me a chance <br /> to do things as I see fit...</p> Barand's code give me <p>I decided to start my own business because I want<br /> to be my own boss!<br /> <br /> My boss is a jerk and never appreciates anything<br /> that I do for him, so why put up with the abuse?!<br /> He takes me for granted and doesn't appreciate<br /> all of my talents.<br /> <br /> Running my own business will give me a chance<br /> to do things as I see fit...</p> Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344524 Share on other sites More sharing options...
xyph Posted May 10, 2012 Share Posted May 10, 2012 Mine's easy enough to change, just add a second capturing group. This one's PHP 5.3+, as I've already shown an example with create_function, and I hate programming in strings. <?php $string = 'A bunch of text The same paragraph A new paragraph New one with linebreaks in between'; # Convert Windows (\r\n) and Mac (\r) to Unix (\n) $string = str_replace(array("\r\n","\r"), "\n", $string); # Grab a linebreak, followed by 0 or 1 linebreak after, followed by 0 or more after that $string = preg_replace_callback('#\n(\n?)(\n*)#', function( $match ) { $return = ''; # Only 1 line break matched if( empty($match[1]) && empty($match[2]) ) return "<br>\n"; # At least 2 matched else $return .= "</p>\n"; # More than 2 matched if( !empty($match[2]) ) $return .= str_replace("\n","<br>\n",$match[2]); return $return.'<p>'; }, $string ); echo '<p>'.$string.'</p>'; ?> In the future, you should try to make the changes to work yourself, and if you can't, ask for more help. As it is, it looks like you're just waiting for someone to post a completely working solution. Replies like this: That doesn't even run... are unacceptable if you want people to help you further. Try it, if it fails, post the code you've tried and the reason you tried it. Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344527 Share on other sites More sharing options...
doubledee Posted May 10, 2012 Author Share Posted May 10, 2012 Mine's easy enough to change, just add a second capturing group. This one's PHP 5.3+, as I've already shown an example with create_function, and I hate programming in strings. <?php $string = 'A bunch of text The same paragraph A new paragraph New one with linebreaks in between'; # Convert Windows (\r\n) and Mac (\r) to Unix (\n) $string = str_replace(array("\r\n","\r"), "\n", $string); # Grab a linebreak, followed by 0 or 1 linebreak after, followed by 0 or more after that $string = preg_replace_callback('#\n(\n?)(\n*)#', function( $match ) { $return = ''; # Only 1 line break matched if( empty($match[1]) && empty($match[2]) ) return "<br>\n"; # At least 2 matched else $return .= "</p>\n"; # More than 2 matched if( !empty($match[2]) ) $return .= str_replace("\n","<br>\n",$match[2]); return $return.'<p>'; }, $string ); echo '<p>'.$string.'</p>'; ?> Is there a way to make that work in versions earlier than PHP 5.3?? (I'm on MAMP and am stuck with 5.2.6) In the future, you should try to make the changes to work yourself, and if you can't, ask for more help. As it is, it looks like you're just waiting for someone to post a completely working solution. Replies like this: That doesn't even run... are unacceptable if you want people to help you further. Try it, if it fails, post the code you've tried and the reason you tried it. I did run his code and that is why I posted that. (Turns out I had some parse error I didn't catch.) Debbie Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344543 Share on other sites More sharing options...
xyph Posted May 10, 2012 Share Posted May 10, 2012 I did run his code and that is why I posted that. (Turns out I had some parse error I didn't catch.) Then mention the parse error, post the code that caused the error, etc. Statements like the one I quoted aren't going to help anyone with anything. Is there a way to make that work in versions earlier than PHP 5.3?? (I'm on MAMP and am stuck with 5.2.6) Yes, there are two ways. I mentioned one in my first reply, and gave a direct example using the other in my first snippet. You can use the create_function syntax, or you can hard-code the function outside of the preg_replace_callback arguments, and include the function name, as a string, in it's place. Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344585 Share on other sites More sharing options...
Barand Posted May 10, 2012 Share Posted May 10, 2012 I did run his code and that is why I posted that. (Turns out I had some parse error I didn't catch.) That's OK, Doubledee. Apology accepted. Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344634 Share on other sites More sharing options...
doubledee Posted May 11, 2012 Author Share Posted May 11, 2012 I did run his code and that is why I posted that. (Turns out I had some parse error I didn't catch.) That's OK, Doubledee. Apology accepted. Glad someone did! I think we have too many version going on for one thread... FWIW, here is your code with my test data... <?php $text="I decided to start my own business because I want to be my own boss! My boss is a jerk and never appreciates anything that I do for him, so why put up with the abuse?! He takes me for granted and doesn't appreciate all of my talents. Running my own business will give me a chance to do things as I see fit... Line One Line Two Line Three Line Four Line Eight Line Ten"; function paras($text) { function nl(&$v, $k) { $v = nl2br($v); } $a = explode("\n\n", $text); array_walk($a, 'nl'); return '<p>' . join("</p>\n\n<p>", $a) . '</p>'; } echo paras($text); ?> When I run your code I see this output... I decided to start my own business because I want to be my own boss! My boss is a jerk and never appreciates anything that I do for him, so why put up with the abuse?! He takes me for granted and doesn't appreciate all of my talents. Running my own business will give me a chance to do things as I see fit... Line One Line Two Line Three Line Four Line Eight Line Ten Notice how we lost two lines at the top... Furthermore, if we look at the HTML, you see an errant <p></p> after the first line with nothing in it. <p>I decided to start my own business because I want to be my own boss!</p> <p></p> <p>My boss is a jerk and never appreciates anything that I do for him, so why put up with the abuse?! He takes me for granted and doesn't appreciate all of my talents.</p> <p>Running my own business will give me a chance to do things as I see fit...</p> <p>Line One<br /> Line Two<br /> Line Three<br /> Line Four</p> <p></p> <p>Line Eight</p> <p>Line Ten</p> The above test data is NOT the best choice to show what I am looking for, however based on my rules, it should have this HTML... <p>I decided to start my own business because I want to be my own boss!</p> <br /> <br /> <br /> <p>My boss is a jerk and never appreciates anything that I do for him, so why put up with the abuse?! He takes me for granted and doesn't appreciate all of my talents.</p> <br /> <p>Running my own business will give me a chance to do things as I see fit...</p> <br /> <p>Line One<br /> Line Two<br /> Line Three<br /> Line Four</p> <br /> <br /> <br /> <p>Line Eight</p> <br /> <p>Line Ten</p> Without being a human, this is virtually no way to know how to properly determine what is a Paragraph and what isn't in the disparate example above. However, this is what I was trying to do... - If you have a sentence/phrase/block of text, and it is followed by two carriage returns, then it should be wrapped in <p></p> - If you have a sentence/phrase/block of text, and it is followed by one carriage returns, then it should be followed by a <br /> So a better example would be... <p>This is one sentence in our paragraph. This is another sentence in our paragraph. And so on...</p> <p>This is yet another paragraph but with only one sentence...</p> <p>This is a list...<br /> Item 1<br /> Item 2<br /> Item 3 (End with a P-tag)<br /></p> <br /> <br /> <br /> <p>This is a new paragraph. It has no space after this line, so we need a break.<br /> This is still part of the same paragraph because we don't have a blank line in between...<br /> Still the same paragraph but this time we close it out.</p> <br /> <p>The end.</p> That oughta keep ya busy!! Debbie P.S. I still think Xyph's example has the most hope, but this thread is rather *foggy* at this point?! Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344644 Share on other sites More sharing options...
Braxton Posted May 11, 2012 Share Posted May 11, 2012 This is the method I generally use for wrapping paragraphs. Hope this helps. function wrapBody($body){ $temp = ''; $lines = explode("\r\n", $body); foreach($lines as $line){ if(!empty($line)){ $temp .= "<p>".$line."</p>\n"; } } return $temp; } Quote Link to comment https://forums.phpfreaks.com/topic/262308-function-to-add-tags/#findComment-1344685 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.