#!/bin/sh # SPDX-FileCopyrightText: 2025 Lady # SPDX-License-Identifier: MPL-2.0 SHELL = /bin/sh # This Source Code Form is subject to the terms of the Mozilla Public License, v 2.0. # If a copy of the M·P·L was not distributed with this file, You can obtain one at . # This make·file should be run from the root of the source directory. CAT := cat GIT := git MKDIR := mkdir PRINTF := printf SED := gsed TEST := test XARGS := xargs XSLTPROC := xsltproc LESML := LesML DOCDIR := doc PROJECT_NAME := C·Girls HEADER_FILES = $(sort $(patsubst ./%,%,$(shell find . '(' -path '.' -o -prune ')' -a -type f -a -name '*.h'))) DOCUMENTATION_FILES = $(patsubst %.h,$(DOCDIR)/%.xhtml,$(HEADER_FILES)) documentation : $(DOCDIR)/README.xhtml $(DOCUMENTATION_FILES) $(DOCDIR)/index.xhtml ; # (callable) Strip portions between `(*´ and `*)´ and collapse newlines in the argument. # Backslash sequences in the argument are handled ⅌ `printf´. # Single quotes must not appear in the argument or this will break. makeunreadable = $(shell LANG=C LC_ALL=C printf '%s\n' '$(subst $(newline),$(space),$1)' | $(SED) 's/^[ ]*//;s/[ ]*$$//;s/[ ]*([*][^*]*[*])[ ]*//g' | $(XARGS) -0 $(PRINTF) '%b\n') define readablesedcmd \\@^/[*]$$@,\\@^[\t]*[*]/$$@d; (*delete multiline comments*) \\@^/[*][^*]*.?[^/]*[*]/$$@d; (*delete singleline traditional comments*) \\@^//@d; (*delete singleline newstyle comments*) \\@^/[*][*]$$@s@^.*$$@@; (*delete start of documentation comments (leaving newline)*) \\@^ [*][*]//*$$@s@^.*$$@@; (*delete end of documentation comments (leaving newline)*) \\@^ [*][*]$$@s@$$@ @; (*add trailing space to empty documentation comment lines*) \\@^ [*][*] @!{ (*format non·empty lines of code*) s@/[*]\\([^* ]*\\)[*]/@\\1@g; (*explicit formatting*) \\@/[*][^ ]*[*]/@!{ (*autoformat lines without explicit formatting*) s@^\0043ifndef \\([^ ]*\\)@\0043ifndef ⟨\\1⟩@; (*macro ifndef*) s@^\0043define \\([^ ]*\\)@\0043define ⟨\\1⟩@; (*macro define*) s@^\0043endif /[*] \\([^ ]*\\) [*]/@\0043endif /* ⟨\\1⟩ */@; (*macro define*) \\@\t*[?:]@!s@^\\(\t\t*\\)\\([^ ]*\\);@\\1⟨\\2⟩;@; (*handle (presumed) enum members without assignment*) \\@\t*[?:]@!s@^\\(\t\t*\\)\\([^ ]*\\) =@\\1⟨\\2⟩ =@; (*handle (presumed) enum members with assignment*) \\@\t*[?:]@!s@^\\(\t\t*\\)\\([^= ]\\( *[^= ]\\)*\\) \\([^ ][^ ]*\\);@\\1⸤\\2⸥ ⟨\\4⟩;@; (*handle (presumed) struct members*) s@^\\(constexpr \\)*\\([^\t= ]\\( *[^= ]\\)*\\) \\([^= ][^= ]*\\) =@\\1⸤\\2⸥ ⟨\\4⟩ =@; (*handle file‐scope assignments*) s@^enum \\([^ ][^ ]*\\)@enum ⸤\\1⸥@; (*enum declarations*) \\@^enum@s@: \\([^{]*[^{ ]\\)@: ⸤\\1⸥@; (*enum underlying values*) s@^struct \\([^ ][^ ]*\\)@struct ⸤\\1⸥@; (*struct declarations*) s@^typedef \\([^ ]\\( *[^ ]\\)*\\) \\([^ ][^ ]*\\);@typedef ⸤\\1⸥ ⸤\\3⸥;@; (*typedef definitions*) \\@^[^\t ][^\t ]* [^ ][^ ]*(@s@, *@⸥, ⸤@g; (*format function arguments*) s@^\\([^\t ][^ ]*\\) \\([^ ][^ ]*\\)(\\([^)][^)]*\\))@⸤\\1⸥ ⟨\\2⟩(⸤\\3⸥)@; (*format functions*) s@\\(//.*\\)$$@⟦\\1⟧@; (*format comments*) }; \\@.@s@^@\t|`@; (*format beginning of line*) \\@.@s@$$@´@; (*format end of line*) }; \\@^ [*][*] @{ (*format documentation*) s@^ [*][*] [ \t]*@@; (*drop documentation leader*) s@ :—@ :⁠—@g; (*fixup spacing for :—*) s@« @« @g; (*fixup spacing for «*) s@‹ @‹ @g; (*fixup spacing for ‹*) s@—: @—⁠: @g; (*fixup spacing for —:*) s@ »@ »@g; (*fixup spacing for »*) s@ ›@ ›@g; (*fixup spacing for ›*) s@{<\\([^>]*\\)[.]h>}@{🔗`\\1`<./\\1>}@g; (*header file linking*) }; endef sedcmd := $(call makeunreadable,$(readablesedcmd)) # The first argument should be shell commands producing Les·M·L; the second should be the title of the page. processlesml = { $(PRINTF) '%s\n%s' '' ''; } | xsltproc --stringparam PROJECT_NAME '$(PROJECT_NAME)' --stringparam TITLE '$2' xslt/documentation.xslt - $(DOCUMENTATION_FILES) : $(DOCDIR)/%.xhtml : %.h $(LESML)/parser.xslt xslt/documentation.xslt @if $(TEST) '!' -d $(DOCDIR); then $(MKDIR) -p $(DOCDIR); fi @$(PRINTF) '%s\n' 'Building documentation for <$<>…' >&2 @$(call processlesml,$(PRINTF) '%s\n\n' '#!lesml@en$$' '⁌ Documentation for `<$<>´'; $(SED) '$(sedcmd)' <'$<'; $(PRINTF) '\n\n%s' '⁂' 'A part of {🔗$(PROJECT_NAME) Documentation<./index.xhtml>}.',Documentation for <$<>) >|'$@' $(DOCDIR)/README.xhtml : README $(LESML)/parser.xslt xslt/documentation.xslt @$(PRINTF) '%s\n' 'Building documentation README…' >&2 @$(call processlesml,$(CAT) README; $(PRINTF) '\n\n%s' '⁂' 'A part of {🔗$(PROJECT_NAME) Documentation<./index.xhtml>}.',$(PROJECT_NAME) Readme) >|'$@' $(DOCDIR)/index.xhtml : FORCE $(LESML)/parser.xslt xslt/documentation.xslt @$(PRINTF) '%s\n' 'Building documentation index…' >&2 @$(call processlesml,$(PRINTF) '%s\n\n' '#!lesml@en$$' '⁌ $(PROJECT_NAME) Documentation' '• {🔗$(PROJECT_NAME) Readme<./README.xhtml>}'$(foreach header,$(HEADER_FILES), '• {🔗Documentation for `$(header)´<./$(patsubst %.h,./%.xhtml,$(header))>}'),) >|'$@' $(LESML)/parser.xslt : %/parser.xslt : FORCE $(GIT) submodule update --init '$*' FORCE : ; .PHONY : FORCE documentation