make my file readable as either Perl or HTML - html

In the spirit of the "Perl Preamble" where a script works properly whether executed by a shell script interpreter or the Perl interpreter...
I have a Perl script which contains an embedded HTML document (as a "heredoc"), i.e.:
#!/usr/bin/perl
... some Perl code ...
my $html = <<'END' ;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
... more HTML ...
</HTML>
END
... Perl code that processes $html ...
I would like to be able to work on the HTML that's inside the Perl script and check it out using a web browser, and only run the script when the HTML is the way I want. To accomplish this, I need the file to be openable both as an HTML file and as a Perl script.
I have tried various tricks with Perl comments and HTML comments but can't get it quite perfect. The file as a whole doesn't have to be "strictly legal" HTML (although the embedded document should be)... just displayable in a browser with no (or minimal) Perl garbage visible.
EDIT: Solved! See my own answer

Read it and weep Mr. #Axeman... I now present to you the empty set:
</dev/fd/0 eval 'exec perl -x -S $0 ${1+"$#"}' #> <!--
#!perl
... some Perl code ...
my $html = << '<!-- END' ; # -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
... more HTML ...
</HTML>
<!-- END
... Perl code that processes $html ...
# -->

This sounds like a path to pain. Consider storing the HTML in a separate file and reading it in within the script.

Maybe this is a job for Markup::Perl:
# don't write this...
print "Content-type: text/html;\n\n";
print "<html>\n<body>\n";
print "<p>\nYour \"lucky number\" is\n";
print "<i>", int rand 10, "</i>\n</p>\n";
print "</body>\n</html>\n";
# write this instead...
use Markup::Perl;
<html><body><p>
Your "lucky number" is
<i><perl> print int rand 10 </perl></i>
</p></body></html>
You could also drop the use Markup::Perl line and run your script like
perl -MMarkup::Perl my_page_with_embedded_perl.html
Then the page should render pretty well.

Sounds to me like you want a templating solution, such as Template::Toolkit or HTML::Template. Embedding HTML in your code or embedding code in your HTML is a recipe for pain.

Have you considered putting Perl inside of HTML?
Like ASP4 does?
It's a lot easier that way - trust me ;-)

Related

get linked css files via a regexp in a html-page

i try to parse a html page which a have loaded with perl. i need to get the src="asd/jkl/xyz.css" for example out of the html-repsone to manipulate the path to an absolute.
the reason why i want to do this is, that is need the css inline in a E-Mail head ...
so my try to realize this is:
load the page via perl
get the src of the linked css
load the css files via perl
parse the css und put the contents of the css files in the head-tag of my generated email.
has anyone a better idea or a working regex?
Try something like this:
#!/usr/bin/env perl
use XML::LibXML;
my $parser = XML::LibXML->new();
my $doc = $parser->load_html(location => "http://mywebsite.com", recover => 2);
print $doc->findnodes('//link[#rel="stylesheet"]/#src');
Reference: http://metacpan.org/pod/XML::LibXML

Perl script wont run; just displays actual code in the browser

I am new to Perl and am having trouble getting my scripts to run properly. Where am I supposed to put the actual Perl scripts in order for them to run correctly? I am testing everything out on my lap top and am trying to call a script from a html page and all I get is the actual script (code) itself displayed in my web browser as opposed to the information that the code is designed to produce. Therefore, I figure I am supposed to put the Perl file somewhere else? Currently I have the Perl script and the HTML file in the same directory. Any help would be greatly appreciated! See below:
<head>
<title>Student Web Page</title>
</head>
<body>
<h1>WELCOME! You have reached Kito's Student Web Page</h1>
<br />
<p>To run the folloiwing applications, click on the appropriate line:</p>
<form ACTION="first.pl" METHOD="get">
<p>
<input TYPE="submit" VALUE="Step 5 - Perl Environment Variables">
</p>
</form>
#!c:\perl\bin\perl.exe -w
use strict;
print "Content-type: text/html\n\n";
print "<HTML><HEAD><TITLE>Environment Variables</TITLE></HEAD><BODY>";
foreach (keys %ENV) {
print "<BR><FONT COLOR=green>$_</FONT> is set to <FONT COLOR=red>$ENV{$_}</FONT>";
}
print "</BODY></HTML>";
You need to configure your webserver to execute the CGI file. How this is done depends on the webserver and operating system.
Some examples:
http://www.thesitewizard.com/archive/addcgitoapache.shtml
Under linux with apache install the mod_cgi module. Under windows with IIS install activestate perl.

