diff --git a/.github/docker-build-pdf.sh b/.github/docker-build-pdf.sh index 35ab13f..427bd76 100755 --- a/.github/docker-build-pdf.sh +++ b/.github/docker-build-pdf.sh @@ -4,22 +4,26 @@ if [[ -z "${PANDOCK}" ]]; then PANDOCK=ghcr.io/commonhaus/pandoc-pdf:3.1 fi -# Git commit information (SHA, date, repo url) + DATE=$(date "+%Y-%m-%d") +URL=$(gh repo view --json url --jq '.url')/ + +if [[ -z "${GITHUB_SHA}" ]]; then + GITHUB_SHA=$(git rev-parse --short HEAD) +fi + +echo GITHUB_SHA=${GITHUB_SHA} + +# Git commit information (SHA, date, repo url) if [[ "${IS_PR}" == "true" ]]; then FOOTER="${DATE} ✧ ${GITHUB_REF}" -elif [[ -z "${GITHUB_SHA}" ]]; then - GITHUB_SHA=$(git rev-parse --short HEAD) + URL="${PR_URL}" +else FOOTER="${DATE} ✧ commit ${GITHUB_SHA}" + URL="${URL}blob/${GITHUB_SHA}/" fi -if [[ -z "${GIT_COMMIT}" ]]; then - GIT_COMMIT=$(git rev-parse HEAD) -fi -URL=$(gh repo view --json url --jq '.url')/ echo URL=${URL} -echo GIT_COMMIT=${GIT_COMMIT} -echo GITHUB_SHA=${GITHUB_SHA} # Docker command and arguments ARGS="--rm -e TERM -e HOME=/data -u $(id -u):$(id -g) -v $(pwd):/data -w /data" @@ -32,15 +36,24 @@ elif [[ -z "${DOCKER}" ]]; then DOCKER=docker fi -TO_CMD=${1:-nope} +function run_shell() { + ${DOCKER} run ${ARGS} --entrypoint="" "${PANDOCK}" "$@" +} + +function run_pandoc() { + ${DOCKER} run ${ARGS} "${PANDOCK}" "$@" +} + + +TO_CMD=${1:-noargs} # Invoke command in the pandock container with common docker arguments if [[ "${TO_CMD}" == "sh" ]]; then - ${DOCKER} run ${ARGS} --entrypoint="" "${PANDOCK}" "$@" + run_shell "$@" exit 0 fi # Invoke pandoc with common docker arguments -if [[ "${TO_CMD}" != "nope" ]]; then - ${DOCKER} run ${ARGS} "${PANDOCK}" "$@" +if [[ "${TO_CMD}" != "noargs" ]]; then + run_pandoc "$@" exit 0 fi @@ -100,18 +113,28 @@ function to_pdf() { function run_pdf() { ${DOCKER} run ${ARGS} \ "${PANDOCK}" \ - -H ./.pandoc/header.tex \ - -A ./.pandoc/afterBody.tex \ -d ./.pandoc/bylaws.yaml \ -M date-meta:"$(date +%B\ %d,\ %Y)" \ - --metadata-file=CONTACTS.yaml \ -V footer-left:"${FOOTER}" \ - -V github:"${URL}blob/${GIT_COMMIT}/" \ + -V github:"${URL}" \ "$@" echo "$?" } +# Convert markdown to DOCX +function run_docx() { + ${DOCKER} run ${ARGS} \ + "${PANDOCK}" \ + -d ./.pandoc/agreements.yaml \ + -M date-meta:"$(date +%B\ %d,\ %Y)" \ + -V github:"${URL}" \ + -o "$1" \ + "$2" + + echo "$?" +} + mkdir -p output/tmp mkdir -p output/public @@ -138,12 +161,12 @@ for x in "${BYLAWS[@]}"; do fi done -# Convert bylaws to PDF +# # Convert bylaws to PDF to_pdf_pattern \ bylaws \ "cf-bylaws.pdf" \ "./bylaws/" \ - -M title:"Commonhaus Foundation Bylaws" \ + -M title:"Bylaws" \ "${BYLAWS[@]}" ## POLICIES @@ -158,7 +181,7 @@ function to_policy_pdf() { "${1}" \ "${1}.pdf" \ "./policies/" \ - -M title:"Commonhaus Foundation ${2} Policy" \ + -M title:"${2} Policy" \ "./policies/${1}.md" } @@ -166,32 +189,26 @@ function to_policy_pdf() { to_policy_pdf code-of-conduct "Code of Conduct" to_policy_pdf conflict-of-interest "Conflict of Interest" to_policy_pdf ip-policy "Intellectual Property" -to_policy_pdf security-policy "Security Vulnerability Reporting" -to_policy_pdf succession-plan "Continuity and Administrative Access" to_policy_pdf trademark-policy "Trademark" -to_pdf ./TRADEMARKS.md trademark-list ./ "Commonhaus Foundation Trademark List" +to_pdf ./TRADEMARKS.md trademark-list ./ "Trademark List" ## AGREEMENTS -function to_agreement_pdf() { +function to_agreement_doc() { if [[ ! -f "./agreements/${1}.md" ]]; then echo "No agreement found at ./agreements/${1}.md" exit 1 fi - local name=$(basename ${1}) - sed -E 's/\[Insert [^]]* here\]/______________________________________/g' \ - "./agreements/${1}.md" > "./output/tmp/${name}.md" - - to_pdf_pattern \ - "${1}" \ - "$(basename ${1}).pdf" \ - "./agreements/$(dirname ${1})/" \ - -M title:"Commonhaus Foundation ${2} Agreeement" \ - "./output/tmp/${name}.md" + if [[ -z "${2}" ]]; then + echo "No agreement name provided" + exit 1 + fi + run_docx \ + "./output/public/${2}.docx" \ + "./agreements/${1}.md" } -# Very redundant, but .. whatever. ;) -to_agreement_pdf bootstrapping/bootstrapping Bootstrapping +to_agreement_doc bootstrapping/bootstrapping bootstrapping-agreement ls -al output/public \ No newline at end of file diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 86e6919..0e7fa27 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -63,6 +63,7 @@ jobs: GIT_COMMIT: ${{ github.sha }} GH_TOKEN: ${{ github.token }} IS_PR: ${{ github.event_name == 'pull_request' }} + PR_URL: ${{ github.event.pull_request.html_url }} run: ./.github/docker-build-pdf.sh - uses: actions/upload-artifact@v4 diff --git a/.gitignore b/.gitignore index 0e02f0b..41853fc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ *.DS_Store *~ +.~* .cache +.config .idea .vscode node_modules diff --git a/.pandoc/agreements.yaml b/.pandoc/agreements.yaml new file mode 100644 index 0000000..8a3bf0c --- /dev/null +++ b/.pandoc/agreements.yaml @@ -0,0 +1,13 @@ +from: gfm+emoji+alerts +reader: gfm+emoji+alerts +number-sections: true +file-scope: true +filters: +- .pandoc/filters/fix-links.lua +- .pandoc/filters/agreement-form.lua +metadata-file: CONTACTS.yaml +reference-doc: .pandoc/content/cf-agreement-template.docx +template: .pandoc/content/docx-template.txt +shift-heading-level-by: -1 +variables: + website: https://www.commonhaus.org/ diff --git a/.pandoc/bylaws.yaml b/.pandoc/bylaws.yaml index b7e427e..fca3717 100644 --- a/.pandoc/bylaws.yaml +++ b/.pandoc/bylaws.yaml @@ -1,13 +1,19 @@ -from: gfm+emoji -reader: gfm+emoji +from: gfm+emoji+alerts +reader: gfm+emoji+alerts number-sections: true file-scope: true filters: -- .pandoc/fix-links.lua +- .pandoc/filters/alerts.lua +- .pandoc/filters/fix-links.lua +include-in-header: +- .pandoc/content/header.tex +include-after-body: +- .pandoc/content/afterBody.tex +metadata-file: CONTACTS.yaml pdf-engine: lualatex pdf-engine-opts: - '-shell-escape' -template: .pandoc/templates/commonhaus-eisvogel +template: .pandoc/content/commonhaus-eisvogel toc: true toc-depth: 3 variables: diff --git a/.pandoc/content/CF_logo_horizontal_single_default_svg-tex.pdf b/.pandoc/content/CF_logo_horizontal_single_default_svg-tex.pdf new file mode 100644 index 0000000..6214e60 Binary files /dev/null and b/.pandoc/content/CF_logo_horizontal_single_default_svg-tex.pdf differ diff --git a/.pandoc/content/CF_logo_horizontal_single_default_svg-tex.pdf_tex b/.pandoc/content/CF_logo_horizontal_single_default_svg-tex.pdf_tex new file mode 100644 index 0000000..2179cc8 --- /dev/null +++ b/.pandoc/content/CF_logo_horizontal_single_default_svg-tex.pdf_tex @@ -0,0 +1,48 @@ +%% Creator: Inkscape 1.3.2 (091e20ef0f, 2023-11-25), www.inkscape.org +%% PDF/EPS/PS + LaTeX output extension by Johan Engelen, 2010 +%% Accompanies image file 'CF_logo_horizontal_single_default_svg-tex.pdf' (pdf, eps, ps) +%% +%% To include the image in your LaTeX document, write +%% \input{.pdf_tex} +%% instead of +%% \includegraphics{.pdf} +%% To scale the image, write +%% \def\svgwidth{} +%% \input{.pdf_tex} +%% instead of +%% \includegraphics[width=]{.pdf} +%% +%% Images with a different path to the parent latex file can +%% be accessed with the `import' package (which may need to be +%% installed) using +%% \usepackage{import} +%% in the preamble, and then including the image with +%% \import{}{.pdf_tex} +%% Alternatively, one can specify +%% \graphicspath{{/}} +%% +%% For more information, please see info/svg-inkscape on CTAN: +%% http://tug.ctan.org/tex-archive/info/svg-inkscape +%% +\begingroup% + \makeatletter% + \providecommand\color[2][]{% + \errmessage{(Inkscape) Color is used for the text in Inkscape, but the package 'color.sty' is not loaded}% + \renewcommand\color[2][]{}% + }% + \providecommand\transparent[1]{% + \errmessage{(Inkscape) Transparency is used (non-zero) for the text in Inkscape, but the package 'transparent.sty' is not loaded}% + \renewcommand\transparent[1]{}% + }% + \providecommand\rotatebox[2]{#2}% + \newcommand*\fsize{\dimexpr\f@size pt\relax}% + \newcommand*\lineheight[1]{\fontsize{\fsize}{#1\fsize}\selectfont}% + \def\svgwidth{150px} + \setlength{\unitlength}{150px} + \makeatother% + \begin{picture}(1,0.10569674)% + \lineheight{1}% + \setlength\tabcolsep{0pt}% + \put(0,0){\includegraphics[width=\unitlength,page=1]{./.pandoc/content/CF_logo_horizontal_single_default_svg-tex.pdf}}% + \end{picture}% +\endgroup% diff --git a/.pandoc/afterBody.tex b/.pandoc/content/afterBody.tex similarity index 100% rename from .pandoc/afterBody.tex rename to .pandoc/content/afterBody.tex diff --git a/.pandoc/content/agreement-header.txt b/.pandoc/content/agreement-header.txt new file mode 100644 index 0000000..637fdca --- /dev/null +++ b/.pandoc/content/agreement-header.txt @@ -0,0 +1,7 @@ + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" + xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" + xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" + xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" + xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" + mc:Ignorable="w14 wp14 w15" diff --git a/.pandoc/content/cf-agreement-template.docx b/.pandoc/content/cf-agreement-template.docx new file mode 100644 index 0000000..53ac60a Binary files /dev/null and b/.pandoc/content/cf-agreement-template.docx differ diff --git a/.pandoc/templates/commonhaus-eisvogel.latex b/.pandoc/content/commonhaus-eisvogel.latex similarity index 98% rename from .pandoc/templates/commonhaus-eisvogel.latex rename to .pandoc/content/commonhaus-eisvogel.latex index 97b7b89..76ac036 100644 --- a/.pandoc/templates/commonhaus-eisvogel.latex +++ b/.pandoc/content/commonhaus-eisvogel.latex @@ -275,10 +275,10 @@ $if(verbatim-in-note)$ \usepackage{fancyvrb} $endif$ \usepackage{xcolor} -\definecolor{default-linkcolor}{HTML}{4077C0} -\definecolor{default-filecolor}{HTML}{4077C0} -\definecolor{default-citecolor}{HTML}{4077C0} -\definecolor{default-urlcolor}{HTML}{4077C0} +\definecolor{default-linkcolor}{HTML}{4D7343} +\definecolor{default-filecolor}{HTML}{4D7343} +\definecolor{default-citecolor}{HTML}{4D7343} +\definecolor{default-urlcolor}{HTML}{4D7343} $if(footnotes-pretty)$ % load footmisc in order to customize footnotes (footmisc has to be loaded before hyperref, cf. https://tex.stackexchange.com/a/169124/144087) \usepackage[hang,flushmargin,bottom,multiple]{footmisc} @@ -677,7 +677,7 @@ $endif$ % % heading color % -\definecolor{heading-color}{RGB}{40,40,40} +\definecolor{heading-color}{HTML}{1A402A} $if(beamer)$ $else$ \addtokomafont{section}{\color{heading-color}} @@ -875,10 +875,10 @@ $else$ $if(disable-header-and-footer)$ $else$ \usepackage[headsepline,footsepline]{scrlayer-scrpage} - \newpairofpagestyles{eisvogel-header-footer}{ + \newcommand{\headertext}{$if(header-left)$$header-left$$else$$title$$endif$} \clearpairofpagestyles - \ihead*{\textcolor{gray}{$if(header-left)$$header-left$$else$$title$$endif$}} + \ihead*{\raisebox{-.7ex}{\input{./.pandoc/content/CF_logo_horizontal_single_default_svg-tex.pdf_tex}} \hspace{2px} \headertext} \chead*{\textcolor{gray}{$if(header-center)$$header-center$$else$$endif$}} \ohead*{\textcolor{gray}{$if(header-right)$$header-right$$else$$date$$endif$}} \ifoot*{\textcolor{gray}{$if(footer-left)$$footer-left$$else$$for(author)$$author$$sep$, $endfor$$endif$}} diff --git a/.pandoc/content/docx-template.txt b/.pandoc/content/docx-template.txt new file mode 100644 index 0000000..b9807b0 --- /dev/null +++ b/.pandoc/content/docx-template.txt @@ -0,0 +1,84 @@ + + + +$if(title)$ + + + + + $title$ + +$endif$ +$if(subtitle)$ + + + + + $subtitle$ + +$endif$ +$for(author)$ + + + + + $author$ + +$endfor$ +$if(date)$ + + + + + $date$ + +$endif$ +$if(abstract)$ +$if(abstract-title)$ + + + + + $abstract-title$ + +$endif$ + $abstract$ +$endif$ +$for(include-before)$ + $include-before$ +$endfor$ +$if(toc)$ + $toc$ +$endif$ +$if(lof)$ + $lof$ +$endif$ +$if(lot)$ + $lot$ +$endif$ + $body$ +$for(include-after)$ + $include-after$ +$endfor$ +$-- sectpr will be set to the last sectpr in a reference.docx, if present +$if(sectpr)$ + $sectpr$ +$else$ + +$endif$ + + diff --git a/.pandoc/header.tex b/.pandoc/content/header.tex similarity index 98% rename from .pandoc/header.tex rename to .pandoc/content/header.tex index 369c42e..2f63619 100644 --- a/.pandoc/header.tex +++ b/.pandoc/content/header.tex @@ -1,6 +1,8 @@ +\usepackage{awesomebox} \usepackage{fontspec} \usepackage{moresize} \usepackage{xcolor} +\usepackage{svg} % Header and footer ------------------------------------------ % Read date of last commit from file diff --git a/.pandoc/filters/agreement-form.lua b/.pandoc/filters/agreement-form.lua new file mode 100644 index 0000000..8371ec0 --- /dev/null +++ b/.pandoc/filters/agreement-form.lua @@ -0,0 +1,116 @@ +-- Horizontal separator in Word DOCX +local horizontalSeparator = [[ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]] + +local function HorizontalRule(elem) + print("CFLUA: Found horizontal rule ") + return pandoc.RawBlock('openxml', horizontalSeparator) +end + +local function Header(header) + if header.level == 1 then + local content = pandoc.utils.stringify(header.content) + content = content:gsub("Commonhaus Foundation%s*(.*)", "%1") + print("CFLUA: Found header " .. content) + return pandoc.Header(1, content) + end + return header +end + +local function Para(para) + local content = pandoc.utils.stringify(para.content) + local insert = string.match(content, "%[Insert.*]") + if insert then + content = content:gsub("(.*)%[Insert.*](.*)", "%1______________________________%2") + print("CFLUA: Found insert " .. content) + return pandoc.read(content, 'markdown').blocks + end + return para +end + +local function BulletList(list) + local content = pandoc.utils.stringify(list.content) + if string.match(content, "%[Insert.*]") then + for i, item in ipairs(list.content) do + local itemContent = pandoc.utils.stringify(item[1].content) + itemContent = itemContent:gsub("(.*)%[Insert.*](.*)", "%1______________________________%2") + print("CFLUA: Found insert " .. itemContent) + list.content[i][1] = pandoc.Plain(itemContent) + end + end + return list +end + +return { + { Header = Header }, + { HorizontalRule = HorizontalRule }, + { BulletList = BulletList }, + { Para = Para } +} \ No newline at end of file diff --git a/.pandoc/filters/alerts.lua b/.pandoc/filters/alerts.lua new file mode 100644 index 0000000..a35e5a7 --- /dev/null +++ b/.pandoc/filters/alerts.lua @@ -0,0 +1,14 @@ +local alerts = pandoc.List({'note', 'tip', 'important', 'warning', 'caution'}) + +if FORMAT:match 'latex' then + function Div(d) + local class = string.lower(d.classes[1]) + if alerts:includes(class) then + local alert,alertidx = alerts:find(class) + local alertText = pandoc.utils.stringify(d.content[1]) + d.content[1] = pandoc.RawInline('tex', '\\begin{' .. class .. 'block}') + d.content[#d.content + 1] = pandoc.RawInline('latex', '\\end{' .. class .. 'block}') + return d + end + end +end \ No newline at end of file diff --git a/.pandoc/fix-links.lua b/.pandoc/filters/fix-links.lua similarity index 96% rename from .pandoc/fix-links.lua rename to .pandoc/filters/fix-links.lua index f9743d8..75b368a 100644 --- a/.pandoc/fix-links.lua +++ b/.pandoc/filters/fix-links.lua @@ -75,9 +75,9 @@ end local function Inline (el) if el.t == 'RawInline' and el.format:match'html.*' then if el.text:match'= 2.15 includes 'tag', nil values and functions + if key ~= 'tag' and val and type(val) ~= 'function' then + valueCopy[key] = val + numKeys = numKeys + 1 + lastKey = key + end + end + if numKeys == 0 then + -- this allows empty tables to be formatted on a single line + -- XXX experimental: render Doc objects + value = typename == 'Doc' and '|' .. value:render() .. '|' or + typename == 'Space' and '' or '{}' + elseif numKeys == 1 and lastKey == 'text' then + -- this allows text-only types to be formatted on a single line + typ = typename + value = value[lastKey] + typename = 'string' + else + value = valueCopy + -- XXX experimental: indicate array sizes + if #value > 0 then + typ = typ .. '[' .. #value .. ']' + end + end + end + + -- output the possibly-modified value + local presep = #prefix > 0 and ' ' or '' + local typsep = #typ > 0 and ' ' or '' + local valtyp = type(value) + if valtyp == 'nil' then + add('nil') + elseif ({boolean=1, number=1, string=1})[valtyp] then + typsep = #typ > 0 and valtyp == 'string' and #value > 0 and ' ' or '' + -- don't use the %q format specifier; doesn't work with multi-bytes + local quo = typename == 'string' and '"' or '' + add(string.format('%s%s%s%s%s%s%s%s', indent, prefix, presep, typ, + typsep, quo, value, quo)) + -- light userdata is just a pointer (can't iterate over it) + -- XXX is there a better way of checking for light userdata? + elseif valtyp == 'userdata' and not pcall(pairs(value)) then + add(string.format('%s%s%s%s %s', indent, prefix, presep, typ, + tostring(value):gsub('userdata:%s*', ''))) + elseif ({table=1, userdata=1})[valtyp] then + add(string.format('%s%s%s%s%s{', indent, prefix, presep, typ, typsep)) + -- Attr and Attr.attributes have both numeric and string keys, so + -- ignore the numeric ones + -- XXX this is no longer the case for pandoc >= 2.15, so could remove + -- the special case? + local first = true + if prefix ~= 'attributes:' and typ ~= 'Attr' then + for i, val in ipairs(value) do + local pre = maxlen and not first and ', ' or '' + dump_(string.format('%s[%s]', pre, i), val, maxlen, + level + 1, add) + first = false + end + end + -- report keys in alphabetical order to ensure repeatability + for key, val in logging.spairs(value) do + local pre = maxlen and not first and ', ' or '' + -- this check can avoid an infinite loop, e.g. with metatables + -- XXX should have more general and robust infinite loop avoidance + if key:match('^__') and type(val) ~= 'string' then + add(string.format('%s%s: %s', pre, key, tostring(val))) + + -- pandoc >= 2.15 includes 'tag' + elseif not tonumber(key) and key ~= 'tag' then + dump_(string.format('%s%s:', pre, key), val, maxlen, + level + 1, add) + end + first = false + end + add(string.format('%s}', indent)) + end + return table.concat(buffer, maxlen and '' or '\n') +end + +logging.dump = function(value, maxlen) + if maxlen == nil then maxlen = 70 end + local text = dump_(nil, value, maxlen) + if #text > maxlen then + text = dump_(nil, value, nil) + end + return text +end + +logging.output = function(...) + local need_newline = false + for i, item in ipairs({...}) do + -- XXX space logic could be cleverer, e.g. no space after newline + local maybe_space = i > 1 and ' ' or '' + local text = ({table=1, userdata=1})[type(item)] and + logging.dump(item) or tostring(item) + io.stderr:write(maybe_space, text) + need_newline = text:sub(-1) ~= '\n' + end + if need_newline then + io.stderr:write('\n') + end +end + +-- basic logging support (-1=errors, 0=warnings, 1=info, 2=debug, 3=debug2) +-- XXX should support string levels? +logging.loglevel = 0 + +-- set log level and return the previous level +logging.setloglevel = function(loglevel) + local oldlevel = logging.loglevel + logging.loglevel = loglevel + return oldlevel +end + +-- verbosity default is WARNING; --quiet -> ERROR and --verbose -> INFO +-- --trace sets TRACE or DEBUG (depending on --verbose) +if type(PANDOC_STATE) == 'nil' then + -- use the default level +elseif PANDOC_STATE.trace then + logging.loglevel = PANDOC_STATE.verbosity == 'INFO' and 3 or 2 +elseif PANDOC_STATE.verbosity == 'INFO' then + logging.loglevel = 1 +elseif PANDOC_STATE.verbosity == 'WARNING' then + logging.loglevel = 0 +elseif PANDOC_STATE.verbosity == 'ERROR' then + logging.loglevel = -1 +end + +logging.error = function(...) + if logging.loglevel >= -1 then + logging.output('(E)', ...) + end +end + +logging.warning = function(...) + if logging.loglevel >= 0 then + logging.output('(W)', ...) + end +end + +logging.info = function(...) + if logging.loglevel >= 1 then + logging.output('(I)', ...) + end +end + +logging.debug = function(...) + if logging.loglevel >= 2 then + logging.output('(D)', ...) + end +end + +logging.debug2 = function(...) + if logging.loglevel >= 3 then + logging.warning('debug2() is deprecated; use trace()') + logging.output('(D2)', ...) + end +end + +logging.trace = function(...) + if logging.loglevel >= 3 then + logging.output('(T)', ...) + end +end + +-- for temporary unconditional debug output +logging.temp = function(...) + logging.output('(#)', ...) +end + +return logging diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index adc86cc..15048d9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,7 +29,7 @@ text is also included verbatim in the [dco.txt](dco.txt) file in the root direct - **Markdown linting**: `npm run lint` - **YAML syntax validation**: `npm run yaml` - **Markdown link checks**: `npm run links` or `npm run linksv` (verbose) - - **Build pdfs**: If you use docker or podman, run `./.github/docker-build-pdf.sh` to use a pre-configured docker image to convert markdown bylaws and policies to pdf. + - **Build pdfs**: If you use docker or podman, run `./.github/docker-build-pdf.sh` to use a pre-configured container image to convert markdown bylaws and policies to pdf. ## Flow of information @@ -44,6 +44,15 @@ Markdown content is converted into pdfs and is published on the website. [CONTACTS.yaml]: ./CONTACTS.yaml +## Pandoc for PDFs and DOCX + +We use pandoc (via a container image) to convert bylaws, policies, and agreements into pdf and docx files. + +- `./.github/docker-build-pdf.sh` is the script that drives that conversion (aggregating bylaws into a single pdf, converting each policy into a standalone pdf, and generating a word/docx file for each agreement) +- The `.pandoc` directory contains the machinery to perform those conversions + - `fix-links.lua` applies to both pdfs and docx files; it does some basic link fixing to transition from a GitHub markdown doc into something that can standalone + - `agreement-form.lua` applies only to agreements. It replaces `[Insert...here]` values with blanks (which can be picked up if/when subsequently printed as a pdf), and handles header rules and other markdown to docx conversion issues. The `cf-agreement-template.docx` file contains the base styles that are used when translating the other doc. Those styles are best updated by unzipping the document and adjusting the raw xml. + ## Submitting changes - **Create a PR**: Submit your changes via a pull request from your fork. Check the automatic build for link or pdf generation errors.