summaryrefslogtreecommitdiff
path: root/IkiWiki/Plugin/highlight.pm
blob: f43f18628cf783d8c6bd7075fc79a51ab9c82cc9 (plain)
  1. #!/usr/bin/perl
  2. package IkiWiki::Plugin::highlight;
  3. use warnings;
  4. use strict;
  5. use IkiWiki 3.00;
  6. use highlight;
  7. # locations of highlight's files
  8. my $filetypes="/etc/highlight/filetypes.conf";
  9. my $langdefdir="/usr/share/highlight/langDefs";
  10. sub import {
  11. hook(type => "getsetup", id => "highlight", call => \&getsetup);
  12. hook(type => "checkconfig", id => "highlight", call => \&checkconfig);
  13. }
  14. sub getsetup () {
  15. return
  16. plugin => {
  17. safe => 1,
  18. rebuild => 1, # format plugin
  19. },
  20. tohighlight => {
  21. type => "string",
  22. example => ".c, .h, .cpp, .pl, .py, Makefile:make",
  23. description => "source files to syntax highlight",
  24. safe => 1,
  25. rebuild => 1,
  26. },
  27. }
  28. sub checkconfig () {
  29. if (exists $config{tohighlight}) {
  30. foreach my $file (split /, /, $config{tohighlight}) {
  31. my @opts = $file=~s/^\.// ?
  32. (keepextension => 1) :
  33. (noextension => 1);
  34. my $ext = $file=~s/:(.*)// ? $1 : $file;
  35. my $langfile=ext2langfile($ext);
  36. if (! defined $langfile) {
  37. error(sprintf(gettext(
  38. "tohighlight contains unknown file type '%s'"),
  39. $ext));
  40. }
  41. hook(
  42. type => "htmlize",
  43. id => $file,
  44. call => sub {
  45. my %params=@_;
  46. highlight($langfile, $params{content});
  47. },
  48. longname => sprintf(gettext("Source code: %s"), $file),
  49. @opts,
  50. );
  51. }
  52. }
  53. }
  54. my %ext2lang;
  55. my $filetypes_read=0;
  56. # Parse highlight's config file to get extension => language mappings.
  57. sub read_filetypes () {
  58. open (IN, $filetypes);
  59. while (<IN>) {
  60. chomp;
  61. if (/^\$ext\((.*)\)=(.*)$/) {
  62. $ext2lang{$_}=$1 foreach $1, split ' ', $2;
  63. }
  64. }
  65. close IN;
  66. $filetypes_read=1;
  67. }
  68. sub langfile ($) {
  69. return "$langdefdir/$_[0].lang";
  70. }
  71. # Given a filename extension, determines the language definition to
  72. # use to highlight it.
  73. sub ext2langfile ($) {
  74. my $ext=shift;
  75. read_filetypes() unless $filetypes_read;
  76. if (exists $ext2lang{$ext}) {
  77. return langfile($ext2lang{$ext});
  78. }
  79. # If a language only has one common extension, it will not
  80. # be listed in filetypes, so check the langfile.
  81. elsif (-e langfile($ext)) {
  82. return langfile($ext);
  83. }
  84. else {
  85. return undef;
  86. }
  87. }
  88. # Interface to the highlight C library.
  89. sub highlight ($$) {
  90. my $langfile=shift;
  91. my $input=shift;
  92. my $gen = highlightc::CodeGenerator_getInstance($highlightc::XHTML);
  93. $gen->setFragmentCode(1); # generate html fragment
  94. $gen->setHTMLEnclosePreTag(1); # include stylish <pre>
  95. $gen->initLanguage($langfile);
  96. $gen->initTheme("/dev/null"); # theme is not needed because CSS is not emitted
  97. $gen->setEncoding("utf-8");
  98. my $output=$gen->generateString($input);
  99. highlightc::CodeGenerator_deleteInstance($gen);
  100. return $output;
  101. }
  102. 1