0

In brief:

I would like to programmatically mimic the org mode sequence C-c C-e h o to export a buffer to HTML and open the web browser.

My scenario:

  • I have a written a shell-command (in my code snippet below, this command is remplaced by the simple "more" command) that processes the current buffer file (the (buffer-file-name) part).
  • the shell command (here "more") generates an org mode compatible output and stores it in new_buffer.
  • my problem: I want to export this new_buffer into an html file and open the browser (like the manual C-c C-e h o sequence).
  • then I kill the temporary new_buffer

-> I do not know how to do that. For the moment I use org-html-export-as-html, however this function simply exports the created new_buffer into a new *Org HTML Export* buffer.

What I have done so far (with my brittle emacs-lisp knowledge):

 (defun generate_html()
  (interactive)
  (let ((new_buffer (generate-new-buffer (concat (buffer-file-name) ".org"))))
    (shell-command (concat "more " (buffer-file-name)) new_buffer)
    (org-html-export-as-html ) ;; <-- what to do here to mimic C-c C-e h o ?
    (kill-buffer new_buffer)))
1

Looks like you'll need to define your own command to do it. If you look in ox-html.el and search for ":menu-entry" (on my machine [Org 9.0.9], it's on line 105), you'll see that C-c C-e h H and C-c C-e h h point to commands in ox-html.el, but C-c C-e h o is implemented via a lambda function that you'll have to reproduce. No idea why it was done differently than the other options.

| improve this answer | |
  • Thanks for this information. At worst, maybe I can save the exported html into a file and open it with another shell-command chromium file.hmtl – Picaud Vincent Jan 24 '19 at 20:10
  • 4
    The anonymous function just handles async export. Since the OP is exporting synchronously, only the else part is needed: (org-open-file (org-html-export-to-html)) -- all the optional arguments are nil. – NickD Jan 25 '19 at 2:47
  • @NickD thanks for the comment, I will try that today – Picaud Vincent Jan 25 '19 at 7:53
1

The solution to my alternative issue (I used pandoc, more below) may apply to your's as well.

I was looking for a CGI-based approach to render org files in the browser, thus implicitly publishing them on the fly. This would allow me to work with the org files without having to actively publish them.

In the past, I took a lot of notes using ReStructured Text and later AsciiDoc. I had implemented a solution for each of the formats, but ended up with this handy Perl-based script that would do the conversion on the fly. AsciiDoc, MarkDown and ReStructured Text are covered, but org gave me a headache as I simply could not render the result of org-html-export-as-html.

When invoking

emacs <source.org> --batch --kill -l ~/.emacs -f org-html-export-to-html

on the terminal, a file source.html is generated, but when I put the command in my CGI:

emacs <source.org> --batch --kill -l ~/.emacs -f org-html-export-to-html && cat source.html

it did not come up. This wasn't anyway what I wanted, as an HTML file would have been generated.

I did not find a way of making Emacs redirect the result of org-html-export-as-html to stdout in batch mode. All in all, the whole thing seemed too complicated, until I looked for an alternative way of converting org to html: https://pandoc.org/.

Now I have a single sgml.pl that will convert all these formats on the fly to HTML and thus can be used as a CGI for viewing them on the browser.

This is circumventing Emacs and should therefore perhaps not belong to this forum. I apologise.

Let me know if you're interested in the code.

Best,

Denis

Ok, since I have been asked (I hope this helps):

The below CGI works for both Apache2 and Nginx.

Just to recap,

In Apache2, a handler is defined:

<IfModule mod_actions.c>`
    Action convert-sgml /cgi/sgml.pl`
    AddHandler convert-sgml .adoc .md .org .rst .txt`
...
</IfModule>

In Nginx:

location ~ \.(adoc|md|org|rst|txt)$ {`
    fastcgi_param PATH_TRANSLATED $document_root$document_uri;`
    rewrite ^(.+\.)(adoc|md|org|rst|txt)$ /cgi-bin/sgml.pl?$document_root$document_uri last;`
...
}

The actual CGI code (pandoc does not convert into AsciiDoc, hence using asciidoctor):

#! /usr/bin/perl

# Obtain the server software from the signature (Apache/nginx),
# in order to determine which environment variable will have
# the name of the file to be converted.
$ENV{'SERVER_SOFTWARE'}=~/^([A-Za-z]+)/;
my $serverName=$&;
my %httpd=(
    'Apache','PATH_TRANSLATED'
    ,'nginx','QUERY_STRING'
    );
my $input=$ENV{$httpd{$serverName}};
my $ext=$input;

# Determine the file type (asciidoc/markdown/org/restructured text)
# and choose the corresponding converter
my %sgml=(
    'asciidoc','\.(adoc|txt)'
    ,'markdown','\.md'
    ,'org','\.org'
    ,'rst','\.rst'
    );
my %processor=(
    'asciidoc',"/opt/local/bin/asciidoctor -a last-update-label! -o - '%s'"
    ,'markdown',"/usr/local/bin/pandoc '%s'"
    ,'org',"/usr/local/bin/pandoc '%s'"
    ,'rst',"/usr/local/bin/pandoc '%s'"
    );
my $cmd;
foreach my $key (keys %sgml) {
    if ($input =~ /$sgml{$key}/) {
    $cmd=sprintf("$processor{$key}",$input);
    last;
    }
}

use CGI ':all';
use utf8;
use open ':encoding(utf8)';
binmode(STDOUT, ":utf8");
print header;
#print "<pre>\ninput=".$input."\noutput=".$output."\next=".$ext."\ncmd=".$cmd."\n</pre>\n";
system("$cmd");
| improve this answer | |
  • thanks for the comment. Yes it would be nice to have the code. Too big to post it here? – Picaud Vincent Jan 24 at 9:26
0

I came to this solution, that do what I wanted:

  • calls a shell command I have written in C++ code_to_org that transforms some source code into an org mode compatible document
  • exports it to a html file and starts the web-browser to visualize it.

.

(defun my-code-to-html()
  (interactive)
  (save-buffer)
  (setq current_buffer (current-buffer))
  (setq current_filename (buffer-file-name))
  (with-temp-buffer
    (shell-command (concat "code_to_org " current_filename) (current-buffer))
    (org-open-file (org-export-to-file 'html (concat current_filename ".html")))
    )
  )
| improve this answer | |
  • 2
    Good! --- btw, you might want to look into learning how to use the let form in elisp. setq creates global variables, which can eventually catch up with you. let (and its sister let*) create local variables that disappear when it's done. Cheers! – Sue D. Nymme Jan 25 '19 at 15:08
  • Thank you for your clarification @SueD.Nymme. That is one of my regret, not having learnt (emacs) lisp. I must do that. – Picaud Vincent Jan 25 '19 at 15:19
0

My org-mode version is 9.4, Emacs version is 25.1.50.1.

I'd do

(org-open-file (org-html-export-to-html))

to programmatically export the org buffer to html and open it in a browser.

I looked for the definition function org-html-export-to-html and looked around in the same file, stopping where the shortcut menu is defined:

(?o "As HTML file and open"
    (lambda (a s v b)
      (if a (org-html-export-to-html t s v b)
    (org-open-file (org-html-export-to-html nil s v b)))))

With trace-function of org-html-export-to-html I saw that its arguments were all nil, and as the whole arglist is optional, it may be omitted.

| improve this answer | |
New contributor
Christian Nybø is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
  • BTW, 25.1.50 is a bleeding-edge (i.e. code in-development) from 3-4 years ago. You're strongly encouraged to upgrade to either the current bleeding edge (28.0.50) or to a released version of Emacs. – Stefan 15 hours ago

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.