logoalt Hacker News

vogelke • today at 7:13 AM • 0 replies • view on HN

If you can suppress your gag reflex, M4 can do some of what you want. sinclude(...) will include a file and be silent in case of failure. I did something like this for user-login history because I couldn't use PHP or Perl:

    me% cat index.m4
    <!DOCTYPE html>
    <html>
      <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Better user history</title>
        <link rel="stylesheet" href="local.css">
      </head>

      <body>
          <h3>Users</h3>
          <ul>
            <li><em>By username</em></li>
            <ul>
    sinclude(`byuser.m4')dnl
            </ul>
            <li><em>By last login date</em></li>
            <ul>
    sinclude(`bydate.m4')dnl
            </ul>
          </ul>
    sinclude(`footer.m4')dnl
      </body>
    </html>

    me% cat byuser.m4
    <li><a href="byuser/A-L">A-L</a></li>
    <li><a href="byuser/M-Z">M-Z</a></li>

    me% cat bydate.m4
    <li><a href="bydate/2025">2025</a></li>
    <li><a href="bydate/2026">2026</a></li>

    me% cat footer.m4
    <p><em>Last update: syscmd(`date | tr -d "\n"')</em>

    me% m4 index.m4 > index.htm

    me% cat index.htm
    <!DOCTYPE html>
    <html>
      <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Better user history</title>
        <link rel="stylesheet" href="local.css">
      </head>

      <body>
          <h3>Users</h3>
          <ul>
            <li><em>By username</em></li>
            <ul>
    <li><a href="byuser/A-L">A-L</a></li>
    <li><a href="byuser/M-Z">M-Z</a></li>
            </ul>
            <li><em>By last login date</em></li>
            <ul>
    <li><a href="bydate/2025">2025</a></li>
    <li><a href="bydate/2026">2026</a></li>
            </ul>
          </ul>
    <p><em>Last update: Mon Oct 12 03:08:32 EDT 2026</em>
      </body>
    </html>