2

I'm trying to figure out a good workflow for printing source code and studying it.

So far, the TOhtml function seems really useful for this purpose. I can create an html file with ease, open it in a browser and get a source code listing with extremely legible line numbers.

My only complaint is that the resulting HTML file tries to mimic my white text on a dark background.

For instance, foo.txt

Line 1
Line 2

Which looks like this in my terminal

   1 Line 1
   2 Line 2
~
~
~
~
~
~
~
~
foo.txt

produces the following output:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>~/tmp/foo.txt.html</title>
<meta name="Generator" content="Vim/8.1">
<meta name="plugin-version" content="vim8.1_v1">
<meta name="syntax" content="none">
<meta name="settings" content="number_lines,use_css,no_foldcolumn,expand_tabs,line_ids,prevent_copy=">
<meta name="colorscheme" content="least">
<style type="text/css">
<!--
pre { font-family: monospace; color: #ffffff; background-color: #000000; }
body { font-family: monospace; color: #ffffff; background-color: #000000; }
* { font-size: 1em; }
.LineNr { color: #008080; font-weight: bold; }
-->
</style>

<script type='text/javascript'>
<!--

/* function to open any folds containing a jumped-to line before jumping to it */
function JumpToLine()
{
  var lineNum;
  lineNum = window.location.hash;
  lineNum = lineNum.substr(1); /* strip off '#' */

  if (lineNum.indexOf('L') == -1) {
    lineNum = 'L'+lineNum;
  }
  var lineElem = document.getElementById(lineNum);
  /* Always jump to new location even if the line was hidden inside a fold, or
   * we corrected the raw number to a line ID.
   */
  if (lineElem) {
    lineElem.scrollIntoView(true);
  }
  return true;
}
if ('onhashchange' in window) {
  window.onhashchange = JumpToLine;
}

-->
</script>
</head>
<body onload='JumpToLine();'>
<pre id='vimCodeElement'>
<span id="L1" class="LineNr">1 </span>Line 1
<span id="L2" class="LineNr">2 </span>Line 2
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->

I've tried disabling CSS via

let g:html_use_css = 0

but the resulting html file still mimics the colorscheme of my current vim configuration.

It seems like there should be a dedicated way to say "export this code as HTML in a way that will look nice when printed or viewed in a browser instead of mimicking what I see in my terminal".

I have found a 30% solution. Just call sed on the html that vim generates with css generation disabled. It will do in a pinch but seems less than ideal.

It is possible to manually adjust the colors with sed. This intentionally ugly command line avoids differences between BSD and GNU sed.

< foo.txt.html sed \
's/bgcolor="#......"/bgcolor="#ffffff"/;s/text="#......"/text="#000000"/' \
> /tmp/a.html ; \
cp /tmp/a.html foo.txt.html
1

In terminal Vim, the background for the HTML is derived from the option background. If it is set to dark, the HTML background is black. If light the HTML background is white. The colors are fixed. Changing the Vim colorscheme does not change the colors used in HTML.

In GVim the colors in the HTML match the colorscheme. If you use the colorscheme "default", you get a white background.


Another way would be to post-process the generated HTML and remove the internal CSS and replace it with a link to a external CSS file. You could then prepare a external CSS that fits your needs.

I don't know if this fits with your planed workflow. Anyway here is a quick-hack example:

let DEFAULT_CSS="My-default-css-file.css"

function! MyToHtml(bang, css)
    let myCss=g:DEFAULT_CSS
    if !empty(a:css)
        let myCss = a:css
    endif

    " Create HTML
    TOhtml

    " if bang is given, write a css file. Name derived from html file
    " but with extension 'css'
    if !empty(a:bang)
        let cssFilename = substitute(expand("%"), '\.html$', '.css', '')
        execute '/^<style type="text\/css">/+2;/^<\/style>/-2 write! ' . cssFilename
        call cursor(1, 1)
    endif

    " delete the inline css code and replace it with a stylesheet link
    execute '/^<style type="text\/css">/;/^<\/style>/d'
    put! ='<link rel=\"stylesheet\" href=\"' . myCss . '\">'

endfunc


" Usage:
" MyToHtml[!] [css-file]
" If bang (!) is given, write css-file from css found in html
" If css-file is given use this as css-file
" If css-file is NOT given use css-file set in g:DEFAULT_CSS
command! -bang -nargs=? MyToHtml call MyToHtml(<q-bang>, <q-args>)

  • I think there is an empty function, to avoid comparing to the empty string. – D. Ben Knoble Mar 21 at 14:03
  • @D.BenKnoble Yes, empty() works. Updated. – Ralf Mar 22 at 6:05

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.