<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://stratum0.org/mediawiki/index.php?action=history&amp;feed=atom&amp;title=Benutzer%3ADaniel_Bohrer%2FSemantic_M4rkup</id>
	<title>Benutzer:Daniel Bohrer/Semantic M4rkup - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://stratum0.org/mediawiki/index.php?action=history&amp;feed=atom&amp;title=Benutzer%3ADaniel_Bohrer%2FSemantic_M4rkup"/>
	<link rel="alternate" type="text/html" href="https://stratum0.org/mediawiki/index.php?title=Benutzer:Daniel_Bohrer/Semantic_M4rkup&amp;action=history"/>
	<updated>2026-04-24T02:44:10Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in Stratum 0</subtitle>
	<generator>MediaWiki 1.31.2</generator>
	<entry>
		<id>https://stratum0.org/mediawiki/index.php?title=Benutzer:Daniel_Bohrer/Semantic_M4rkup&amp;diff=14162&amp;oldid=prev</id>
		<title>Daniel Bohrer: &quot;Slides&quot;</title>
		<link rel="alternate" type="text/html" href="https://stratum0.org/mediawiki/index.php?title=Benutzer:Daniel_Bohrer/Semantic_M4rkup&amp;diff=14162&amp;oldid=prev"/>
		<updated>2016-10-14T20:07:31Z</updated>

		<summary type="html">&lt;p&gt;&amp;quot;Slides&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         ____                             _   _        __  __            _                      &lt;br /&gt;
        / ___|  ___ _ __ ___   __ _ _ __ | |_(_) ___  |  \/  | __ _ _ __| | ___   _ _ __        &lt;br /&gt;
        \___ \ / _ \ &amp;#039;_ ` _ \ / _` | &amp;#039;_ \| __| |/ __| | |\/| |/ _` | &amp;#039;__| |/ / | | | &amp;#039;_ \       &lt;br /&gt;
         ___) |  __/ | | | | | (_| | | | | |_| | (__  | |  | | (_| | |  |   &amp;amp;lt;| |_| | |_) |      &lt;br /&gt;
        |____/ \___|_| |_| |_|\__,_|_| |_|\__|_|\___| |_|  |_|\__,_|_|  |_|\_\\__,_| .__/       &lt;br /&gt;
                                                                                   |_|          &lt;br /&gt;
                                  with the M4 macro processor                                &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
= M4 =&lt;br /&gt;
&lt;br /&gt;
* Kernighan &amp;amp;amp; Ritchie, 1977&lt;br /&gt;
* part of almost every Unix/Linux distribution&lt;br /&gt;
* Heavily used in GNU &amp;lt;code&amp;gt;autotools&amp;lt;/code&amp;gt;&lt;br /&gt;
* Simple mechanism:&lt;br /&gt;
** define macros&lt;br /&gt;
** when macro token is found in input, replace token with definition&lt;br /&gt;
** write input to output&lt;br /&gt;
&lt;br /&gt;
= Example 1: Hello World(?) =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$ cat 01-helloworld.m4&lt;br /&gt;
define(HELLO, Ohai)dnl&lt;br /&gt;
HELLO world.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;$ m4 01-helloworld.m4&lt;br /&gt;
Ohai world.&amp;lt;/pre&amp;gt;&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;dnl&amp;lt;/code&amp;gt;: Discard to Next Line&lt;br /&gt;
** &amp;amp;quot;comments&amp;amp;quot;&lt;br /&gt;
** prevents unwanted whitespace in output&lt;br /&gt;
&lt;br /&gt;
= Example 2 =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$ cat 02-more-hello.m4&lt;br /&gt;
define(Nice, Happy)dnl&lt;br /&gt;
define(HELLO, Nice to meet you)dnl&lt;br /&gt;
HELLO World.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;$ m4 02-more-hello.m4&lt;br /&gt;
Happy to meet you World.&amp;lt;/pre&amp;gt;&lt;br /&gt;
What happened?&lt;br /&gt;
&lt;br /&gt;
= Example 2: step by step =&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;| Input&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;| Macro definitions&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;amp;gt; define(Nice, Happy)dnl              &lt;br /&gt;
  define(HELLO, Nice to meet you)dnl&lt;br /&gt;
  HELLO World.&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;| Input&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;| Macro definitions&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;amp;gt;                                     &lt;br /&gt;
  define(HELLO, Nice to meet you)dnl&lt;br /&gt;
  HELLO World.&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
# Nice → Happy&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;| Input&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;| Macro definitions&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;                                      &lt;br /&gt;
&amp;amp;gt; define(HELLO, Nice to meet you)dnl&lt;br /&gt;
  HELLO World.&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
# Nice → Happy&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;| Input&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;| Macro definitions&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;                                      &lt;br /&gt;
&amp;amp;gt; define(HELLO, Happy to meet you)dnl&lt;br /&gt;
  HELLO World.&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
# Nice → Happy&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;| Input&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;| Macro definitions&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;                                      &lt;br /&gt;
&amp;amp;gt;&lt;br /&gt;
  HELLO World.&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
# Nice → Happy&lt;br /&gt;
# HELLO → Happy to meet you&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;| Input&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;| Macro definitions&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;                                      &lt;br /&gt;
&lt;br /&gt;
&amp;amp;gt; HELLO World.&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
# Nice → Happy&lt;br /&gt;
# HELLO → Happy to meet you&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;| Input&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;| Macro definitions&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;                                      &lt;br /&gt;
&lt;br /&gt;
&amp;amp;gt; Happy to meet you World.&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
# Nice → Happy&lt;br /&gt;
# HELLO → Happy to meet you&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Expansion Rules (1) =&lt;br /&gt;
&lt;br /&gt;
# Macro expansion is recursive&lt;br /&gt;
#* macros inside of macros are evaluated first (unless quoted)&lt;br /&gt;
#* &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt; is a macro itself&lt;br /&gt;
&lt;br /&gt;
But maybe we don&amp;#039;t want that.&lt;br /&gt;
&lt;br /&gt;
= Quoting =&lt;br /&gt;
&lt;br /&gt;
Quoting prevents unwanted macro replacement&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$ cat 03-quoting.m4&lt;br /&gt;
define(`Nice&amp;#039;, `Happy&amp;#039;)dnl&lt;br /&gt;
define(`HELLO&amp;#039;, ``Nice&amp;#039; to meet you&amp;#039;)dnl&lt;br /&gt;
HELLO World.&lt;br /&gt;
&lt;br /&gt;
$ m4 02-quoting.m4&lt;br /&gt;
Nice to meet you World.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Parametric Macros =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$ cat 04-params.m4&lt;br /&gt;
define(`HEADING&amp;#039;, `&amp;amp;lt;h1 id=&amp;amp;quot;$1&amp;amp;quot;&amp;amp;gt;$2&amp;amp;lt;/h1&amp;amp;gt;&amp;#039;)dnl&lt;br /&gt;
define(`PARA&amp;#039;,    `&amp;amp;lt;p id=&amp;amp;quot;$1&amp;amp;quot;&amp;amp;gt;$2&amp;amp;lt;/p&amp;amp;gt;&amp;#039;)dnl&lt;br /&gt;
define(`ITALIC&amp;#039;,  `&amp;amp;lt;i&amp;amp;gt;$1&amp;amp;lt;/i&amp;amp;gt;&amp;#039;)dnl&lt;br /&gt;
dnl&lt;br /&gt;
HEADING(title, `This is the title&amp;#039;)&lt;br /&gt;
PARA(first_para, This is rendered as text. Parameters can even span&lt;br /&gt;
multiple lines. If you include commas`,&amp;#039; be sure to include quotes.)&lt;br /&gt;
PARA(second_para, This is normal text. ITALIC(This is italic.))&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;$ m4 04-params.m4 &lt;br /&gt;
&amp;amp;lt;h1 id=&amp;amp;quot;title&amp;amp;quot;&amp;amp;gt;This is the title&amp;amp;lt;/h1&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;p id=&amp;amp;quot;first_para&amp;amp;quot;&amp;amp;gt;This is rendered as text. Parameters can even span&lt;br /&gt;
multiple lines. If you include commas, be sure to include quotes.&amp;amp;lt;/p&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;p id=&amp;amp;quot;second_para&amp;amp;quot;&amp;amp;gt;This is normal text. &amp;amp;lt;i&amp;amp;gt;This is italic.&amp;amp;lt;/i&amp;amp;gt;&amp;amp;lt;/p&amp;amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Expansion Rules (2) =&lt;br /&gt;
&lt;br /&gt;
# Quoted text is simply stripped of the quotes&lt;br /&gt;
# Macro expansion is recursive&lt;br /&gt;
#* macros inside of macros are evaluated first (unless quoted)&lt;br /&gt;
#** inner macros can generate more parameters for outer macros&lt;br /&gt;
# Leading whitespace of parameters is removed&lt;br /&gt;
# The expansion of a macro is always re-evaluated&lt;br /&gt;
#* read: &amp;amp;quot;strip one layer of quoting, or expand again&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
Rule of thumb:&lt;br /&gt;
&lt;br /&gt;
* One quoting level per parentheses.&lt;br /&gt;
&lt;br /&gt;
= You probably noticed =&lt;br /&gt;
&lt;br /&gt;
M4 macros are a great way to build semantic markup.&lt;br /&gt;
&lt;br /&gt;
* Semantics:&lt;br /&gt;
** Wikipedia: “the linguistic, and also philosophical study of meaning”&lt;br /&gt;
** more than only formatting&lt;br /&gt;
** ideally machine-readable&lt;br /&gt;
&lt;br /&gt;
= For example =&lt;br /&gt;
&lt;br /&gt;
* Write your meeting minutes in Markdown, using a “public macro interface” for e.g.:&lt;br /&gt;
** votes&lt;br /&gt;
** resolutions&lt;br /&gt;
** TODOs&lt;br /&gt;
* Write an M4 library for each output&lt;br /&gt;
** define the “public macro interface” accordingly&lt;br /&gt;
* Use the markup with multiple M4 “libraries” to convert your minutes to:&lt;br /&gt;
** human-readable formats like Markdown&lt;br /&gt;
*** with consistent formatting&lt;br /&gt;
*** via pandoc: HTML, ReST, LaTeX, PDF, …&lt;br /&gt;
** machine-readable formats like JSON, CSV, XML, …&lt;br /&gt;
&lt;br /&gt;
See: https://github.com/rohieb/minutes-m4rkup&lt;br /&gt;
&lt;br /&gt;
= example.m4rkdown =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;MEETING_MINUTES(Board meeting, 2016-09-01, 20:00,&lt;br /&gt;
    [Adam Ant, Henrietta Horse, Beatrice Bull], [Ephraim Elephant], [Adam Ant])&lt;br /&gt;
&lt;br /&gt;
We talked about things for a while.&lt;br /&gt;
&lt;br /&gt;
* RESOLUTION(Resolution 2016-00, VOTE_ADOPTED(3,0,0), World Domination)&lt;br /&gt;
* TODO(T2016-03, Adam Ant, Build Doomsday Machine)&lt;br /&gt;
* Recent TODOs:&lt;br /&gt;
    * TODO(T2016-02, , Try out LAZZZORs from Evil Corp., [&lt;br /&gt;
        * They make nice, cheap LAZZZORS&lt;br /&gt;
        * LAZZZORS are needed for Doomsday Machine])&lt;br /&gt;
    * DONE(T2016-01, Beatrice Bull, Buy some space rockets)&lt;br /&gt;
END(21:00)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= example.markdown =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Board meeting 2016-09-01&lt;br /&gt;
========================&lt;br /&gt;
&lt;br /&gt;
* Starting time: 20:00&lt;br /&gt;
* Attending: Adam Ant, Henrietta Horse, Beatrice Bull&lt;br /&gt;
* Absent: Ephraim Elephant&lt;br /&gt;
* Minute taker: Adam Ant&lt;br /&gt;
&lt;br /&gt;
We talked about things for a while.&lt;br /&gt;
&lt;br /&gt;
* __Resolution 2016-00 ✔ (3|0|0):__ World Domination&lt;br /&gt;
* __TODO Adam Ant:__ Build Doomsday Machine&lt;br /&gt;
* Recent TODOs:&lt;br /&gt;
    * __TODO:__ Try out LAZZZORs from Evil Corp.. &lt;br /&gt;
        * They make nice, cheap LAZZZORS&lt;br /&gt;
        * LAZZZORS are needed for Doomsday Machine&lt;br /&gt;
    * ~~__DONE Beatrice Bull:__ Buy some space rockets~~&lt;br /&gt;
* Ending at 21:00&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= example.json =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;{&lt;br /&gt;
  &amp;amp;quot;metadata&amp;amp;quot;: { &amp;amp;quot;type&amp;amp;quot;: &amp;amp;quot;Board meeting&amp;amp;quot;,&amp;amp;quot;date&amp;amp;quot;: &amp;amp;quot;2016-09-01&amp;amp;quot;, &amp;amp;quot;start_time&amp;amp;quot;: &amp;amp;quot;20:00&amp;amp;quot;,&lt;br /&gt;
    &amp;amp;quot;attendants&amp;amp;quot;: &amp;amp;quot;Adam Ant, Henrietta Horse, Beatrice Bull&amp;amp;quot;,&lt;br /&gt;
    &amp;amp;quot;absentees&amp;amp;quot;: &amp;amp;quot;Ephraim Elephant&amp;amp;quot;, &amp;amp;quot;keeper_of_minutes&amp;amp;quot;: &amp;amp;quot;Adam Ant&amp;amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;amp;quot;content&amp;amp;quot;: [ &lt;br /&gt;
    { &amp;amp;quot;type&amp;amp;quot;: &amp;amp;quot;resolution&amp;amp;quot;, &amp;amp;quot;public&amp;amp;quot;: true, &amp;amp;quot;ref&amp;amp;quot;: &amp;amp;quot;Resolution 2016-00&amp;amp;quot;,&lt;br /&gt;
      &amp;amp;quot;vote&amp;amp;quot;: { &amp;amp;quot;approved&amp;amp;quot;: true, &amp;amp;quot;pro&amp;amp;quot;: 3, &amp;amp;quot;contra&amp;amp;quot;: 0, &amp;amp;quot;abstain&amp;amp;quot;: 0 },&lt;br /&gt;
      &amp;amp;quot;text&amp;amp;quot;: &amp;amp;quot;World Domination&amp;amp;quot;, &amp;amp;quot;allocated_money&amp;amp;quot;: &amp;amp;quot;&amp;amp;quot;, &amp;amp;quot;notes&amp;amp;quot;: &amp;amp;quot;&amp;amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    { &amp;amp;quot;type&amp;amp;quot;: &amp;amp;quot;todo&amp;amp;quot;, &amp;amp;quot;public&amp;amp;quot;: true, &amp;amp;quot;done&amp;amp;quot;: false, &amp;amp;quot;ref&amp;amp;quot;: &amp;amp;quot;T2016-03&amp;amp;quot;,&lt;br /&gt;
      &amp;amp;quot;assigned&amp;amp;quot;: &amp;amp;quot;Adam Ant&amp;amp;quot;, &amp;amp;quot;text&amp;amp;quot;: &amp;amp;quot;Build Doomsday Machine&amp;amp;quot;,&lt;br /&gt;
      &amp;amp;quot;notes&amp;amp;quot;: &amp;amp;quot;&amp;amp;quot; },&lt;br /&gt;
    { &amp;amp;quot;type&amp;amp;quot;: &amp;amp;quot;todo&amp;amp;quot;, &amp;amp;quot;public&amp;amp;quot;: true, &amp;amp;quot;done&amp;amp;quot;: false, &amp;amp;quot;ref&amp;amp;quot;: &amp;amp;quot;T2016-02&amp;amp;quot;,&lt;br /&gt;
      &amp;amp;quot;assigned&amp;amp;quot;: &amp;amp;quot;&amp;amp;quot;, &amp;amp;quot;text&amp;amp;quot;: &amp;amp;quot;Try out LAZZZORs from Evil Corp.&amp;amp;quot;, &amp;amp;quot;notes&amp;amp;quot;:&amp;amp;quot;&lt;br /&gt;
  * They make nice, cheap LAZZZORS&lt;br /&gt;
  * LAZZZORS are needed for Doomsday Machine&amp;amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    { &amp;amp;quot;type&amp;amp;quot;: &amp;amp;quot;todo&amp;amp;quot;, &amp;amp;quot;public&amp;amp;quot;: true, &amp;amp;quot;done&amp;amp;quot;: true, &amp;amp;quot;ref&amp;amp;quot;: &amp;amp;quot;T2016-01&amp;amp;quot;,&lt;br /&gt;
      &amp;amp;quot;assigned&amp;amp;quot;: &amp;amp;quot;Beatrice Bull&amp;amp;quot;, &amp;amp;quot;text&amp;amp;quot;: &amp;amp;quot;Buy some space rockets&amp;amp;quot;, &amp;amp;quot;notes&amp;amp;quot;: &amp;amp;quot;&amp;amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;amp;quot;end_time&amp;amp;quot;: &amp;amp;quot;21:00&amp;amp;quot;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Daniel Bohrer</name></author>
		
	</entry>
</feed>