0

I am using literate programming in org mode. It adds a new syntactic construction to the language: <<macro name>>. Unfortunately, it breaks all the colouring and tabulation after it. For example, this code in cperl-mode:

my $redis = $c->app->storage('redis');

<<get session id from cookie>>

# checking login, password
my $login = $c->param('login');

is rendered as this:

enter image description here

I tried to colourize the new keyword for cperl mode:

(font-lock-add-keywords 'cperl-mode '(("<<.+?>>" . 'font-lock-variable-name-face)))

But it only changes the colour of the first word: as you can see the word "get" is red.

How to set the specific colour for constructions like <<...>> and setup correct tabs after it?

1
  • The problem is that Org mode colorizes the code block according the declared language (perl in this case I presume), but the noweb syntax is not perl. It is a stretch already for Org mode to keep the rest of the file colorized according to Org syntax while allowing code blocks to be colorized according to a different mode; mixing yet another mode in there just complicates things further. In short, I don't know how to do it, and I think it is going to be complicated. If you don't get an answer here, you might want to ask on the Org ML.
    – NickD
    Commented May 10, 2023 at 15:29

1 Answer 1

1

The challenge here is that in cperl-mode some Perl syntax is treated beyond font-lock-mode. In Perl, "<<" starts a here-document, in your example taking "get" as the delimiter of the here-document. cperl-mode acts accordingly and fontifies "get" as the here-doc delimiter. It also takes the rest of your document as the content of the here-doc and fontifies it as string. This happens outside of font-lock. The rest of the <<...>> line is fontified according to your added rule.

You can, sort of, get what you want by fiddling with the syntax of your noweb blocks:

#+NAME: [say hello]
#+BEGIN_SRC perl
say "Hello, world";
#+END_SRC

#+BEGIN_SRC perl :noweb yes :results output
  use 5.024;

  {
      <<[say hello]>>
  }

  say "Hello again!";
#+END_SRC

In this example, I started the code block id with a square bracket. This works for org-mode. But square brackets are illegal as here-doc delimiters, and cperl-mode respects that. So, the last line of the source block will be fontified as Perl code.

The extra braces { } around the macro are needed if you want the indentation after your macro to be correct in cperl-mode: The noweb line is an "incomplete statement", so the next line would be interpreted as a continuation line.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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