Both answers so far are correct but a more thorough answer seems warranted.
If you use this:
$content = wpautop( $post->post_content );
you're applying the one function that adds paragraph tags to post content. wpautop()
is one of many functions (including plugin functions at times) that hooks onto the_content
, so if you do this:
$content = apply_filters('the_content', $post->post_content);
you're getting the post content run through any filters on the_content
which includes wpautop()
by default.
Finally, if you're in the loop, you can just do this:
$content = apply_filters( 'the_content', get_the_content() );
which is essentially a wrapper for the second code snippet, but of course it's a little nicer looking. Update 1 Sep 2018: Revised based on comment. Props @timmb.
Generally, I'd say that the preferred "right way" to do this is from last to first since using a core WP function should enable more backwards compatibility (theoretically, at least). The only other decision to make then is whether you want to allow WordPress and plugins to also modify the post content. If that's the case, definitely use the 2nd or 3rd options.