How to get the HTML source of a webpage in Ruby [duplicate]

This question already has answers here:
Equivalent of cURL for Ruby?
(13 answers)
Closed 7 years ago.
In browsers such as Firefox or Safari, with a website open, I can right click the page, and select something like: "View Page Source" or "View Source." This shows the HTML source for the page.
In Ruby, is there a function (maybe a library) that allows me to store this HTML source as a variable? Something like this:
source = view_source(http://stackoverflow.com)
where source would be this text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Stack Overflow</title>
etc
Use Net::HTTP:
require 'net/http'
source = Net::HTTP.get('stackoverflow.com', '/index.html')
require "open-uri"
source = open(url){ |f| f.read }
UPD: Ruby >=1.9 allows syntax
require "open-uri"
source = open(url, &:read)
UPD: Ruby >=3.0 demands syntax
require "open-uri"
source = URI(url).open(&:read)
require 'open-uri'
source = open(url).read
short, simple, sweet.
Yes, like this:
require 'open-uri'
open('http://stackoverflow.com') do |file|
#use the source Eric
#e.g. file.each_line { |line| puts line }
end
require 'mechanize'
agent = Mechanize.new
page = agent.get('http://google.com/')
puts page.body
you can then do a lot of other cool stuff with mechanize as well.
You could use the builtin Net::HTTP:
>> require 'net/http'
>> Net::HTTP.get 'stackoverflow.com', '/'
Or one of the several libraries suggested in "Equivalent of cURL for Ruby?".
Another thing you might be interested in is Nokogiri. It is an HTML, XML, etc. parser that is very easy to use. Their front page has some example code that should get you started and see if it's right for what you need.
If you have cURL installed, you could simply:
url = 'http://stackoverflow.com'
html = `curl #{url}`
If you want to use pure Ruby, look at the Net::HTTP library:
require 'net/http'
stack = Net::HTTP.new 'stackoverflow.com'
# ...later...
page = '/questions/4217223/how-to-get-the-html-source-of-a-webpage-in-ruby'
html = stack.get(page).body

How can I call a Perl script inside HTML page?

I have a single HTML file, how I use a Perl script(date/hour) in the HTML code?
My goal: show a date/hour in HTML
Obs.: alone both script are ok.
Example:
HTML File:
<html>
<body>
code or foo.pl script
</body>
</html>
Perl script(foo.pl):
#!/usr/local/bin/perl
use CGI qw/:push -nph/;
$| = 1;
print multipart_init(-boundary=>'----here we go!');
for (0 .. 4) {
print multipart_start(-type=>'text/plain'),
"The current time is ",scalar(localtime),"\n";
if ($_ < 4) {
print multipart_end;
} else {
print multipart_final;
}
sleep 1;
}
Perl is a server-side language, so it must be run on the server. The HTML code is displayed in the browser, and it is generated by the server. So you would have to run the perl script on the server to generate the date / hour, and embed that into the HTML code that you serve to the browser.
Here is a tutorial on how to do this.
It sounds like you want Ajax. Your HTML page uses JavaScript to call your Perl program. Your JavaScript gets the response and replaces the part of the page where you want the data to go. Alternatively, you can just skip the Perl bit altogether and just do it all in JavaScript.
You can either generate the entire HTML page via a CGI script (as per Chetan's answer) - or as an alternative you can use one of the templating modules (EmbPerl, Mason, HTML::Template, or many others).
The templating solution is better for real software development, where separation of HTML and the Perl logic is more important. E.g. for EmbPerl, your code would look like:
<html>
<body>
[- my $date_hour= my_sub_printing_date_and_hour(); # Logic to generate -]
[+ $date_hour # print into HTML - could be combined with last statement +]
</body>
</html>

Writing a vim function to insert a block of static text

I'd like to be able to do something like this in vim (you can assume v7+ if it helps).
Type in a command like this (or something close)
:inshtml
and have vim dump the following into the current file at the current cursor location
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
</body>
</html>
Can I write a vim function do this is? Is there a better way?
Late to the party, just for future reference, but another way of doing it is to create a command, e.g.
:command Inshtml :normal i your text here^V<ESC>
The you can call it as
:Inshtml
Explanation: the command runs in command mode, and you switch to normal mode with :normal, then to insert mode with 'i', what follows the 'i' is your text and you finish with escape, which is entered as character by entering ^V
It is also possible to add arguments, e.g.
:command -nargs=1 Inshtml :normal i You entered <args>^V<ESC>
where <args> (entered literally as is) will be replaced with the actual arguments, and you call it with
:Inshtml blah
I do that by keeping under my vim folder a set of files which then I insert using the r command (which inserts the contents of a file, at the current location if no line number is passed) from some function:
function! Class()
" ~/vim/cpp/new-class.txt is the path to the template file
r~/vim/cpp/new-class.txt
endfunction
This is very practical - in my opinion - when you want to insert multi-line text. Then you can, for example, map a keyboard shortcut to call your function:
nmap ^N :call Class()<CR>
i have created a new file generate_html.vim in ~/.vim/plugins/
with the following code
"
" <This plugin generates html tags to new html files>
"
autocmd BufNewFile *.html call Generate_html()
function! Generate_html()
call append(0, "<!DOCTYPE HTML>")
call append(1, "<html><head>")
call append(2, " <title></title>")
call append(3, ' <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />')
call append(4, ' <style type="text/css">')
call append(5, ' </style>')
call append(6, '</head>')
call append(7, '<body>')
call append(8, '</body>')
call append(9, '</html>')
endfunction
this way, everytime I open a new .html file in vim, it prints that text to the new file
Can you define an abbreviation. e.g.
:ab insh 'your html here'
as nothing in the above appears to be parameterised ?
In fact, looking at my VIM configs, I detect a new .html file being loaded thus:
autocmd BufNewFile *.html call GenerateHeader()
and define a function GenerateHeader() to insert my required template (I do the same for Java/Perl etc.).
It's worth getting the Vim Cookbook for this sort of stuff. It's a sound investment.
snippetsEmu
I like to use the snippetsEmu vim plugin to insert code snippets like your.
The advantage of snippetsEmu is that you can specify place holders and jump directly to them in order to insert a value. In your case you could for example add a place holder between the title tags so you can easily add a title to the document when inserting this snippet.
snippetsEmu comes with various snippets (also for HTML) and new snippets can be esaily added.
EDIT
snipMate
Today I revisited my VIM confiugration + installed plugins and found the snipMate plugin, which is IMHO even better than snippetsEmu. snipMate updates just like TextMate all placeholders on the fly.
This should be possible. I use auto-replacement. In my .vimrc I have this line:
iab _perls #!/usr/bin/perl<CR><BS><CR>use strict;<CR>use warnings;<CR>
And whenever I start a Perl script, I just type _perls and hit Enter.
You can use Python (or any other program) if like me you haven't quite grasped vimScript
This guy talks about the vim expression register. Essentially you put something like this in your .vimrc file
:imap <C-j> <C-r>=system('/home/BennyHill/htmlScript.py')<CR>
So that every time in insert mode you press Ctrlj it calls the script htmlScript.py which has something like this in it (NOTE I haven't actually tested this)
#!/usr/bin/env python
import sys
snippet="""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
</body>
</html>"""
sys.stdout.write(snippet)
Then just remember to make the file executable (chmod 0755 /home/BennyHill/htmlScript.py). It might be overkill, but I am far more comfortable with Python than I am with vim's syntax.
You can once copy this text to some ( for example 'a' ) register. And paste it every time you need unless you overwrite register 'a'.
To copy to register a in visual mode: "ay
To paste from register a in normal mode: "ap
To paste from register a in insert mode: a
Or if you have this template already copied you can use
let #a = #*
To put this template to register a.
There are many template expander plugins for vim.
NB: I'm maintaining the fork of muTemplate. Just dump your code into
{rtp}/template/html.template or into $VIMTEMPLATES/html.template. And that's all. If you don't want the snippet to be implicitly loaded when opening a new HTML file, then name the template-file html/whatever.template (instead of html.template), and load it with :MuTemplate html/whatever of with whatever^r<tab> in INSERT mode (in an HTML buffer).
All the path issues, portability issues, etc are already taken care of. And unlike snippetEmu that supports (and somehow expects) several (hard to maintain, IMO) snippets in a same snippets definition file, Mu-template requires one template-file per snippet.
Put your text in a file (e.g.,html).
Then put the following in your .vimrc.
command Inshtml r html
I use Inshtml instead of inshtml because vim doesn't support user defined command starting with small letter.
Then if can type Inshtml in command mode (i.e., :Inshtml).