debiandude has asked for the wisdom of the Perl Monks concerning the following question:

Basically how is it done here. I think it is such a cool feature and want to steal borrow it for my website. How are they parsing the message. Do they do it once. Look for a code block and copy it as a reference into some database table that holds code blocks? Is it available as some module already on CPAN? Thanks.

Replies are listed 'Best First'.
Re: perlmonks downloadable code blocks
by ikegami (Patriarch) on Apr 11, 2008 at 04:07 UTC
    I heard PM uses a simple regexp to identify code blocks and there's evidence* to support that. I don't know what the actual code is for displaytype=selectcode , displaytype=displaycode and displaytype=displaycode;part=X, but that same simple regexp would extract the code blocks quite easily. For example, the third page I mentioned could be generated with something as simple as
    my $post_body = ...from db...; my $part = $cgi->param{part}; my $block = ($post_body =~ m{<c>(.*?)</c>}gi)[$part]; if (!defined($block)) { ...error... } else { print("Content-Type: text/plain\n\n$block"); }

    * — PM recognizes <c>...</c> but not <c >...</c> like it does for other tags, and PM recognizes code blocks inside of HTML comments.

      That's pretty snazzy. And I guess I could modify the code inline as well with something like this:
      my $match = 0; my $post_body = ...from db...; $match++ while $post_body =~ s/<c>(.*?)<\/c>/<a href='download?part=$m +atch'>Download Me<\/a><pre>$1<\/pre>/i;
        PM does a bit more than that — it escapes "<", ">" and "&", at least — but that's the idea.

        By the way, I'd add the "g" modifier to your s///. There's no reason to search from the start of the string every pass.

      The reason I wanted the while is because I update each code block with the number corresponding to which code block it is. Here is an example
      my $post_body ='<c>this is the first code block code</c> This is <c>an +other code block</c>'; my $part = 1; $part++ while $post_body =~ s/<c>(.*?)<\/c>/<a href='download?part=$p +art'>Download Me<\/a><pre>$1<\/pre>/i; print $post_body, "\n";
      And I will have this as an output:
      <a href='download?part=1'>Download Me</a><pre>this is code</pre> This +is <a href='download?part=2'>Download Me</a><pre>more code</pre>
      Am I missing something, because I still don't see how I can have the output that I want if I use the global switch.
        Ah good point. e modifier to the rescue.
        my $part; $post_body =~ s{<c>(.*?)<\/c>}{ ++part; qq{<a href='download?part=$part'>Download Me</a><pre>$1</pre>} }gei;
Re: perlmonks downloadable code blocks
by jdporter (Paladin) on Apr 11, 2008 at 14:21 UTC
    Look for a code block and copy it as a reference into some database table that holds code blocks? Is it available as some module already on CPAN?

    No. No.

    As you (presumably) know, code blocks are supposed to be enclosed in <code>...</code> tags by the author of the post. The content of the post is stored in the database exactly as submitted by the author. Given that, it is trivial for the PerlMonks engine to find and extract code blocks. When the node is rendered, <code> tags are transformed into appropriate HTML, download links are created for the code block(s), etc.

    A word spoken in Mind will reach its own level, in the objective world, by its own weight