Skip to content

Latest commit

 

History

History
110 lines (85 loc) · 3.9 KB

v2mdman.md

File metadata and controls

110 lines (85 loc) · 3.9 KB

man pages: write in Markdown, maintain by Git, release in *roff

what

This is a technique which permits:

  • to write tha man pages in markdown
  • an easy management of the man pages using git and cmake
  • to avoid the dependence from the markdown translator to release the source tree or for the source packages of Linux distributions.

why

It is doubtless that the *roff syntax is obsolete and boring

how

We have integrated pandoc in our developing process.

Man pages are in a specific directory named man. The CMakeLists.txt include just one line regarding the man pages:

add_subdirectory(man)

The file man/CMakeLists.txt translates all the files with .[1-8].md suffix in man pages .[1.8] using pandoc and storing the result in the source tree (not in the build tree) using a makefile. So if the man page is newer than the markdown source the translation phase is skipped. So pandoc is needed only to build the man pages if the markdown source has been updated. In this way git can track the versions both of the markdown source and of the *roff man pages.

Neither man/CMakeLists.txt nor man/Makefile have project specific definitions, so both can be copied in any new project.

details

This is man/CMakeLists.txt:

cmake_minimum_required(VERSION 3.7)

set(PANDOC_ORG "VirtualSquare")

# ### pandoc pages

file(GLOB VU_PANDOC_PAGES ${CMAKE_CURRENT_SOURCE_DIR}/*.[1-8].md)
set(VU_MAN_FILES)
foreach(VU_PANDOC_PATH IN LISTS VU_PANDOC_PAGES)
# VU_PANDOCPAGE: basename of VU_PANDOC_PATH
	get_filename_component(VU_PANDOCPAGE ${VU_PANDOC_PATH} NAME)
# VU_MANPAGE: VU_PANDOCPAGE without the suffix
	string(REGEX REPLACE "\.md$" "" VU_MANPAGE ${VU_PANDOCPAGE})
	list(APPEND VU_MAN_FILES ${VU_MANPAGE})
endforeach(VU_PANDOC_PATH)

add_custom_target(${PROJECT_NAME}_manpages ALL make PANDOC_ORG="${PANDOC_ORG}"  ${VU_MAN_FILES}
	WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})

### man pages
file(GLOB VU_MAN_PAGES ${CMAKE_CURRENT_SOURCE_DIR}/*.[1-8])
foreach(VU_MAN_PATH IN LISTS VU_MAN_PAGES)
	get_filename_component(VU_MANPAGE ${VU_MAN_PATH} NAME)
	string(REGEX REPLACE ".*\\." "" MAN_CHAPTER ${VU_MANPAGE})
	install(FILES ${VU_MAN_PATH} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_CHAPTER})
endforeach(VU_MAN_PATH)

The code after the comment ### pandoc pages creates a list (VU_MAN_FILES) including all the pages that can be generated by pandoc (i.e. a list of all the .md files without the suffix).

The target ${PROJECT_NAME}_manpages runs make o create/update these man pages (if needed).

The code after the comment ### man pages installs the man pages (generated by pandoc or simply written in *roff) in the right chapter.

and this is man/Makefile:

PANDOC=pandoc
PANDOCOK := $(shell command -v ${PANDOC} 2> /dev/null)

none:

% : %.md
ifdef PANDOCOK
# copy copyright notice
		grep "^\.\\\\\"" $< > $@ || true
# run pandoc
		$(eval SECTION := $(subst .,,$(suffix $@)))
		$(eval BASENAME := $(basename $@))
		$(eval TITLE := $(shell echo "${BASENAME}\(${SECTION}\)" | tr [:lower:] [:upper:]))
		$(eval HEADER := "$(shell man ${SECTION} intro | head -1 | sed -e 's/^[^[:blank:]]*[[:blank:]]*//' -e 's/[[:blank:]]*[^[:blank:]]*$$//' )")
		$(PANDOC) -standalone -M title=${TITLE} -M section=${SECTION} -M header=${HEADER} -M footer=${PANDOC_ORG} -M "date=`date +\"%B %Y\"`" --to man $< >> $@
else
		echo "${PANDOC} is not available. Manpage $@ cannot be updated" >/dev/stderr >&2
endif

This Makefile calls pandoc to create the man pages. There is a workaround to copy the copyright notice from the markdown source.

where

Many projects: vdeplug_slirp, libvolatilestream, libvpoll-eventfd, libfduserdata, vdeplug_pcap, vdeplug_vdesl, nlinline, randmac, libvdeslirp, libstropt, vuos, vdeplug_vlan, libvdestack, ...

Note: the markdown source was formerly translated using ronn instead of pandoc. We are currently converting the projects' man pages.

references:

pandoc