The aim of this document is to introduce the perl, bash and viml files written to access, build and manipulate abbreviations, thesaurus, glossaries, footnotes, bibitems from an imported central SQL-like google spreadsheets csv-file through BBEdit-clippings1 and vim-UltiSnips2 and to show its conjunction use with BBEdit-Preview MultiMarkdown mainly to compile multi-lingual multi-columned writings in the html and pdf-format at the same time.

Formulation of the problem Energiewende

A ‘normal’ text is clustered around maximal one or two ‘big’ main thoughts. Here it is FFEW, IDEW, and later 4P. In co-occurrence with the latter, we had to explain the fourth field – it is about the GSPL.

In the decades of 2000 - 2020 the EU Economic Commission followed a political approach which is a so-called international division of labour theory3 and as an integrated ‘CO2-market’4 is emerging, we have had to write some documents in a bi-lingual context. Besides the mainly addressed countries 🇩🇪 and 🇫🇷, we suspect 🇯🇵, 🇪🇸 and 🇺🇸 to play a potential role within this idea – an idea which may be encircled by the two opposite terms democracy and a nations military potential. In one funny word, it could be stated as: “The plasma physicist who started to re-invent the ‘moped’”5.

But before all, this still imposes manifold computer problems: How to access abbreviations which do exist only of non-common ASCII-chars like – here comes a special line – ÎÉTÉ (“îlots économiques de la transition énergétique”).

How to ‘re-use’ common buzz-words consistently like “Energiewende” and let the term explain themselves more or less bi-lingually?6 If we fail in togetherness, do we end up in combining “Energiewende” with “Kindergarten”?7

Already when leaving ISO 8859-1 codepage good old BBEdit has proofed to fail for giving a result while attempting to access the first clipping example. For the second, we made the choice to keep names consistently, but with ISO 3166-1 (ALPHA-2)-ending names or – even better – to show a small flag symbol when high-lighting may be useful for the reader. Thus, we had to go back to (even older and better) vim, that is, first look up for big words, then drill-down into all sub-items and languages.

Thus there are now for each ‘main’ writing two thesaurus files: One contains a project description pointer and is edited by the writer, e.g. ffew-main.txt – it is accessed via vim’s thesaurus function, namely via the keys <C-x> <C-t> (see :h 'tsr'), then toggle through the main-items (<C-n> and <C-p) and then select one of them while appending {.a,.f,.g,.n} to this abbreviation – which now should be derived from ffew-subs.txt – and finish again the expansion with <C-], e.g. with the problematic ÎÉTÉ.

Here is it how it was done:

First Select `Thesaurus`...
First Select Thesaurus

type: iete<Cx><Ct>

...then select `Abbreviation`
…then select Abbreviation

type: <Cn><Cn><Cn><C]>

Now your vim expands the abbreviation to

[>ÎÉTÉ🇫🇷][^s.a. Glossar [?îlots économiques de la transition énergétique]: Stratégies de mise en œuvre particulièrement économiques et simples]

or in rendered form from Markdown:

Les [>ÎÉTÉ🇫🇷]8 peuvent également servir de tremplin pour atteindre le nouveau rivage… in English the stepping stones towards the carbon free future.

Note that a postfootnote is hooked after its definition to indicate MMD that the item is rendered to html glossary.

Since we do not want to mess up with vim’s &rtp (runtime-path), simply start to join our writing team with mkdir the :

cd ~/ev/vim # or where "google backup & sync"[ed] dir resides

and touch, edit, save the following ~/ev/vim/autoload/evlk.vim

function evlk#ReRead()
    for f in split(glob('/Users/sm/Documents/evlka/vim/*.vim'),'\n')
        exe 'source' f
    endfor
    set thesaurus=
    for f in split(glob('/Users/sm/Documents/evlka/vim/thesaurus/*.txt'),'\n')
        let &thesaurus=&thesaurus . ',' . expand(f)
    endfor
    echom "thesaurus sourced"
endfunction

and then for me to have the thesaurus and abbreviation reader into vim’s &rtp link it symbolic to

ln -s ~/ev/vim/autoload/evlk.vim ~/.vim/autoload

Done so you can read project files which are generated by perl and bash scripts from a google spreadsheet masterfile, where all *.bib and glossary, abbreviation data is stored. If you want to rely on MMD and LaTex, you will have to generate *.csv, *.bib, *.mmd and .vim files simultaneously…yes. Your read correctly. But, it is only one slightly apoted perl Text::CSV binary reading script and some ‘GNU sed tee cat’ combinated three-liners.

Let us go back to thesaurus: The key access can be done beginning from the thesaurus starting points, e.g. here ffew, 4p, ckg and gsp.

Let us have a try: It is always hard to remember what belongs to ckg, here for our Christian community die christlich kulturellen Grundlagen:

ckg.f: [>CKG]9

Now what exactly was the French translation of that?

Typing ffew<C-x><C-t> pop-ups the thesaurus main file and…

...the pop up comes with `national country` orientational flags
…the pop up comes with national country orientational flags

The following expands to its glossary entry:

BasCC.g: [?Bases de la Culture Chrétienne]

You may always have at hand:

Possible endings of abbreviations
.n expand normalized word Short form entry
.a expand abbrevition markdown entry [>abbrev]
.g expand glossary markdown entry [?Short form entry]
.f expand both within a footnote [^Very long text]
.r expand to reference both special
.l expand to label both special UltiSnips

The ‘big words’

It may be a good practise to have the posthook footnotes at the same place and to indicate here you are handling with an important term. Can we have bi-lingual footnotes made out of our abbreviations (MMD), glossary and? With a flag as a sign? Such a role could be seen in the term ‘4P’, so we combine 4P.f for two languages. The main language is German, hence we start expanding abbreviation with typing 4PDE:

4P🇩🇪10

Note, that the flags are rendered directly in HTML, but not in LuaLaTeX11

If the writer just types FFEW.f or 4P.f, within the document’s window a pop-up with an abbreviation list and sub-item occurs, and as well the ‘childs’ of the abbreviations like a footnote, a short or long form of a glossary entry w/o explanation can be expanded via F5 in BBEdit or via Ctr-] in vim. Even a list with items which are sub-ordinated can be contained, thus via a drop-down analysis you can check bottom-up and vice-versa, say select first expanding to expand second word to expand third final word within one single pop-up. This may sound complicated, with little practise this is useful tool for keeping flow of speech or while checking if thoughts are stillwell structured after having left a side note.A side note may change your complete structure!

Ever needed an exhausting long glossary – especially in the energy sector?

The energy transition – or the second electrification ‘of the world’ – can be seen from a juridical, human and technological perspective. As you will see, because of the three, we as part of the Christians believe the right order here has to be done first before trying to organize your home.

We are starting with the longest match: In terms of jurisdiction there is devastating international landscape of complete ‘babel’. The glossaries of the common ‘electrification’ so called organisations12 do not match each another’s nor their own ones. Once you cite rule x with its underlying term A, it does not apply for rule y of the same organisation, because the word A here has a complete different meaning in rule x than in rule y. Babel is also very powerful mean to protect a position of power, a very liberal mind could state.

That is why we decided to split glossaries into ‘old jurisdiction’ and ‘our christian non-babel’ words. The ‘old’ can be found only in den portable Document format, they are to exhaustive for html code.

In the ‘human’ and ‘technological’ perspective it matters that we start making an order. In a world of interdependent relations, one has to (re-)iterate the nodes of vertices13. Note that the ‘last electrification’ took place from 1890 to 1920 and that the world tumbled into struggles. Innovation took also place in between chemistry and electrical science – like nowadays in Battery Management System (BMS), laser-tech for connecting galvanic items. Since we do follow common knowledge and science since late 90’s, we introduce cultural or even religious habits to inspect the impact. There are manyfold ways to inspect, but keep in mind, that it is very likely that this time electricity will nearly merge all markets: mobility, heat, cold, information, even water can be done14. And: It represents more than 80% of your economic live: My home Town Kronberg is a town, where about 1.200 bankers live. They say: “Small money is beautiful”. Indeed, Energiewende eats up 1.2 Bio Euro in a 20 years span. It is still a small town with 18.000 habitants15. How comes?

It is \(18.000*6.000*20=1.2e9\), but each ‘filling up’ a BEV or each ‘heating day’ a flat may not be mentioned, yes, as it is uncool to talk about small money – or energy – or electrification.

So you see, talking about manifold expenditures and small money is boring, sum them up and make a plan (for a community) is highly interesting. This is what this text tool is about. Configure social and technological innovation beginning from the end in the future towards the now in the present, from cultural to technological, from individual to community levels.

Working with UltiSnips

Cross-Reference to a character in an paragraph

This is now an example of three references, but none yields correctly to the wanted line in a paragraph. One link goes naturally to the section (or header), here to the first mentioned ÎÉTÉ16. The others go to glossary and to the footnote. All of them are jumping to the correct line, in PDF as well as in HTML – or to the glossary entry17 – and of course – to the given footnote. But how to link to one line in a paragraph?

Since a chapter or section may span several pages, the given solution is unprecise. Since we do not want to tumble into package handling, we check how to setup an own referencing done with UltiSnips, a package for vim.

This here is one special line reference to ÎÉTÉ . It should now link to the first occurrence of itself and is precise as expected. We here propose the use of \phantomsection and \autoref for LaTeX and format neutral tags <span> and <a> for HTML. You will see the power of vim, python and the a flag within UltiSnipsEdit’s regex feature – a quasi non-standard UTF8-to-ASCII ‘back’-converter18. Beware there is a lot of backticking, and typing this literately is nearly not feasible. Note that small backticks in the middle are to protect the anchor word from being expanded from MMD as an abbreviation or glossary entry.

For setting a label as ‘per-line-type’ please write:

label<tab>ÎÉTÉ<C-b>

This will be expanded to MultiMarkdown’s syntax as

`<span id="ÎÉTÉ"><a id="iete">`{=html}`ÎÉTÉ` `</a></span>`{=html} 
`\phantomsection\label{iete}`{=latex}  

Or for referencing an even more complex example19 write (please take an eye on ‘η’ here):

ref<tab>ÎÉTÉ helps more than η!<C-j> 

will be expanded to

`<a href="#iete_helps_e_">ÎÉTÉ helps η!</a>`{=html} 
`in \autoref{iete_helps_e_}`{=latex}

Note the obligatory space between the two ` (backticks).

Open a MarkDown file with ending *.md in vim and type :UltiSnipsEdit20 and insert for setting the precise label

snippet label "Two Anchors for HTML/LaTeX" w
\`<span id="$1"><a id="${2:${1/\\\w+\{(.*?)\}|\\(.)|(\w+)|([^\w\\]+)/(?4:_:\L$1$2$3\E)/ga}}">\`{=html}\`${1:${VISUAL}}\` \`</a></span>\`{=html}
\`\phantomsection\label{${2:${1/\\\w+\{(.*?)\}|\\(.)|(\w+)|([^\w\\]+)/(?4:_:\L$1$2$3\E)/ga}}}\`{=latex}
endsnippet

and for referencing precise to label

snippet ref "Two References for HTML/LaTeX" w
\`<a href="#${2:${1/\\\w+\{(.*?)\}|\\(.)|(\w+)|([^\w\\]+)/(?4:_:\L$1$2$3\E)/ga}}">${1:${VISUAL}}</a>\`{=html} 
\`in \autoref{${2:${1/\\\w+\{(.*?)\}|\\(.)|(\w+)|([^\w\\]+)/(?4:_:\L$1$2$3\E)/ga}}}\`{=latex}
endsnippet

Protecting white-space in French or adding hyphenation

The marks for exclamation and questions marks are preceded, the quotation marks are preceded and followed by a white space. The method in MMD to protect a white space from hyphenation is to protect it via \ a backslash. The same \ will protect any following sequence byte which follows it.

To have an extra hyphenation rule, one again needs to add via :UltraSnipsEdit a hyphen rule. You may define global rules in the header or wrap the words which may fail, and thus should be controlled within the text body. Note the trick that we wrap the rule into a md comment with following snippet.

<!-- snippet babelhyphenation for "${1:${VISUAL}}" -->\`{${1/-/\\-/g}}\`{=latex}\`${1/-/\&shy;/g}\`{=html}<!-- end snippet -->

As an example we may want to hyphen So-lar-ka-ta-s-ter, type <ESC>viwx (for visually inner word x-cut) and ibab<C-n> which will enter insert-mode and expand to snippet name, type <tab><CMD-V>21 and the result will be

<!-- snippet babelhyphenation for "So-lar-ka-ta-s-ter" -->`{So\-lar\-ka\-ta\-s\-ter}`{=latex}`So&shy;lar&shy;ka&shy;ta&shy;s&shy;ter`{=html}<!-- end snippet -->

Again, trying to type literately these characters will surely fail.

Summaries and bi-lingual ‘columnists’

At the end we decided to summarize every text with 5 to 7 sentences. That is a par force method for a complex theme, but we feel like this is very helpful due to the fact that after 25 year – a quarter of a century – the cores of the Energiewende have not been recognised by far. Everybody can speak 1 or 2 languages, so we decided that you always have your native language in the left column, the second in the right column. For the computer to combine and format these texts, it takes less than 400 ms for a 1 Ghz 12 W Mac-Mini22 to compile 6 texts with 3 languages to 2 formats23. Keep in mind that the Gutenberg Bible took a lot of work, nowadays, it is still a standard: Two columns, 19 cm width, 6–7 cm range for every column. Your eye can fly over and your brain will keep the meaning – this is called ‘Quer-Lesen’ – right connotation – in German language or – wrong connotation – Speed Reading24. Reading is not mainly processed with the eyes, it is also processed via the ear25. Especially that technic’s aim is to omit the inner-step ‘ear’. That is about the form – note our ancients did it right without any science.

Turning to content, one could start to argue. But: Nepotism and “Informations Overload” is the opposite of knowledge: Johann Wolfgang Goethe once started a letter with this:

I am sorry to write you a long letter, but I did not have the time to shorten it...

Since April 1996 ‘we’ have the technology of mimicking information via re-use of its content. Perl-Apache Handler was one26. Since 1996: only technologies for even better clicking advertisments, streaming vids and stackoverflow.com our brains –– instead of sharing thoughts and make out of the cheap photovoltaic technologies a per-se democratic decade.

To easily swap between languages in an one-column-environment the following snippet might be useful.

snippet selectlanguage "select lang for babel latex" w 
\`\selectlanguage{${1|ngerman,french,english,spanish|}}\`{=latex}
endsnippet

In a one column environment the language attribute tag is only definable in LaTeX, not in HTML27. The following section combines multilingual with multi-column surroundings, which is, conversely, again feasible.

Multi-language columns in multicol

Unfortunately, the paracol environment does not support the pdfpages and pdflscape package. The overall advantage comes when translation is done via the -i for incoming and -o for outgoing md-files with Translate Shell. The advantage is that not only that it provides multiple translate engines28, it also keeps the origin MMD Format, that is, it is not fragmented and it keeps its proper formatting. Here normative paragraphing is done with optional row balancing at rows 1,11,21,31, it is called ‘synchronised’ within the paracol29-package, and the lines inbetween are rendered without any paragraphing. Together with GNU Sed’s seldomly used -s-flag, any arbitrary text element can be translated and its variants can be printed column-wise.

Think of having this as our arbitrary summary element in German language:

echo -e "Dieser Kurztext befasst sich mit den Familienfreundliche Energiewende-Formen, dem Four Play der Energiewende[^Photovoltaik‐(Anlage), Wärmepumpen‐(Anlage), Battery Electric Storage System intelligent and Battery Electric Vehicle], den Ökonomische Inseln der Energiewende sowie deren Verhältnis untereinander.
Ein hier vorgestellter Lösungsvorschlag soll das derzeitige Spannungsverhältnis der privaten und gewerblichen „4P“-Umsetzungsart überwinden.
Zudem verbindet er die drei IDEW und stellt so einen pareto-optimalen Einsatz zwischen Off- und OnGrid-Technologien, BEV und BESSI, aber auch militärischer Sicherheit und demokratischer Freiheit her. 
\n
\n
\n
\n
Der Text adressiert sich an Kenner der Energiewende." > ~/ev/tex/xmp/tex20/1de-ngerman-Zusammenfassung1.md

The above one-liner generates our summary which counts four sentences. We will render this with ‘standard’ multicol- and with paracol-package30 and put German to column 1, add a de to lang-tag for HTML, pass the ngerman to babel, print a header containing Zusammenfassung_with_more_words without any ‘_’, and do a synchronisation of the row [1]1 (eleven) with one-based lining. Note that in HTML every row is being synced. Now we want a four column-width translation in French, English and Spanish, that is in bash

j=1;
for lng in fr en es 
	do 
		head=$(trans -b de:$lng Zusammenfassung)
		let "j=j+1"
		trans de:"$lng" -b -i /tex20/1de-ngerman-Zusammenfassung1.md 
		                   -o /tex20/"$j""$lng"-xxx-"$head".md 
	done

With cd ~/ev/tex/xmp/tex20; gvim -o {1..4}*.md the GUI version of vim starts31, :set spell will guess language and highlight not known spelling, <Leader>ct (for change thesaurus, my leader is \ ) will open multipaged suggestions for thesauri of various on- and offline sources32.

See the source and its output.

	`\begin{multicols}{4}`{=latex}
	🇩🇪`\worldflag{DE}`{=latex}
	{{/tex/xmp/tex20/1ade-ngerman-Zusammenfassung1.md}}
	`\columnbreak`{=latex}
	🇫🇷`\worldflag{FR}`{=latex}
	{{/tex/xmp/tex20/2afr-french-Résumé.md}}
	`\columnbreak`{=latex}
	🇬🇧`\worldflag{GB}`{=latex}
	{{/tex/xmp/tex20/3aen-english-Summary.md}}
	`\columnbreak`{=latex}
	🇪🇸`\worldflag{ES}`{=latex}
	{{/tex/xmp/tex20/4aes-spanish-Resumen.md}}
	`\end{multicols}`{=latex}  

Zusammenfassung: Dieser Kurztext befasst sich mit den Familienfreundliche Energiewende-Formen, dem Four Play der Energiewende33, den Ökonomische Inseln der Energiewende sowie deren Verhältnis untereinander. Ein hier vorgestellter Lösungsvorschlag soll das derzeitige Spannungsverhältnis der privaten und gewerblichen „4P“-Umsetzungsart überwinden. Zudem verbindet er die drei IDEW und stellt so einen pareto-optimalen Einsatz zwischen Off- und OnGrid-Technologien, BEV und BESSI, aber auch militärischer Sicherheit und demokratischer Freiheit her.

Der Text adressiert sich an Kenner der Energiewende.

Résumé: Ce court texte traite la transition énergétique familiale, les [?Quatre Grandes de la transition énergétique]34, les [?îlots économiques de la transition énergétique] et leurs relations les uns avec les autres. Une proposition de solution présentée ici vise à surmonter la tension actuelle entre la méthode de mise en œuvre privée et commerciale « 4P ». De plus, il relie les trois îles économiques de la transition énergétique et crée ainsi une utilisation Pareto-optimale entre les technologies sans et avec réseau, entre les véhicules électrique et les systèmes de stockage électrique à batterie, mais aussi au niveau de la sécurité militaire et de la liberté démocratique.

Le texte s’adresse aux connaisseurs de la transition énergétique.

Summary This short text deals with family-friendly forms of the energy transition, the four play (4P) of the energy transition35, the economic islands36 of the energy transition and their relationship to one another. The proposed solution presented is intended to overcome the current concurrence between the private and commercial “4P” implementation method. In addition, it connects the three very-economic islands of the energy transition and thus creates a Pareto-optimal use between off- and on-grid technologies, BEV and BESS37, but this also alters the level of national military security and economic and democratic freedom of individuals.

The text addresses itself to connoisseurs of the energy transition.

Resumen Este breve texto trata de las formas favoralefamiliares de la transición energética, los «cuatro juegos» (4P) de la transición energética38, las islas económicas de la transición energética y su relación entre sí. La solución propuesta que se presenta aquí tiene como objetivo superar la tensión actual entre el método y implementación «4P» privado y comercial. Además esta propuesta conecta los tres islas muchos económicas y, por lo tanto, crea un uso óptimo de Pareto entre las tecnologías fuera y en la red baja tensión, vehículo eléctrico de batería (VEB) y almacenamiento de energía (BESS)39, pero también seguridad militar y libertad democrática.

El texto se dirige a los conocedores de la transición energética.

Obviously the multicol package can handle even 4 columns without any parameters and break words in a narrow column environment. But syncing text in height is not foreseen. The last paragraph is loose.

GNU’s sed --seperate in combination with table columns

A more humanitarian and readable solution is to sync long texts at specified rows. This is done via the \selectcolumn*[column] – the star * – in the paracol command.

Since vim does not supply any Previewer for MMD for several common browsers, but BBEdit does, we have to build a wrapper for bbinclude to refresh sed -s outcome on multiple files. The base idea is to put onto stack 10 lines of each language, build and eventually sync rows and columns by a small bash script which is invoked by typing in BBEdit.

First we need a wrapper for BBEdit’s #bbinclude# (see p. 400, 1).

#!/usr/bin/env LANG=de_DE.UTF-8 COMMAND_MODE=legacy bash
DBG=0;j=-1;args=()
for i in $(seq 3 2 "${#@}") ; do
  let "j++";args+=( "${!i}" )
done
set "${args[@]}"  
[[ $DBG > 0 ]] && { printf "\n<br />%s" "<b>$0</b>" "$@" >> ~/ev/dbg/debug.html ; }
cmd="${args[*]}"
[[ $DBG > 1 ]] && { echo -e "\n<br />cmd=${cmd}" >> ~/ev/dbg/debug.html ; }
eval "${cmd}" ; echo $?;

Now we can copy a command from the shell, put it in backticks and apply the Text Filter.

Let us start with a simple multiline generating printf statement in the shell:

printf "%s\n" {1..2}{a..b}

The output is

1a
1b
2a
2b

and we want to print it to ~/home.txt.

Double quote any collating argument, put it into backticks and wrap it into a commentary string:

<!-- `shell2bbinclude_cmd.sh printf "%s\n" "{1..2}{a..b}" '>' ~/home.txt`

use Text Filter and the above expands to

<!-- #bbinclude "/Users/sm/Documents/evlka/tex/xmp/tex17/shell2bbinclude_wrapper.sh" #A#="printf" #B#="%s\n" #C#="{1..2}{a..b}" #D#=">" #E#="/Users/sm/home.txt" -->
<!-- end bbinclude -->

Now consider an on-the-fly 3-column paracol and more complex example. bbinc is an abbreviation for the fully expanded path (!) of the command shell2``bbinclude_cmd.sh and wrapped in backticks, type bbinc<CMD+S+V> while having selected the command you want to wrap from the terminal to BBEdit, e.g.

`/Users/sm/Documents/evlka/tex/xmp/tex17/shell2bbinclude_cmd.sh  ~/Documents/evlka/tex/xmp/tex17/paracoln.sh 3 00123  /Users/sm/Documents/evlka/tex/xmp/tex20/{1,2,3}a*.md ">" /Users/sm/Documents/evlka/tex/xmp/tex20/o123.md`

then again select in one-line the command wrapped with backticks in BBEdit, apply the Text Filter DefaultFilter_Markdown.sh and you receive from shell2bbinclude_cmd.sh within the current window of BBEdit the wrapped command

<!-- #bbinclude "/Users/sm/Documents/evlka/tex/xmp/tex17/shell2bbinclude_wrapper.sh" #A#="/Users/sm/Documents/evlka/tex/xmp/tex17/paracoln.sh" #B#="3" #C#="00123" #D#="/Users/sm/Documents/evlka/tex/xmp/tex20/1ade-ngerman-Zusammenfassung1.md" #E#="/Users/sm/Documents/evlka/tex/xmp/tex20/2afr-french-Résumé.md" #F#="/Users/sm/Documents/evlka/tex/xmp/tex20/3aen-english-Summary.md" #G#=">" #H#="/Users/sm/Documents/evlka/tex/xmp/tex20/o123.md" -->
<!-- end bbinclude -->

Simply include the generated-on-the-fly file with

 {{~/ev/tex/xmp/tex20/o123.md}}

and now each time you type any arbitrary sequence of characters into BBEdit’s window the new multilingual file is (re-)constructed via GNU sed and displayed in the Preview Window.

When you have finished editing just add an ‘␣’ into the #bbinclude to disable it. The BASH command becomes a normal commentary string and thus it will be accessible for future access or modifications. Note also if you would like you can shrink the multiple and ordered files supplied to sed --separate by changing #D="…" to

#D#="/xmp/tex20/{1,2,3}a*.md"

You can also further shrink this to

#D#="/xmp/tex20/{1..3}a*.md"

In any case you might want to write long bi- or tri-lingual sections, you may want to

#D#="/xmp/tex20/{1..3}{a..b}*.md"

Note that you have to change the line 4 in paracol-index.sh if you want to generate the newest possible variant files without checking details of the current folder. I wrote this for mine to produce multilingual manuals in landscape40 mode.

Please also be aware that you now have the full power of BASH within your MacVim, NeoVim, BBEdit in-parallel windows, say, if you need to compile some sections over some languages, first you should edit or experiment on the shell, e.g.

echo " "{a..b}{1,{4..5}}*.md

would expand to ‘a1*.md a4*.md a5*.md b1*.md b4*.md b5*.md’ and thus generates Section ‘a’ and ‘b’ over languages having ID 1,4 and 5.

🇩🇪 Zusammenfassung: Dieser Kurztext befasst sich mit den Familienfreundliche Energiewende-Formen, dem Four Play der Energiewende41, den Ökonomische Inseln der Energiewende sowie deren Verhältnis untereinander. Ein hier vorgestellter Lösungsvorschlag soll das derzeitige Spannungsverhältnis der privaten und gewerblichen „4P“-Umsetzungsart überwinden. Zudem verbindet er die drei IDEW und stellt so einen pareto-optimalen Einsatz zwischen Off- und OnGrid-Technologien, BEV und BESSI, aber auch militärischer Sicherheit und demokratischer Freiheit her.

🇫🇷 Résumé: Ce court texte traite la transition énergétique familiale, les [?Quatre Grandes de la transition énergétique]42, les [?îlots économiques de la transition énergétique] et leurs relations les uns avec les autres. Une proposition de solution présentée ici vise à surmonter la tension actuelle entre la méthode de mise en œuvre privée et commerciale « 4P ». De plus, il relie les trois îles économiques de la transition énergétique et crée ainsi une utilisation Pareto-optimale entre les technologies sans et avec réseau, entre les véhicules électrique et les systèmes de stockage électrique à batterie, mais aussi au niveau de la sécurité militaire et de la liberté démocratique.

🇬🇧 Summary This short text deals with family-friendly forms of the energy transition, the four play (4P) of the energy transition43, the economic islands44 of the energy transition and their relationship to one another. The proposed solution presented is intended to overcome the current concurrence between the private and commercial “4P” implementation method. In addition, it connects the three very-economic islands of the energy transition and thus creates a Pareto-optimal use between off- and on-grid technologies, BEV and BESS45, but this also alters the level of national military security and economic and democratic freedom of individuals.

Der Text adressiert sich an Kenner der Energiewende.

Le texte s’adresse aux connaisseurs de la transition énergétique.

The text addresses itself to connoisseurs of the energy transition.

Interestingly enough to note that word hyphenation works reliably not even only in a narrow column while applying \usepackage{microtype}, but also it seems to be a stable practise in html view, which, notably, is genereted through its own internal hyphen rules, e.g. firefox, safari and chrome all render differently, but properly. In fact, for many of them it is the same than LibreOffice or OpenOffice. To inspect finally all documents in all browsers the following statement might be useful.

for i in firefox safari chrome ; do open -a $i ~/ev/dbg/debug.{html,pdf} ; done

VIM

vimrc

" 
" taken from emilyst/home/the dotfiles"
"
"  0 preamble ==============================================================
"  1 important =============================================================
"  2 moving around, searching and patterns =================================
"  3 tags ==================================================================
"  4 displaying text and plugins============================================
" 4a Globals for Plugins ==================================================
"  5 syntax, highlighting and spelling =====================================
"  6 multiple windows ======================================================
"  7 multiple tab pages ====================================================
"  8 terminal ==============================================================
"  9 using the mouse =======================================================
" 10 GUI ==================================================================
" 11 printing =============================================================
" 12 messages and info ====================================================
" 13 selecting text =======================================================
" 14 editing text =========================================================
" 15 tabs and indenting ===================================================
" 16 folding ==============================================================
" 17 diff mode ============================================================
" 18 mapping ==============================================================
" 19 reading and writing files ============================================
" 20 the swap file ========================================================
" 21 command line editing =================================================
" 22 executing external commands ==========================================
" 23 running make and jumping to errors ===================================
" 24 language specific ====================================================
" 25 multi-byte characters ================================================
" 26 various =============================================================
" 27 globals =============================================================
"
" 1 important ============================================================= {{{
set rtp+=/usr/local/opt/fzf

"source $VIMRUNTIME/ftplugin/man.vim

if has('gui')
    source $VIMRUNTIME/vimrc_example.vim
    set guioptions+=a
    set nowrap
    set macmeta
    map <c-m-o> xh 
    map <c-m-p> dw
    map <c-m-b> db
    map <c-m-n> d<left><left> 
endif
set cmdheight=2
"set autoread 
set nocompatible
set exrc
let b:is_bash = 1


" ========================================================================= }}}

" 2 moving searching ====================================================== {{{

" fn arrow 14 lines, ctrl arrow 3 lines, alt arrow next paragraph

map <c-up> 3k
map <c-down> 3j


"  set hlsearch
"set incsearch
set ignorecase
"set smartcase

let mapleader = "\\""

function! Repeat()
    let times = input("Count: ")
    let char  = input("Char: ")
    exe ":normal a" . repeat(char, times)
endfunction

imap <C-u> <C-o>:call Repeat()<cr>

"nnoremap qd :silent! normal mpea"<Esc>bi"<Esc>`pl
"nnoremap qw :silent! normal <Esc>mpea'<Esc>bi'<Esc>`pl
"nnoremap qm :silent! normal mpea*<Esc>bi*<Esc>`pl
"nnoremap qp :silent! normal mpea\|<Esc>bi\|<Esc>`pl
"nnoremap wq :silent! normal mpeld bhd `ph<CR>
noremap q b 

vnoremap (( "sc(<C-r>s)<Esc>
vnoremap qc "sc{<C-r>s}<Esc>
vnoremap "" "sc"<C-r>s"<Esc>
vnoremap '' "sc'<C-r>s'<Esc>

" Quote-like inner word consisting of letters from iskeyword.
nnoremap <silent> qw :call Quote('"')<CR>
nnoremap <silent> qs :call Quote("'")<CR>
nnoremap <silent> qm :call Quote("*")<CR>
nnoremap <silent> mq "ds*<esc>
nnoremap <silent> q_ :call Quote("_")<CR>
nnoremap <silent> qq :exe "norm! ysiw" 
nnoremap <silent> wq :call UnQuote()<CR>
nnoremap <silent> <Leader>qq :exe "norm mz" \|:set iskeyword+=@-@,36,42,91,93,123,125 \|:echo 'iskeywordExtendedOn' \|:exe "norm `z" <cr>
nnoremap <silent> <Leader>qe :set iskeyword-=@-@,36,42,91,93,123,125 \| :echo 'iskeywordExtendedOff'<cr>
nnoremap <silent> <Leader>qa :set nrformats+=alpha \| :echo 'nrformatsExtendedOnAlpha'<cr>
nnoremap <silent> <Leader>qn :set nrformats-=alpha \| :echo 'nrformatsExtendedOffAlpha'<cr>

"                 mark {                  del spaces            go bac
"nnoremap qf :exe "norm ^F{mzj"   \| :.,+6 s/\s*$//gec   \| :exe "norm `z"             \| :.,+6 s/\(do\)\@<!\n\(\s*\)/\1; /gec              \| :exe "norm `z" \| :.,.+2 s/\(\s*\)\n/\1/gec <CR> 

"nnoremap qu :exe "norm ^f{l mz" \| :.-1,.+1 s/\(\S\);/\1±/gec \| :.,.+3 s/\(\s\{2,\}\);\(\s*\)/±\1\2/gec \| :.,.+1 s/±\s\=/\r/gec <CR>
"                 mark {                  set ± keep spaces               set±

" folding f-j
nnoremap q0 :exe "norm mz^F{m<%m>%" 
nnoremap q1 :exe "norm mz" 
nnoremap q5 :* s/\s\{3,\}$//ge \| :* s/\s#.*$//ge \| :* s/[;\s]*$//ge  
nnoremap q6 :.-3,+3 s/^#[^ ].*\n//g
nnoremap q7 :.-3,+3 s/\n\s*\n\s*\n\+/\r\r/g
nnoremap qg :* s/[\n\r]/±/ge
nnoremap qh :* s/\(in\\|then\\|else\\|do\)\s*±/\1±±/gec 
nnoremap qi :* s/±±/\<Nul>/gec \| :* s/±/;\<Nul>/gec 
nnoremap qj :* s/{\(\s\)*;/{\1/gec 
"assemble lines form 'qf' to 'qj' to 'qF'
"r! echo -n "nnoremap qF " ; sed -n -e '101,+4p' ~/.vim/vimrc | tr '\n' ' ' | sed -n -e 's/nnoremap q[f-j]/\\\|/g' -e 's/\/gec/\/ge/gp'
" end folding f-j

" now in one
nnoremap qF :exe "norm mz^F{m<%m>%" \| :* s/\s#.*$//ge \| :* s/\s\{3,\}\n$//ge \| :* s/;\s*$//ge  \| :* s/[\n\r]/±/ge \| :* s/\(in\\|then\\|else\\|do\)\s*±/\1±±/ge  \| :* s/±±/\<Nul>/ge \| :* s/±/;\<Nul>/ge  \| :* s/{\(\s\)*;/{\1/ge \| :exe norm "`z" 
vnoremap qG : s/\s#.*$//ge \| :* s/\s\{3,\}\n$//ge \| :* s/;\s*$//ge  \| :* s/[\n\r]/±/ge \| :* s/\(in\\|then\\|else\\|do\)\s*±/\1±±/ge  \| :* s/±±/\<Nul>/ge \| :* s/±/;\<Nul>/ge  \| :* s/{\(\s\)*;/{\1/ge  

"nnoremap <C-@> {rhs}
"nnoremap <Nul> {rhs}

" unfolding: aus zwei mach eins, dann \n 
nnoremap qu :exe "norm mz" \| s/;\([\x0]\)/\1/ge \| s/[\x0]/\r/ge \| :exe "norm `z" 

" echo may dissapear after 4 seconds
"autocmd CursorHold * echo
"autocmd FocusLost * echo

function! s:empty_message(timer)
  if mode() ==# 'n'
    echon '-'
  endif
endfunction

augroup cmd_msg_cls
    autocmd!
    "autocmd CursorHold * call timer_start(25000, funcref('s:empty_message'))
    autocmd CmdLineLeave : call timer_start(25000, funcref('s:empty_message'))
augroup END
" end of making noise dissapear

function! Quote(quote)
  normal mz
  exe 's/\(\k*\%#\k*\)/' . a:quote . '\1' . a:quote . '/'
  normal `zl
endfunction

function! UnQuote()
  normal mz
  exe 's/["' . "'" . ']\(\k*\%#\k*\)[' . "'" . '"]/\1/'
  normal `z
endfunction

" Press F8 to highlight search word under cursor
nnoremap <F8> :let @/='\<<C-R>=expand("<cword>")<CR>\>'<CR>:set hls<CR>

" Press F4 to toggle highlighting on/off"  and show current value.
noremap <F4> :set hlsearch! hlsearch?<CR>

" iterm2 integration
noremap <Leader>ff :call SendToTerminal(substitute(@*,"\n"," ","g")) \|:exe "norm! gv"<CR> 
noremap <Leader>gg :call SendToTerminal("clear")<CR> 
noremap <Leader>tr :call SendToTerminal("transn \"" . substitute(@*,"\n"," ","g") . "\"") \|:exe "norm! gv"<CR> 
noremap <Leader>lc :call SendToTerminal('\!\!') \| :call SendToTerminal("")<CR>
" Window resizing mappings 
nnoremap <S-Up> <C-w>+
nnoremap <S-Down> <C-w>-
nnoremap <S-Left> <C-w><
nnoremap <S-Right> <C-w>>

" Jumping faster between tabs
nnoremap <C-S-right> <C-w>l
nnoremap <C-S-left> <C-w>h
nnoremap <C-S-Up> <C-w>k
nnoremap <C-S-Down> <C-w>j
if has('gui')
 nnoremap <D-right> <C-w>l
 nnoremap <D-left> <C-w>h
 nnoremap <D-Up> <C-w>k
 nnoremap <D-Down> <C-w>j
 let macvim_skip_cmd_opt_movement = 1
endif
" ========================================================================= }}}

" 3 tags=================================================================== {{{



" ========================================================================= }}}

" 4 displaying text and plugins============================================ {{{


" ========================================================================= }}}

" 5 syntax, highlighting and spelling====================================== {{{

packadd! matchit
set omnifunc=syntaxcomplete#Complete

": if has("autocmd") && exists("+omnifunc")
        "autocmd Filetype *
                    "\   if &omnifunc == "" |
                    "\           setlocal omnifunc=syntaxcomplete#Complete |
                    "\   endif
    "endif


if has('spell')
  set nospell
"   set dictionary=/usr/share/dict/words
   set dictionary=/usr/share/dict/propernames
  set complete+=kspell
  " Manually Added Words Are Sent To `Names` Dictionary
  nnoremap zG 2zg
endif

"nnoremap <Leader>ct :ThesaurusQueryReplaceCurrentWord<CR>
let g:tq_map_keys=1
let g:tq_use_vim_autocompletefunc=1
let g:tq_openoffice_en_file="/Users/sm/.vim/thesaurus/th_en_US_v2.dat"
let g:tq_enabled_backends=["mthesaur_txt",
            \"openthesaurus_de",
            \"woxikon_de",
            \"cnrtl_fr",
            \"synonymo_fr",
            \"datamuse_com",]

let g:tq_language=['de', 'fr', 'en', 'es' ]
set spelllang=de
set spelllang+=fr
set spelllang+=en
set spelllang+=es
function! s:ToggleSpellLanguage(lang)
  if a:lang == 'none'
    set spellfile=
    set spelllang=
    set nospell
    call evlk#ReRead()
    return
  else
    let &spellfile=expand('~/.vim/spell/' . a:lang . '.utf-8.add') . ',' . expand('~/.vim/spell/names.utf-8.add')
    if a:lang == 'all'
      set spelllang=en,fr,sk,nl,bg,el,es,sl,uk,hu,pl,de,it,ru,no,pt,hr,ca,fi,sv,cs,da,ro,sr,lt,lv,et,tr
    elseif a:lang == 'ende'
      set spelllang=en,de
      call evlk#ReRead()
      set thesaurus =~/.vim/thesaurus/mthesaur.txt
      set thesaurus+=~/.vim/thesaurus/openthesaurus.txt
      let b:tq_language=['en','de']
    elseif a:lang == 'frde'
      set spelllang=fr,de
      call evlk#ReRead()
      set thesaurus+=~/.vim/thesaurus/openthesaurus.txt
      let b:tq_language=['fr','de']
    elseif a:lang == 'defr'
      set spelllang=de,fr
      set thesaurus= 
      set thesaurus+=~/mysynonyms.txt
      set thesaurus+=~/.vim/thesaurus/openthesaurus.txt
      let b:tq_language=['de','fr']
    elseif a:lang == 'defren'
      set spelllang=de,fr,en
      set thesaurus= 
      set thesaurus+=~/mysynonyms.txt
      set thesaurus+=~/.vim/thesaurus/openthesaurus.txt
      set thesaurus+=~/.vim/thesaurus/mthesaur.txt
      let b:tq_language=['de','fr','en']
    elseif a:lang == 'fr'
      set spelllang=fr
      "call evlk#ReRead()
      set thesaurus= 
      let b:tq_language=['fr']
    elseif a:lang == 'bg'
      set spelllang=bg
    elseif a:lang == 'ca'
      set spelllang=ca
    elseif a:lang == 'cs'
      set spelllang=cs
    elseif a:lang == 'da'
      set spelllang=da
    elseif a:lang == 'de'
      set spelllang=de
      set thesaurus=''
      set thesaurus+=~/.vim/thesaurus/openthesaurus.txt
      call evlk#ReRead()
      let b:tq_language=['de'] 
    elseif a:lang == 'en'
      set spelllang=en
      set thesaurus-=~/.vim/thesaurus/openthesaurus.txt
      call evlk#ReRead()
      let b:tq_language=['en']
    elseif a:lang == 'el'
      set spelllang=el
    elseif a:lang == 'es'
      set spelllang=es
      call evlk#ReRead()
      let b:tq_language=['es'] 
    elseif a:lang == 'et'
      set spelllang=et
    elseif a:lang == 'fi'
      set spelllang=fi
    elseif a:lang == 'fr'
      set spelllang=fr
      let g:tq_language=fr
      call evlk#ReRead()
    elseif a:lang == 'hr'
      set spelllang=hr
    elseif a:lang == 'hu'
      set spelllang=hu
    elseif a:lang == 'it'
      set spelllang=it
    elseif a:lang == 'lt'
      set spelllang=lt
    elseif a:lang == 'lv'
      set spelllang=lv
    elseif a:lang == 'nl'
      set spelllang=nl
    elseif a:lang == 'no'
      set spelllang=no
    elseif a:lang == 'pl'
      set spelllang=pl
    elseif a:lang == 'pt'
      set spelllang=pt
    elseif a:lang == 'ro'
      set spelllang=ro
    elseif a:lang == 'ru'
      set spelllang=ru
    elseif a:lang == 'sk'
      set spelllang=sk
      let b:tq_language=['sk','en']
    elseif a:lang == 'sl'
      set spelllang=sl
    elseif a:lang == 'sr'
      set spelllang=sr
    elseif a:lang == 'sv'
      set spelllang=sv
    elseif a:lang == 'tr'
      set spelllang=tr
    elseif a:lang == 'uk'
      set spelllang=uk
    endif
    set spell
  endif
endfunction
command! -nargs=1 ToggleSpellLanguage call <sid>ToggleSpellLanguage(<q-args>)

" ========================================================================= }}}

"  6 Multiple buffers/tabs================================================= {{{
" use ~/{save,launch)_gvim_sessions.sh
" use Startify Plugin with NERDTreeBookmarks
" Read ~/.NERDTreeBookmarks file and takes its second column
" :FZF fuzzy finder
"
let g:startify_bookmarks = systemlist("cut -sd' ' -f 2- ~/.NERDTreeBookmarks")

command! -nargs=* Terminal split | lcd %:h | terminal ++curwin <args>

" ========================================================================= }}}


" 10 GUI=================================================================== {{{

set title titlestring=%<%F%=%l/%L-%P titlelen=70

" restore last session
set sessionoptions+=resize,winpos
"autocmd VIMEnter * :source ~/session.vim
"autocmd VIMLeave * :mksession! ~/session.vim

" ========================================================================= }}}


" 11 printing============================================================== {{{


" ========================================================================= }}}


" 12 messages and info===================================================== {{{



" ========================================================================= }}}


" 13 selecting text======================================================== {{{



" ========================================================================= }}}


" 14 editing text========================================================== {{{

" Only use cursorline for current window
autocmd WinEnter,FocusGained * setlocal cursorline
autocmd WinLeave,FocusLost   * setlocal nocursorline

" ========================================================================= }}}


" 25 multibyte characters 25 multibyte characters ========================= {{{

set encoding=utf-8
"set fileencoding=utf-8
set termencoding=utf-8

" ========================================================================= }}}

" 4 displaying text & Plugins============================================== {{{

set number relativenumber
syntax enable
set noswapfile
set scrolloff=7
set backspace=indent,eol,start

"set fileformat=unix

call plug#begin('~/.vim/plugged')

Plug 'morhetz/gruvbox'
Plug 'jiangmiao/auto-pairs'
Plug 'scrooloose/nerdtree'
Plug 'preservim/nerdcommenter'
Plug 'norcalli/nvim-colorizer.lua'
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
Plug 'Valloric/YouCompleteMe'

Plug 'sirver/ultisnips'

Plug 'tpope/vim-surround'
Plug 'tpope/vim-unimpaired'

Plug 'chrisbra/improvedft'

Plug 'junegunn/vim-easy-align'
Plug '/usr/local/opt/fzf'

"Plug 'luochen1990/rainbow'

Plug 'nelsyeung/twig.vim'

Plug 'dhruvasagar/vim-table-mode'
Plug 'ron89/thesaurus_query.vim'

Plug 'mhinz/vim-startify'

Plug 'prabirshrestha/async.vim'
Plug 'prabirshrestha/vim-lsp'
Plug 'mattn/vim-lsp-settings'

Plug 'prabirshrestha/asyncomplete.vim'
Plug 'prabirshrestha/asyncomplete-lsp.vim'

Plug 'WolfgangMehner/bash-support'

"Plug 'thomasfaingnaert/vim-lsp-snippets'
"Plug 'thomasfaingnaert/vim-lsp-ultisnips'

Plug 'lervag/vimtex'

if has('nvim')
Plug 'nikvdp/neomux'
Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'}  " We recommend updating the parsers on update
endif
call plug#end()

" LSP pop-ups from manual and info, I use help2man.pl to generate my mans with
" sed $0 'self-strip'
runtime ftplugin/man.vim
nnoremap K :<C-U>exe "Man" v:count "<C-R><C-W>"<CR>

let g:ycm_key_list_select_completion = ['<C-n>', '<Down>']
let g:ycm_key_list_previous_completion = ['<C-p>', '<Up>']
let g:SuperTabDefaultCompletionType = '<C-n>'

" better key bindings for UltiSnipsExpandTrigger
let g:UltiSnipsExpandTrigger = "<tab>"
let g:UltiSnipsJumpForwardTrigger = "<tab>"
let g:UltiSnipsJumpBackwardTrigger = "<s-tab>"

let g:UltiSnipsJumpForwardTrigger="<c-b>"
let g:UltiSnipsJumpBackwardTrigger="<c-z>"

" If you want :UltiSnipsEdit to split your window.
let g:UltiSnipsEditSplit="vertical"

function! s:CustomizeYcmLocationWindow()
  " Move the window to the top of the screen.
  wincmd K
  " Set the window height to 5.
  5wincmd _
  " Switch back to working window.
  wincmd p
endfunction

let g:ycm_max_num_identifier_candidates = 80

autocmd User YcmLocationOpened call s:CustomizeYcmLocationWindow()

let g:lsp_semantic_enabled=1

function! s:on_lsp_buffer_enabled() abort
    setlocal omnifunc=lsp#complete
    setlocal signcolumn=yes
    if exists('+tagfunc') | setlocal tagfunc=lsp#tagfunc | endif
    nmap <buffer> gd <plug>(lsp-definition)
    nmap <buffer> gs <plug>(lsp-document-symbol-search)
    nmap <buffer> gS <plug>(lsp-workspace-symbol-search)
    nmap <buffer> gr <plug>(lsp-references)
    nmap <buffer> gi <plug>(lsp-implementation)
    nmap <buffer> gt <plug>(lsp-type-definition)
    nmap <buffer> <leader>rn <plug>(lsp-rename)
    nmap <buffer> [g <plug>(lsp-previous-diagnostic)
    nmap <buffer> ]g <plug>(lsp-next-diagnostic)
    nmap <buffer> K <plug>(lsp-hover)
    inoremap <buffer> <expr><c-f> lsp#scroll(+4)
    inoremap <buffer> <expr><c-d> lsp#scroll(-4)

    let g:lsp_format_sync_timeout = 1000
    autocmd! BufWritePre *.rs,*.go call execute('LspDocumentFormatSync')

    " refer to doc to add more commands
endfunction

nnoremap <leader>lb LspDocumentBuild() \| :echo 'LspDocumentBuild'<CR>

colorscheme gruvbox
autocmd vimenter * ++nested colorscheme gruvbox

if has('gui')
    set background=dark
    set transparency=5
endif

if has('nvim')
    let g:vimtex_compiler_progname = 'nvr'
    highlight Normal ctermbg=NONE guibg=NONE
  "let g:vimtex_view_skim_activate = 1
endif
let g:vimtex_view_method = 'skim' 


" ========================================================================= }}}

" 4a Globals, esp. for Plugins============================================= {{{
let g:BASH_MapLeader  = ','
let g:NERDCreateDefaultMappings = 1
let g:rst_style = 1 " aus vim-plug"

autocmd FileType markdown,rst :silent TableModeEnable
autocmd FileType markdown,rst,tex,latex,html :silent set autoread 

au FocusGained,BufEnter * :silent! !

autocmd FileType markdown
\ let g:table_mode_corner = "|" |
\ let g:table_mode_corner_corner = "|" |
\ let g:table_mode_header_fillchar = "-" |
\ let g:table_mode_align_char = ":"
autocmd FileType rst,sh
\ let g:table_mode_corner = "+" |
\ let g:table_mode_corner_corner = "+" |
\ let g:table_mode_header_fillchar = "="

" ========================================================================= }}}

" 15 tabs and indenting =================================================== {{{

set tabstop=4
set softtabstop=4
set shiftwidth=4
set tw=0
set expandtab
set autoindent
set nowrap

filetype indent plugin on

" ========================================================================= }}}

" 18 mapping ==================================================== {{{

" keep centered when next hit
nnoremap n nzzzv
nnoremap N Nzzzv

" Same when jumping around
nnoremap g; g;zz
nnoremap g, g,zz
nnoremap <c-o> <c-o>zz

nnoremap cp :let @*='"' . expand("%:p") . '"'<CR>

" remappable because of matchit.vim
nmap <tab> %
vmap <tab> %
" ========================================================================= }}}

" 18 mapping ==================================================== {{{

"move lines 
nnoremap ∆ :m .+1<CR>==
nnoremap ˚ :m .-2<CR>==
inoremap ∆ <Esc>:m .+1<CR>==gi
inoremap ˚ <Esc>:m .-2<CR>==gi
vnoremap ∆ :m '>+1<CR>gv=gv
vnoremap ˚ :m '<-2<CR>gv=gv

nnoremap <A-j> :m .+1<CR>==
nnoremap <A-k> :m .-2<CR>==
inoremap <A-j> <Esc>:m .+1<CR>==gi
inoremap <A-k> <Esc>:m .-2<CR>==gi
vnoremap <A-j> :m '>+1<CR>gv=gv
vnoremap <A-k> :m '<-2<CR>gv=gv

" toggle character word{l,r} line paragraph {
:nnoremap <silent> gc xph
:nnoremap <silent> gw "_yiw:s/\(\%#\w\+\)\(\W\+\)\(\w\+\)/\3\2\1/<CR><c-o><c-l>:nohlsearch<CR>
:nnoremap <silent> gl "_yiw?\w\+\_W\+\%#<CR>:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<CR><c-o><c-l>:nohlsearch<CR>
:nnoremap <silent> gr "_yiw:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<CR><c-o>/\w\+\_W\+<CR><c-l>:nohlsearch<CR>
:nnoremap g{ {dap}p{

" quickly open .vimrc ok
nnoremap <leader>ev :exec 'edit ' .  $HOME . "/.vim/vimrc"<CR>:set nohlsearch<CR>
nnoremap <leader>eb <c-w>s<cr>:exec 'edit ' .  $HOME . "/.bash_profile"<CR>"<c-w>s<cr>:set nohlsearch<CR>
nnoremap <leader>Eb <c-w>s<cr>:exec 'edit /etc/bashrc'<CR>:sleep 1<cr>:set nohlsearch<CR>
nnoremap <leader>cr :silent exec '!chrome-cli reload;'<cr> 
nnoremap <leader>sa :so ~/.vim/spell/myabbreviations.vim \| :so ~/.vim/spell/myabbreviations1.vim \| :set isk?<CR>
nnoremap <leader>sA :abclear \| :set iskeyword-=46,@-@ \| :echon ':abc' \| :sleep 500m \| :echon '' \| :set isk?<CR>


nmap ,td :!(cd %:p:h;ctags *.[ch];)&<CR><CR>
nmap ,tr :!(cd %:p:h;find * -type d -exec dirtags.sh {} \;)&<CR><CR>
nmap ,Tm :!(cd %:p:h;ctags --extras=-F -R;)&<CR><CR>
set tags=./tags,tags,~/ev/tags

let g:airline#extensions#tabline#buffer_nr_show = 1

function! ListBuffer()
    let mybuflist = ['BufListRemotReq!']
  for i in range(1, bufnr('$'))
      if buflisted(i)
        "echo i . ' ' . fnamemodify(bufname(i), ':p')
        call add( mybuflist , i . ' ' . fnamemodify(bufname(i), ':p') )
        "return i . ' ' . fnamemodify(bufname(i), ':p')
      endif
  endfor
  echo join(mybuflist,"\n")
  return join(mybuflist,"\n")
endfunction

if has('gui')
 nnoremap <leader>sv :set transparency+=10 \| :exec 'source ' . $HOME . "/.vim/vimrc" \| :set nohlsearch \| :echo '"/.vim/vimrc" sourced.' \| :set transparency-=4<CR>
else
 nnoremap <leader>sv :exec 'source ' . $HOME . "/.vim/vimrc" \| :set nohlsearch \| :echo '"/.vim/vimrc" sourced.' <CR>
endif

nnoremap <leader>rb :RainbowToggle<CR>
let g:rainbow_active = 1

nnoremap <leader>nn :NERDTreeToggle<CR>
nnoremap <leader>nc :NERDTreeFocus<CR>
nnoremap <leader>nf :NERDTreeFind<CR>
nnoremap <leader>nT :call MyNERDTreeNetrwToggle()<CR>

nnoremap=j :%!python -m json.tool<CR>

nnoremap <leader>] :set transparency+=5<cr>
nnoremap <leader>[ :set transparency-=5<cr>

nnoremap <leader>LL :call s:MyToggleVimTeXCompilerMethod()<cr> 

let g:vimtex_compiler_methodMyNumber=0

function! s:MyToggleVimTeXCompilerMethod()     " Switch arara, latexmk and tectonic for vimtex.vim Plug
    let s:vimtex_compiler_methodMyNumber = s:vimtex_compiler_methodMyNumber + 1
    sleep 1
    echo "s:vimtex_compiler_methodMyNumber = " s:vimtex_compiler_methodMyNumber
    if s:vimtex_compiler_methodMyNumber == 2 
        echo "arara"
    elseif s:vimtex_compiler_methodMyNumber == 3
        echo "tectonic"
    elseif s:vimtex_compiler_methodMyNumber == 4
        let s:vimtex_compiler_methodMyNumber = 0
        echo "latexmk"
    endif
endfunction

  "if !exists('g:ycm_semantic_triggers')
    "let g:ycm_semantic_triggers = {}
  "endif

  "au VimEnter * let g:ycm_semantic_triggers.tex=g:vimtex#re#youcompleteme

" the following toggle function is too slow for TeX-Live root caching dirs  
function! MyNERDTreeNetrwToggle()
    if g:NERDTreeHijackNetrw 
        let g:NERDTreeHijackNetrw = 0
    else
        let g:NERDTreeHijackNetrw = 1
    endif
    echom 'g:NERDTreeHijackNetrw = ' . g:NERDTreeHijackNetrw 
endfunction

let NERDTreeNaturalSort = 1
set modifiable
let g:NERDTreeHijackNetrw = 0

" back highjacking? not an easy option
" Highjack nerdtree's highjacking to keep normal nerdtree from loading on directories
"let g:NERDTreeHijackNetrw=0
"augroup NERDTreeHijackNetrw
    "autocmd VimEnter * silent! autocmd! FileExplorer
"augroup END

" that does not work fast enough, switch back to netrw is better
nnoremap <leader>n4 :set ma \| :let NERDTreeSortOrder= ['[[-timestamp]]'] \| :echom 'sort by timestamp' \| :exec "normal! R"  
nnoremap <leader>n&2 :let NERDTreeSortOrder= ['[[extension]]'] \| :exec "normal! R"  \| :echom 'sort by extension'
nnoremap <leader>n6 :let NERDTreeSortOrder= ['[[-size]]']      \| :exec "normal! R"  \| :echom 'sort by size'
nnoremap <leader>n1 :set ma \| :let NERDTreeSortOrder= ['\/$', '*', '\.swp$', '\.bak$', '\~$'] \| :exec "normal! R" \| :echom 'sort by name'
"<CR>
" taken from https://vim.fandom.com/wiki/Open_file_under_cursor#Names_containing_spaces
set isfname+=32



"netrw
let g:netrw_sizestyle="h"

":redir >> ~/mymaps.txt
":map
":redir END

"Plug 'junegunn/vim-easy-align'
" Start interactive EasyAlign in visual mode (e.g. vipga)
xmap ga <Plug>(EasyAlign)

" Start interactive EasyAlign for a motion/text object (e.g. gaip)
nmap ga <Plug>(EasyAlign)

let g:lsp_diagnostics_enabled       = 1
let g:lsp_diagnostics_echo_delay    = 1000
let g:lsp_diagnostics_float_cursor  = 1
let g:lsp_diagnostics_float_delay   = 2500
let g:lsp_diagnostics_signs_error   = {'text': '☞'}
let g:lsp_diagnostics_signs_warning = {'text': '✗'}
let g:lsp_diagnostics_signs_hint    = {'text': '❀'}
let g:lsp_show_message_log_level    = 'error'

" switched to .latexmkrc and lualatex with cm unicode font
"if has('nvim')
    "let g:vimtex_compiler_method = 'latexmk'
    "echo 'nvim detected'
"endif
"if has('gui_macvim')
 "let g:vimtex_compiler_method = 'arara'
"endif
" ================================================================ }}}

" 21 command line editing ======================================== {{{

set history=5000
set wildmode=list:longest,full
set wildignore+=*.o,*.obj,.git,*.rbc,*.class,.svn,vendor/gems/*,*.bak,*.exe,target,tags,.tags,*/.git/*
set wildignore+=*.pyc,*.DS_Store,*.db
set wildignore+=versions/*,cache/*
set fileignorecase
set wildignorecase
set wildmenu

" ================================================================ }}}

" 22 external commands============================================ {{{

function! SendToTerminal(args)
  execute ":silent !run_command '" . a:args . "'"
endfunction

function! s:get_visual_selection()
    " Why is this not a built-in Vim script function?!
    let [line_start, column_start] = getpos("'<")[1:2]
    let [line_end, column_end] = getpos("'>")[1:2]
    let lines = getline(line_start, line_end)
    if len(lines) == 0
        return ''
    endif
    let lines[-1] = lines[-1][: column_end - (&selection == 'inclusive' ? 1 : 2)]
    let lines[0] = lines[0][column_start - 1:]
    return join(lines, "\n")
endfunction

" ================================================================ }}}

function! TextEnableCodeSnip(filetype,start,end,textSnipHl) abort
  let ft=toupper(a:filetype)
  let group='textGroup'.ft
  if exists('b:current_syntax')
    let s:current_syntax=b:current_syntax
    " Remove current syntax definition, as some syntax files (e.g. cpp.vim)
    " do nothing if b:current_syntax is defined.
    unlet b:current_syntax
  endif
  execute 'syntax include @'.group.' syntax/'.a:filetype.'.vim'
  try
    execute 'syntax include @'.group.' after/syntax/'.a:filetype.'.vim'
  catch
  endtry
  if exists('s:current_syntax')
    let b:current_syntax=s:current_syntax
  else
    unlet b:current_syntax
  endif
  execute 'syntax region textSnip'.ft.'
  \ matchgroup='.a:textSnipHl.'
  \ keepend
  \ start="'.a:start.'" end="'.a:end.'"
  \ contains=@'.group
endfunction

" ===================================================================
"
if has('cscope')
  set cscopetag cscopeverbose

  if has('quickfix')
    set cscopequickfix=s-,c-,d-,i-,t-,e-
  endif

  cnoreabbrev csa cs add
  cnoreabbrev csf cs find
  cnoreabbrev csk cs kill
  cnoreabbrev csr cs reset
  cnoreabbrev css cs show
  cnoreabbrev csh cs help

  command -nargs=0 Cscope cs add $VIMSRC/src/cscope.out $VIMSRC/src
endif


cnoreabbrev <expr> csa ((getcmdtype() == ':' && getcmdpos() <= 4)? 'cs add'  : 'csa')
cnoreabbrev <expr> csf ((getcmdtype() == ':' && getcmdpos() <= 4)? 'cs find' : 'csf')
cnoreabbrev <expr> csk ((getcmdtype() == ':' && getcmdpos() <= 4)? 'cs kill' : 'csk')
cnoreabbrev <expr> csr ((getcmdtype() == ':' && getcmdpos() <= 4)? 'cs reset' : 'csr')
cnoreabbrev <expr> css ((getcmdtype() == ':' && getcmdpos() <= 4)? 'cs show' : 'css')
cnoreabbrev <expr> csh ((getcmdtype() == ':' && getcmdpos() <= 4)? 'cs help' : 'csh')

run_command

#!/usr/bin/env osascript
on run argv
  tell application "iTerm"
    tell the first window 
      tell the current session
        write text argv as string
      end tell
    end tell
  end tell

  tell application "MacVim"
    activate
  end tell
end run 

especially mapped to transn for coping with ‘babel’-round-trips and to be consistent with ~/.bash_history and history.

transn

#!/usr/local/bin/bash
# invoked via readline for my daugther Ella Christin
# or via ARGS for debugging 'babel' in my macvim-iterm2
# writings
input="$([[ -p /dev/stdin ]] && cat - || echo "$@")"
[[ -z "$input" ]] && exit 1 

mapfile -t identify < <(trans -j -identify $input)
j=-1
lang=${identify[4]//Code }
lang=${lang// }
[[ $lang == *de* ]] && say $input
[[ $lang == *fr* ]] && say -i -v Audrey $input
[[ $lang == *es* ]] && say -i -v Jorge  $input
[[ $lang == *en* ]] && say -i -v Fiona  $input

#trans -j -e bing -identify -speak -no-translate $input 
#trans -j -identify -speak -no-translate $input 
echo $input | trans -b :de -speak -p

opening multiple lingual files one after another in current vim (w/o GUI) buffer is done via

:args /Users/sm/Documents/evlka/tex/xmp/tex20/{1..4}*.md 

opening them with multiple splits vs (vertical) sp (horizontal) is done in two steps

:argadd ~/ev/tex/xmp/tex20/{1,2,3}a*.md
:argdo sp

You now should check that :set spell is on and vim auto-checked the current’s buffer language and then typing vis\tr (*visually inner sentence call transn *) will read the current sentence in the foreign language an highlight every word while speaking with siri’s text2speach-engines, then pause and then re-translate (make a round-trip) to your native language and read it loadly. Once round-trip is correct, you can be sure that translation is correct (but you can not say anothing about overall quality).

BBEdit

historical abbrev|long|glossary.csv generated the MultiMarkDown-Files

#!/usr/bin/env bash
DBG=0
# three column csv 'dual entry type' to MultiMarkDown
# obsolete since multilingual access is poor
# and files from 'old glossaries' gotten tooo long

AB1=~/Desktop/t/abbrev1a.md
AB2=~/Desktop/t/abbrev2a.md
[[ $DBG == 1 ]] && { for i in "${!AB@}" ; do eval echo \"$0\" > \""\${$i}"\" ; done ; 
echo Schreibe mit "$0" und "$@" nach "${AB1}" und "${AB2}"
echo '<--'$(date | tr -s $'\n')' -->'> "${AB1}"
echo '<--'$(date | tr -s $'\n')' -->'> "${AB2}"
}
#exit;
#@begin=perl@                              # filetype vim extension
perl -i -pe 'END { print "\@ignored=", @ignored} BEGIN {
	use feature 'unicode_strings';
    open R,">/usr/local/bin/keywords-sh21pl.txt" or die;
    open AB1,">>'"${AB1}"'" or die;
    open AB2,">>'"${AB2}"'" or die; 
	while(<>) {
	  chomp;
      ($abbrev,$along,undef, $glossary)=split(",",$_ ,4 );
      #print "|$abbrev,$along,$glossary,|" if '$DBG'; 
      print AB1 "[>$abbrev]:"." " x (8 - length($abbrev))."$along  \n\n";
      print AB2 "[?$along]:"." " x (50 - length($along))."$glossary  \n\n";
      print R "$abbrev\t\t[?$along] \n";
	}
	close R;close AB1; close AB2;
    #$re=join("|",map {quotemeta} keys %s) # if quoting is needed
}' "$@";                                    # beware, this is bash calling perl
#s/($re)/$s{$1}/ego;                       # do this here
#@end=perl@                                # end filetype vim extension

historical abbrev{1,2}.md transcluded in Preview

#!/usr/bin/env LANG=de_DE.UTF-8 COMMAND_MODE=legacy bash
DBG=0
transcludebase='/Users/sm/Desktop/t/'
cat - "$transcludebase"{footnote*,abbrev{1..2}}.md | multimarkdown

[[ $DBG == 1 ]] && {
  mapfile -t ENV < <(env | sed 's/\n/\n<br \/>/g' | sort)
  for i in "${!BB@}" "${ENV[@]}" ; do eval echo \"\<br /\>$i\" ; done ; 
  # nota: unfortunatly BBEdit does not set any BB_DOC_NAME or BB_DOC_PATH
  # so we have to 'do it our way -> gsed'
}

DefaultFilter_(Multi-)Markdown.sh

Put these files into your ‘~/Library/ApplicationSupport/BBEdit/Preview Filters’ folder with proper rights.

DefaultFilter_Markdown_transcluded_runOnceOVim.sh

#!/usr/local/bin/bash
cat <(sed -n '4,40p' ~/ev/tex/_template/tex7.md) - /Users/sm/Desktop/t/footnotes.md /Users/sm/Desktop/t/abbrev1.md /Users/sm/Desktop/t/abbrev2.md | tee >(( cat - | multimarkdown -f -t latex ) > ~/ev/dbg/debug.tex ) | multimarkdown

DefaultFilter_Markdown_transcluded_runOnceDbgVim.sh

#!/usr/bin/env LANG=de_DE.UTF-8 COMMAND_MODE=legacy bash 
cat <(sed -n '4,40p' ~/ev/tex/_template/tex7.md) <(gsed -e 's/{{\(TOC.*\)}}/{{\1XXX/' -e 's/^\([ \t]\+\){{\(.*\)}}/\1XXX\2XXX/' -e 's/{{\(.*\)}}/cat "\1"/e' -e 's/XXX\(.*\)}}/{{\1}}/' - ) /Users/sm/Desktop/t/footnotes.md /Users/sm/Desktop/t/abbrev1.md /Users/sm/Desktop/t/abbrev2.md | tee >(( cat - | multimarkdown -f -t latex | gsed \
-e 's/\\bibitem{\(.*\)}/\\bibitem[\1]{\1}/g' \
-e 's/bibitem\[\([a-zA-Z]*\)\([0-9]*\)/bibitem\[\1(\2)/g' \
-e 's/bibitem\[\([a-z]\)/bibitem[\U\1/' \
-e 's/\s🇩🇪\(.\)/{ \\worldflag{DE}\\nolinebreak\1}/g' \
-e 's/\s🇫🇷\(.\)/{ \\worldflag{FR}\\nolinebreak\1}/g' \
-e 's/\s🇯🇵\(.\)/{ \\worldflag{JP}\\nolinebreak\1}/g' \
-e 's/\s🇪🇸\(.\)/{ \\worldflag{ES}\\nolinebreak\1}/g' \
-e 's/\s🇺🇸\(.\)/{ \\worldflag{US}\\nolinebreak\1}/g' \
-e 's/\\begin{lstlisting}\[language=\(.*\)\]/\\begin{minted}{\1}/' -e 's/\\end{lstlisting}/\\end{minted}/' ) > ~/ev/dbg/debug.tex ) | multimarkdown | tee >(cat - > ~/ev/dbg/debug.html) | cat -



# -e "s/\s\([$ris]\)\{2,\}/ \\\\worldflag{\1}/g" \ #funzt ned
# -e 's/newacronym{η}{η/newacronym{η}{$\\eta$/' \  #-> LuaLaTax, lahm, aber UTF-8

Mimick multimarkdown -t (transclude only) while accepting /dev/stdin with gsed’s cat meanwhile writing {tex,html} to nvr --remote (NeoVim remote)

DefaultFilter_ReStructuredText.py

#!/usr/local/Cellar/docutils/0.17.1_1/libexec/bin/python3.9

# $Id: rst2html4.py 7994 2016-12-10 17:41:45Z milde $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.

"""
A minimal front end to the Docutils Publisher, producing (X)HTML.

The output conforms to XHTML 1.0 transitional
and almost to HTML 4.01 transitional (except for closing empty tags).
"""

try:
    import locale
    locale.setlocale(locale.LC_ALL, '')
except:
    pass

from docutils.core import publish_cmdline, default_description


description = ('Generates (X)HTML documents from standalone reStructuredText '
               'sources.  ' + default_description)

publish_cmdline(writer_name='html4', description=description)

debugMMD.sh (Text Filter)

This one is for debugging only selected part of it (~/Library/Application Support/BBEdit/Text Filters) debugging is done in neovim, normal editing in MacVim

#!/usr/bin/env NVIM_LISTEN_ADDRESS=/Users/sm/nvimsocket bash
#==============================================================================
# GNU `debugMMD.sh' does... 
#
# Usage: debugMMD.sh [OPTION] ...
#
# `debugMDD.sh' tests via Text Filter from BBEdit 
#               part of current (even unsaved) file
#
# Options:
#
# Requirements: 
#      bash 5.0.18  gnu sed 4.8
# 
# Report bugs to <norman.heeg@icloud.com>.
# Notes: ---
#       
# Examples:
#   -none
#       
# [Version]
# GNU debugMMD.sh 0.1 
#
# Copyright 2021 Free Software Foundation, Inc.
# This is free software;  see  the  source  for  copying  conditions.
# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
# 
# Written by  Norman R. Heeg (solar-shop24.eu), norman.heeg@icloud.com 
# Ev. Landeskirche / Belm 24.06.2021
#==============================================================================

CMD=()
set -o nounset                        # Treat unset variables as an 
cat - | tee ~/ev/dbg/debug_short.md

# 1  bbedit selection multiline -> create small {html,tex} in ev/dbg
# 2a bbedit selection singeline -> first check `` and eval/expand
# 2b bbedit selection singeline -> second search in nvr server

if [[ "${BB_DOC_SELSTART}" -gt 1 ]] ; then
 if [[ "${BB_DOC_SELEND_LINE}" -ne "${BB_DOC_SELSTART_LINE}" ]] ; then 
   mapfile -t BB_DOC_NAME_head < <(sed -n '1,/^$/p' "${BB_DOC_PATH}") 
   cat <(printf "%s\n" "${BB_DOC_NAME_head[@]}") ~/ev/dbg/debug_short.md | \
   /Users/sm/Library/Application\ Support/BBEdit/Preview\ Filters/DefaultFilter_Markdown_transcluded_runOnceDbgVim.sh > /dev/null
 else
  line="$(cat ~/ev/dbg/debug_short.md | tr -d '\n')"
  if [[ "${line}" == *'`'* ]] ; then
    echo -e "\n\n"
    eval "${line//\`/}"
    echo -e "\n\n"
  else
      nvr --remote-send "<ESC>/"\
          "$(cat ~/Documents/evlka/dbg/debug_short.md)"\
          "<cr>zz" -remote-expr "set hlsearch" 
  fi
 fi
fi

Upgrade MMD for being compliant with Latex *.bib and \bibitem{...} Format and transclude files on-the-fly

Paracol

shell2bbinclude_cmd.sh

#!/usr/bin/env LANG=de_DE.UTF-8 COMMAND_MODE=legacy bash

fbuffer=()
fbuffer+=( "<!-- #bbinclude" )
fbuffer+=( '"/Users/sm/Documents/evlka/tex/xmp/tex17/shell2bbinclude_wrapper.sh"' )
fbuffer+=( "$@" )
ebuffer=()
ebuffer+=( "-->" )
ebuffer+=( "<!-- end bbinclude -->")
printf "%s " "${fbuffer[@]:0:2}"
for (( j=2 ; j<"${#fbuffer[@]}" ; j++ )) ; do
    let "k=$j+63"
    printf -v val %o "$k"; printf "#\\$val#="
    echo -n "\"${fbuffer[$j]}\" "
done
printf "%s\n" "${ebuffer[@]}"

This command should be executable and within your $PATH environment which is exported from BBEdit and which is different to what you might expect when opening a shell, I had to setenv LANG=de_DE.UTF-8 COMMAND_MODE=legacy again to make it work.

shell2bbinclude_wrapper.sh

#!/usr/bin/env LANG=de_DE.UTF-8 COMMAND_MODE=legacy bash
DBG=0;j=-1;args=()
for i in $(seq 3 2 "${#@}") ; do
  let "j++";args+=( "${!i}" )
done
set "${args[@]}"  
[[ $DBG > 0 ]] && { printf "\n<br />%s" "<b>$0</b>" "$@" >> ~/ev/dbg/debug.html ; }
cmd="${args[*]}"
[[ $DBG > 1 ]] && { echo -e "\n<br />cmd=${cmd}" >> ~/ev/dbg/debug.html ; }
eval "${cmd}" ; echo $?;

paracoln.sh

#!/usr/bin/env LANG=de_DE.UTF-8 COMMAND_MODE=legacy bash
#fill buffer
buffer=
buffer+=( "$(printf "%s " "Aufruf mit '" $0 "$@" "'" )" )
#printf "%s\n" "${buffer[@]}"
#ANZAHLCOL=$(( "${#ARG1}" - 1 ))
ARG1=$1;shift;ANZAHLCOL=$ARG1
ARG2=$1;shift;
#ARG2='leer'
PutFlags=1
DBG=2
HTMLTEXTALIGN='text-align:justify;'

#flag to html
function iso2ris () { 
local new='🇦🇧🇨🇩🇪🇫🇬🇭🇮🇯🇰🇱🇲🇳🇴🇵🇶🇷🇸🇹🇺🇻🇼🇽🇾🇿'
local klein=abcdefghijklmnopqrstuvwxyz
local gross=ABCDEFGHIJKLMNOPQRSTUVWXYZ
local arr=(); arr=( "$@" ); echo "${arr[@]}"  | gsed -e "y/$klein/$new/" -e "y/$gross/$new/" ;
}

#here goes the DEFS...
#...init flag for LaTeX
mapfile -t LANGFLAGARR < <(printf "%s\n" "$@" | gsed \
    -e 's/.*\/\(.*\)\.md$/\1/' -e 's/..\(..\).*/\U\1/'\
    -e 's/EN/GB/')
#...init flag for HTML
LANGFLAGARRHTML=( $(iso2ris "${LANGFLAGARR[@]}") )
[[ $DBG = 1 ]] && { for ((j=0 ; j<"${#LANGFLAGARRHTML[@]}" ; j++)) do
echo LANGFLAGARRHTML $j ${LANGFLAGARRHTML[$j]} ; done ; } 

#...for cols LaTeX
COL0='\`\\switchcolumn[0]\\selectlanguage{\3}\`{=latex}' 
COLX='\`\\switchcolumn[\1]\\selectlanguage{\3}\`{=latex}' 
#...for cols HTML
COL0=${COL0}' \`<\/td><\/tr><tr><td lang=\2 style="'${HTMLTEXTALIGN}'vertical-align:top">\`{=html}';
COLX=${COLX}' \`<\/td><td lang=\2 style="'${HTMLTEXTALIGN}'vertical-align:top">\`{=html}'
#...for 0 and all other column
FINAL0='COL=\(0\) LANG=\(.*\) LATLANG=\(.*\) HEAD=\(.*\)$' # col0 sep because sync and <tr>
FINALX='COL=\(.\) LANG=\(.*\) LATLANG=\(.*\) HEAD=\(.*\)$' # all other X cols
#...for HTML attributes
TABLEATT='BORDER=0'

#regex MID
for ((i = 0 ; i <= ${#ARG2} ; i++)); do regexarr+=( "-e s/COL=$i/COL=${ARG2:$i:1}/" ) ; done 

#regex FIN
regexarr+=("-e s/_/ /g"
 "-e s/${FINAL0}/${COL0}/"
 "-e s/${FINALX}/${COLX}/"
) ; [[ $DBG = 2 ]] && { echo ;  }

#check error ARGS
for i in {1..2}
do
  if [[ -z $(eval echo "\$ARG$i")  ]] ; then
    echo -n "usage: '$0' [0-9]{cols} [001]{order} for \switchcolumn[x]" 
    echo    "filetuplets[1,2 3,4 etc] "
    echo    "examp: $0 2 001 {1,2}*a.txt {1,2}*b.txt"
    echo    "* Beginning fo fileTuplets must be Integer{a,b}*"
    echo    "failed ARG[i]=$i=" $(eval echo "$\$ARG$i")
    exit 1;
  fi
done

#get the LaTeX Section header from first filename
HEADER=$( echo "$1" | gsed -e 's/.*\/....-.*-\(.*\)\.md$/\1/' -e 's/_/ /g' -e 's/[0-9]$//' )
HEADERLABEL="${HEADER,,}";HEADERLABEL="${HEADERLABEL// }"

#get the last 3 digit from filename & check for numbers=cols2sync
sync1=$( echo "$1" | gsed -e 's/.*\/....-.*-\(.*\)\.md$/\1/' -e 's/_/ /g' \
    -e 's/.*\(....\)$/\1/'\
    -e 's/[^0-9]//g'
)
sync2=()
for i in {1..3} ; do [[ "${sync1}" == *"$i"* ]] && \
    { sync2["$i"1]='-e s/\[0\]/\[0\]*/' ; } ; done


# write information about each tuple file has same count of rows
# should ALWAYS contain 21 or 31 or 41 etc rows
mapfile -t result < <( wc -l $@   ) ; buffer+=( "${result[@]}" )
echo "<!--- BEGIN '$0' "$(mydate) " -->"
echo "\`\begin{paracol}{$ANZAHLCOL}[\section{$HEADER}\label{sec:$HEADERLABEL}]" \
     "\hbadness5000\`{=latex}"\
     "\`<div align=\"center\"><table $TABLEATT><tr><td></td><td>\`{=html}"
for i in {1..31..10}
  do
      if [[ -z "${sync2[$i]}" ]] ; then 
          regexarrtem=( "${regexarr[@]}")
      else
          regexarrtem=( "${regexarr[@]}" "${sync2[$i]}" )
      fi

      if [[ $i == 1 && $PutFlags == 1 ]] ; then
        for (( j=0 ; j<"${#LANGFLAGARR[@]}" ; j++ )) ; do
          regexarrtem+=( \
"-e s/\\\\switchcolumn\\[$j\\]/\\\\switchcolumn\\[$j\\]\\\\worldflag{${LANGFLAGARR[$j]}}/"
          #"-e s/lang\=\(fr\) style\=\\\"vertical-align:top\\\">/style\=\\\"vertical-align:top\\\">\1"${LANGFLAGARRHTML["$j"]}"/"
"-e s/\\\\switchcolumn\\[$j\\]\(.*\)cal-align:top\\\">/\\\\switchcolumn\\[$j\\]\1cal-align:top\\\">"${LANGFLAGARRHTML["$j"]}"/"
)
          #printf "<!-- %s -->\n" "${regexarrtem[@]}"
        done
      fi

    gsed -s  '{1F; '$i',+9!d } ' "$@" | \
      gsed \
           -e 's/.*\/\(.*\).md/\1/' \
           -e 's/\(.*\)\.md/\1/' \
           -e 's/^\([0-9]\)\(.*\)\.md$/\1/' \
           -e 's/^\([0-9]\).\(..\)-\(.*\)-\(.*\)$/COL=\1 LANG=\2 LATLANG=\3 HEAD=\4/'\
           "${regexarrtem[@]}"

  done

printf "<!--- %s -->\n" "$(echo -n "END '$0' " ; mydate)" \
       "${buffer[@]//   /}" \
       "$(gsed -n -e '/^# /p' "$0" | tr -d $'\n')" \
       "regexarr=${regexarr[@]}"\
       'multimarkdown syntax obligatory'\
       'https://fletcher.github.io/MultiMarkdown-6/MMD_Users_Guide.html' \
       'inspired from "gsed --seperate" (4.8) & "ctan.org/pkg/paracol"' \
       '© Norman Heeg Kirchenkreis Belm 2021'\
       "HEADER = '${HEADER}'"\
       "sync1 = '${sync1}'"\
       "sync2[{11..31..10}] = '${sync2[11]}' '${sync2[21]}' '${sync2[31]}'"\
       "LANGFLAGARR=${LANGFLAGARR[@]}"\
       "$(date)"

echo "\`\end{paracol}\`{=latex} \`</tr></table></div>\`{=html}"

Generates md multi-column files for HTML and LaTeX

paracol-index.sh

#!/usr/bin/env LANG=de_DE.UTF-8 COMMAND_MODE=legacy bash
DBG=0;CMD="~/Documents/evlka/tex/xmp/tex17/paracoln.sh"
OUT=o
FILESSECONDPOSSIBLECHAR=( a )
#echo {1..3},{1..3} | sed -E -n '/(.),\1$'
# first get all the files {0..9} in dir
function echos(){ while (( $# )); do eval echo -n \"$1\"=\\\'\"\$$1\"\\\'\'';'\' ; shift ; done ; }
[[ "${1:(-1):1}" == '/' ]] && { file="$1"* ; } || { file="$1" ; }
fileh="$( cd -- "$(dirname "$file")" >/dev/null 2>&1 ; pwd -P )";filet="$(basename "$file")";filett="${filet%%.*}";echo "$file" ;#cd "$fileh";
[[ $DBG = 1 ]] && { fi_=( file fileh filet filett ) ; echos "${fi_[@]}" ; exit ;  }
#ls "${fileh}"/{0..9}*.txt 2>/dev/null ;# exit ; 
myfil=();
for i in $(ls "${fileh}"/{0..9}*.md 2>/dev/null) ; 
do 
    file="$i";fileh="$( cd -- "$(dirname "$file")" >/dev/null 2>&1 ; pwd -P )";filet="$(basename "$file")";filett="${filet%%.*}";#echo "$file" ;#cd "$fileh";
    myfil+=( "${filet:0:1}" )
    [[ $DBG = 2 ]] && { echo $filet $i ; }
done
myfilneu=(); mapfile -t myfilneu < <(printf "%s\n" "${myfil[@]}" | sort -u) ; 
[[ $DBG = 3 ]] && { echo "myfilneu"; printf "%s\n" "${myfilneu[@]}" ; }

myfilneuneu=()
for ((i=0 ; i < "${#myfilneu[@]}" ; i++ )) ; do 
    for ((j=0 ; j < "${#myfilneu[@]}" ; j++ )) ; do 
        if [[ $i -ne $j ]] ; then
            myfilneuneu+=( "${myfilneu[$i]},${myfilneu[$j]}" ) 
        fi
    done
done ; [[ $DBG = 4 ]] && { printf "%s\n" "${myfilneuneu[@]}" ; }

CMDARR=()
for i in "${myfilneuneu[@]}" ; do 
    tem=
    for j in "${FILESSECONDPOSSIBLECHAR[@]}" ; do
    tem=$tem" ${fileh}/{${i}}${j}*.md"
    done
    CMDARR+=( "$CMD 001 ${tem} > $fileh/$OUT${i//,/}.md" ); 
done

#printf "%s\n" "${CMDARR[@]}"
#eval "${CMDARR[@]}"

[[ $DBG > 0 ]] && { 
    printf "%s\n" "${CMDARR[@]}" ; 
} || { 
    for i in "${CMDARR[@]}" ; 
    do 
        echo "$i"
        eval "$i"
    done
}

Generates all possible variants of x-column width balanced and synced languages.

Perl

Get the csv from Google Spreadsheets

#!/usr/bin/env bash -

#wget -qO - --output-file="logs.csv" 'https://docs.google.com/spreadsheets/d/1pmTFh42bDu44J94haF8E203welNm3q_d6a2oSQhNPT4/export?format=csv&gid=1988854650' | gzip -d > smu.csv #testdata
wget -qO - --output-file="logs.csv" 'https://docs.google.com/spreadsheets/d/1pmTFh42bDu44J94haF8E203welNm3q_d6a2oSQhNPT4/export?format=csv&gid=426476982' | gzip -d > smu.csv #realdata
wget -qO - --output-file="logs.csv" 'https://docs.google.com/spreadsheets/d/1pmTFh42bDu44J94haF8E203welNm3q_d6a2oSQhNPT4/export?format=csv&gid=1282139860' | gzip -d > abbrev0.csv #abbrev0.csv


#wget -qO - --output-file="logs.csv" 'https://docs.google.com/spreadsheets/d/1pmTFh42bDu44J94haF8E203welNm3q_d6a2oSQhNPT4/export?format=csv&gid=1696415670' | gzip -d | sed -e 's/"//g' > /Users/sm/Documents/evlka/tex/xmp/tex8/GeneralAcro.csv 
wget -qO - --output-file="logs.csv" 'https://docs.google.com/spreadsheets/d/1pmTFh42bDu44J94haF8E203welNm3q_d6a2oSQhNPT4/export?format=csv&gid=1696415670' | gzip -d > /Users/sm/Documents/evlka/tex/xmp/tex8/GeneralAcro.csv 

Writing files for biblatex (or better bib2gls46), vim, BBEdit and Multimarkdown at once together with next executable.

smu3-bib.pl

#!/usr/bin/env perl 
#!/usr/local/bin/perl -CSDL oder CSDA
# https://www.perl.com/pub/2012/05/perlunicook-make-all-io-default-to-utf-8.html/
# orignally form
# https://github.com/kristiannordestgaard/smubib/
#TYPE,KEY,TITLE,AUTHOR,YEAR,PUBLISHER,PAGES,NUMBER
#article,nordestgaard2016,BibTeX is cool,"Nordestgaard, Kristian",2016,Unknown,1--10,1
#book,johnson2016,Better BibTex,"Johnson, Steve",2016,Foobar,,
#report,irena2019a,Innovation landscape brief: Behind-the-meter batteries,,2019,"International Renewable Energy Agency, Abu Dhabi",,
#
###############################################################################################
# sjohnson from Freenode originally gave a proof of concept for this project written in Perl. #
# This work is released under the MIT License: https://opensource.org/licenses/MIT            #
###############################################################################################


use strict;
use warnings;
use utf8;
#use 5.010;

BEGIN { $ENV{PERL_TEXT_CSV}='Text::CSV_PP'; }
my @myheaders = qw( Short Long GlossShort );
my $fileAbbrevOne="/Users/sm/Desktop/t/abbrev1.md";
my $fileAbbrevVim="/Users/sm/.vim/spell/myabbreviations1.vim";
my $fileAbbrevTwo="/Users/sm/Desktop/t/abbrev2.md";
my $direAbbrevBBE="/Users/sm/Library/Application Support/BBEdit/Clippings/";
my $fileDebugLogg="/Users/sm/Documents/evlka/dbg/debug.log";
my $fileVimThesau="/Users/sm/Documents/evlka/vim/thesaurus/";
use File::Basename;
use Text::CSV;

my %umlaute = ("ä" => "ae", "Ä" => "Ae", "ü" => "ue", "Ü" => "Ue", "ö" => "oe", "Ö" => "Oe",
"é" => "e", "è" => "e", "ê" => "e", "ë" => "e", "Ë" => "E", "É" => "E", "È" => "E", "Ê" => "E", 
"à" => "a", "À" => "A", "â" => "a", "Â" => "A",
"û" => "u", "Û" => "U", "ô" => "o", "Ô" => "o", "î" => "i", "Î" => "I", "ç" => "c", "Ç" => "C",
"ß" => "ss", " " => "_", 
"🇦" => "A","🇧" => "B","🇨" => "C","🇩" => "D","🇪" => "E","🇫" => "F","🇬" => "G","🇭" => "H",
"🇮" => "I","🇯" => "J","🇰" => "K","🇱" => "L","🇲" => "M","🇳" => "N","🇴" => "O","🇵" => "P",
"🇶" => "Q","🇷" => "R","🇸" => "S","🇹" => "T","🇺" => "U","🇻" => "V","🇼" => "W","🇽" => "X",
"🇾" => "Y","🇿" => "Z"
);

my $umlautkeys = join ("|", keys(%umlaute));
# ---

my ( $myproject, $file_csv ) = @ARGV ;
if ( (not defined $myproject) || (not defined $file_csv ) || (not -r $file_csv)  ){
    print usage(); exit(1);
}
# ---

$fileVimThesau.="$myproject-subs.txt";

my $csv = Text::CSV->new({ binary => 1, auto_diag => 1, diag_verbose => 1 }) or die "Cannot use CSV: " . Text::CSV->error_diag();
open(my $fh_csv, '<:encoding(UTF-8)', $file_csv) or die "$file_csv $!";
open(my $fh_One, '>:encoding(UTF-8)', $fileAbbrevOne) or die "$fileAbbrevOne $!";
open(my $fh_Two, '>:encoding(UTF-8)', $fileAbbrevTwo) or die "$fileAbbrevTwo $!";
open(my $fh_Vim, '>:encoding(UTF-8)', $fileAbbrevVim) or die "$fileAbbrevVim $!";
open(my $fh_Dbg, '>:encoding(UTF-8)', $fileDebugLogg) or die "$fileDebugLogg $!";

my @headers;
my @row_refs;
my @wanted = qw/Short LongTE GlossShortEingabe GlossLong/;
my %row_hash = qw(  Short Defs
                    LongTE Defl
                    GlossShortEingabe Defgs
                    GlossLong Defgl);
my @clippings = qw/n a g f/;

# collect data
while (my $row = $csv->getline($fh_csv)) {
  if ($. == 1) {
    # populate headers, first row only
    my $count_header_field = 0;
    foreach my $piece (@$row) {
      $headers[$count_header_field++] = $piece;
    }
    # done collecting headers
    next;
  }
  push(@row_refs, $row);
}

$csv->eof or $csv->error_diag();
close($fh_csv);

print $fh_Vim 'set isk+=46';
#my @args = ("rm", "'/Users/sm/Library/Application Support/BBEdit/Clippings/'*.*") ;
#my $return = sytem("rm '/Users/sm/Library/Application Support/BBEdit/Clippings/'*.*") ;
#system(@args) == 0 or die "system @args failed: $?";
my $exit_status ='';
#$exit_status = sytem("rm '/Users/sm/Library/Application Support/BBEdit/Clippings/'*.*") ;
#if ( not $exit_status & 0 ) { print "% Error rm $exit_status\n"; }
# output the data to bibtex
foreach my $row_ref (@row_refs) {
  my $c = -1;
  my $i = "\nnoreabbrev";

  foreach my $field (@$row_ref) {
    trim($field);

    ++$c;
    if ($c == 0) {
      print '@' . $field . '{';
    } elsif ($c == 1) {
      print $field . ",\n"
    } elsif (length($field)) {
        if ($field =~ /\\$/) {
          print "$headers[$c] = {$field },\n"
        } else {
          print "$headers[$c] = {$field},\n"
        }
      $row_hash{$headers[$c]} = $field if /$headers[$c]/i ~~ @wanted; 
      #print $fh_Vim "\n\n" . $row_hash{$headers[$c]} . ' = ' . $field if /$headers[$c]/i ~~ @wanted; 
    }
  }
  #foreach my $fields (@wanted) {
      #print $fh_Vim "\nNEU $fields = $row_hash{$fields} \nENDNEU\n";
  #}
  print $fh_Vim '' . # macvim 
  "$i $row_hash{'Short'}.n $row_hash{'LongTE'}" .
  "$i $row_hash{'Short'}.a \[>$row_hash{'Short'}\]"  .
  "$i $row_hash{'Short'}.g \[?$row_hash{'LongTE'}\]" .
  "$i $row_hash{'Short'}.f \[>$row_hash{'Short'}\]\[^s.a. Glossar [?$row_hash{'LongTE'}]: $row_hash{'GlossShortEingabe'}\]";

  foreach my $j (@clippings) { #bbedit
      open my $fh_BBE, ">", "$direAbbrevBBE$row_hash{'Short'}.$j" or die "Could not write to '$direAbbrevBBE$row_hash{'Short'}.$j': $!";
      print $fh_BBE "$row_hash{'LongTE'}" if ($j eq 'n');
      print $fh_BBE "\[>$row_hash{'Short'}\]" if ($j eq 'a');
      print $fh_BBE "\[?$row_hash{'LongTE'}\]" if ($j eq 'g');
      print $fh_BBE "\[>$row_hash{'Short'}\]\[^s.a. Glossar \[?$row_hash{'LongTE'}\]: $row_hash{'GlossShortEingabe'}\]" if ($j eq 'f');
      close $fh_BBE or die "Could not close '$fh_BBE': $!";
      }
  print $fh_One "\n\[>" . $row_hash{Short} . "\]: " . " " x (13 - length($row_hash{Short})) . $row_hash{LongTE} . "\n";
  print $fh_Two "\n\[?$row_hash{'LongTE'}\]: " . " " x (50 - length($row_hash{'LongTE'})) . "$row_hash{'GlossLong'}\n";
  print "}\n\n";

  # now manipulate ~/mysynonyms.txt to get rid off 'IETE' special ISO and UTF8 chars.
  # can be accessed only by vim  t view h: thesaurus
  #my $chars  = decode('utf8',$row_hash{'Short'},1);
  my $chars = $row_hash{'Short'};
  my $cleanedchars = $chars;
  $cleanedchars =~ s/($umlautkeys)/$umlaute{$1}/g;
  #$cleanedchars = encode('iso-8859-1',"$chars",Encode::FB_QUIET);
  #my $cmd = '~/ev/perl/configLine.sh ^' . "$cleanedchars '$cleanedchars $chars.a $chars.f $chars.g $chars.n'" . ' ~/mysynonyms.txt' ;
  my $cmd = '~/ev/perl/configLine.sh ^' . "$cleanedchars '$cleanedchars $chars.a $chars.f $chars.g $chars.n' $fileVimThesau" ;
  print $fh_Dbg "% $cmd \n" ;
  $exit_status = system($cmd);
  #$exit_status = `"$cmd"`;
  if (not $exit_status == 0) { print $fh_Dbg "% Could not configLine.sh \"$cleanedchars $chars {a.n.f.g}\": $exit_status\n"  };
  # ---

}

close $fh_One or die "Could not close '$fh_One': $!";
close $fh_Two or die "Could not close '$fh_Two': $!";
close $fh_Vim or die "Could not close '$fh_Vim': $!";
close $fh_Dbg or die "Could not close '$fh_Dbg': $!";


sub trim { $_[0] =~ s{^\s+|\s+$}{}g; }

sub usage {
  my $buffer;

  $buffer .= "Purpose: To translate basic Google-formatted spreadsheets saved as .csv to BibTeX ...\n\n";
  $buffer .= "Usage: " . basename($0) . " (-h|--help) [myproject] [file.csv] > [file.bib]\n";

  return $buffer;
}
#

Goto ~/ev/tex/glon/ and type in terminal

./smu1-gd2csv.sh && ./smu3-bib.pl ffew ~/ev/tex/xmp/tex8/GeneralAcro.csv > smu.bib

CSS

img{
    width:100%;
    max-width:600px;
}
hr {
    visibility: hidden;
}
div.footnotes::before {
    content: "Fußnoten:";
    float: left;
    width: 100%;
    font-weight: bold;
    font-size: 120%;
}
div.glossary::before {
    content: "Glossar:";
    margin-bottom: 3em;
    font-weight: bold;
    font-size: 120%;
}
div.citations::before {
    content: "Quellen:";
    font-weight: bold;
    font-size: 120%;
}

Resize images

@import "/Preview CSS/image-size-information-information.css";

a { color: #222222; }
a:visited { color: #222222; }
a:hover {
  color: #ffffff;
  background: #222222;
}
pre {
  border: #777777 1px solid;
  background-color: #cccccc;
}
pre .poetry {
  border: none;
  background: none;
}
img {
  border: #777777 1px solid;
  background-color: #cccccc;
  color: black;
}
figcaption {
  display: block;
  text-align: center;
}
body {
  font: 14px/1.5em Georgia, Palatino, "Palatino Linotype", Times, "Times New Roman";
  margin: 0;
  padding: 0;
  font-size: 1em;
  width: 35em;
  margin: auto;
}
div, h1, h2, h3, h4, h5, h6 { text-align: left; }
div.wrapper {
  font-size: 1em;
  max-width: 47em;
  min-width: 580px;
  margin: auto;
}
pre { padding: 0.5em; }
img {
  display: block;
  margin-left: auto;
  margin-right: auto;
  width: 75%;
}
body { font: 14px/1.5em Georgia, Palatino, "Palatino Linotype", Times, "Times New Roman"; }
p {
  font-size: 1em;
  line-height: 1.5em;
  text-align: justify;
  margin: 1.5em 0 1.5em 0;
  max-width: 35em;
}
li p { margin: 1em 0 1em 0; }
h1, h2, h3, h4 {
  font-family: Arial, Helvetica, "Trebuchet MS", Verdana, sans-serif;
  font-weight: normal;
}
h1 {
  font-size: 1.286em;
  line-height: 0.857em;
  margin: 1.75em 0 0.583em 0;
}
h2 {
  font-size: 1.143em;
  line-height: 1.313em;
  margin: 1.969em 0 0.656em 0;
}
h3, h4 {
  font-size: 1em;
  line-height: 1.5em;
  margin: 2.25em 0 0.75em 0;
}
code {
  font-family: courier;
  font-size: 0.857em;
  line-height: 1.75em;
}
pre {
  font-family: courier;
  font-size: 0.857em;
  line-height: 1.75em;
  margin: 0 0 1.75em 0;
  white-space: pre-wrap;
  white-space: moz-pre-wrap !important;
  white-space: -pre-wrap;
  white-space: -o-pre-wrap;
  word-wrap: break-word;
}
div.bibliography p { text-align: left; }
a {
  text-decoration: none;
  font-weight: bold;
}
.sidebar { padding-top: 3em; }
.sidebar > h1 { margin-top: 0; }
.sidebar h3:first-child { margin-top: 0; }
.sidebar ul {
  margin-left: 0;
  padding-left: 0;
  list-style: none;
}
.sidebar ul ul { margin-left: 15px; }
.sidebar img {
  margin: 0;
  padding: 0;
  border: none;
}
.sidebar a { font-weight: normal; }
.content { padding-top: 3em; }
.content > h1 { margin-top: 0; }
.content h3:first-child { margin-top: 0; }
.content h1:first-child {
  font-size: 1.75em;
  margin-bottom: 1em;
}
.content img {
  padding: 0.5em;
  margin-left: 1em;
  margin-right: 2em;
  max-width: 32em;
}
.content pre { padding: 0.5em; }
.content hr {
  height: 1px;
  color: black;
  background-color: black;
  border: 0;
}
.content a { border-bottom: 1px dashed #888888; }
.tags, .date {
  font-family: Arial, Helvetica, "Trebuchet MS", Verdana, sans-serif;
  font-weight: bold;
  font-size: 0.75em;
}
.comments { margin-top: 5em; }
.comments .comment {
  margin-bottom: 0.5em;
  border-bottom: 1px solid #cccccc;
  padding-bottom: 0.5em;
}
.comments .comment-byline { font-size: 0.75em; }
.comments .comment-byline a { border: none; }
div.header {
  background-image: none;
  border-style: none;
  border-bottom: 1px solid black;
}
span.logo {
  position: absolute;
  top: 10px;
  right: 10px;
  font-family: Didot, AppleMyungjo, Palatino, Times;
  font-size: 32px;
  color: black;
  padding: 10px;
  margin-bottom: 10px;
}
span.tail { color: #888888; }
span.logo > a > img {
  border: none;
  background-color: #ffffff;
  padding: 0px;
  margin: 0px;
}
table {
  /*border: solid black;*/
  border: solid lightgrey;
  border-width: 2px 0px;
  empty-cells: hide;
  border-spacing: 0px;
  padding: 2px;
  margin: 20px auto;
}
table caption {
  margin: 5px;
  text-align: center;
  caption-side: bottom;
}
thead th {
  border: solid gray;
  border-width: 0 0 2px 0;
  padding: 5px;
}
thead > tr:last-child > th { border-style: none; }
tbody > tr:first-child > td {
  border: solid gray;
  border-width: 1px 0 0 0;
}
tbody > tr:first-child > th {
  border: solid gray;
  border-width: 1px 0 0 0;
}
thead + tbody > tr:first-child > td {
  border: solid black;
  border-width: 1px 0 0 0;
}
thead + tbody > tr:first-child > th {
  border: solid black;
  border-width: 1px 0 0 0;
}
td {
  -webkit-hyphens: auto;
  -moz-hyphens: auto;
  -ms-hyphens: auto;
  hyphens: auto;
  border-spacing: 3em;
  border-left: 1px solid lightgrey;
  border-right: 1px solid lightgrey;
}
table td:first-child {
    border-left: none;
    padding-right: 1em;
}
table td:last-child {
    border-right: none;
    padding-left: 1em;
}
figure {
  padding: 0px;
  margin: 0px;
}

strong>em,
em>strong,
b>i,
i>b {
    font-style:normal;
    font-weight:normal;
    text-decoration:underline;
}
 

Get rid of <hr> tags from MMD and convert them to the proper items, also construct an underline mimicking (underlined)47 for html and bold italic in other renderings.

BASH

.bashrc (informational)

Only informationally

# System-wide .bashrc file for interactive bash(1) shells.
# /private/etc/bashrc von urmel 09.08.19, 22:35
eval "$(gsed -n '2p' /Volumes/MacintoshHD/Users/sm/Downloads/pdf/schmierordner/ww2/cgi/mmd2web)"
mapfile -t energiewende < <(cat /Users/sm/Documents/evlka/tex/xmp/tex17/fn/energiewende.txt) ; export energiewende ;
export VIMINIT="source ~/.vim/vimrc"
export LC_TIME=de_DE
export PATH="/usr/local/Cellar/python@3.9/3.9.5/Frameworks/Python.framework/Versions/3.9/bin:$PATH"
export PATH="/Users/sm/Library/Frameworks/Python.framework/Versions/3.10/bin:$PATH"

export PERL_UNICODE=SDA

[[ $TERM_PROGRAM == *"iTerm.app"* ]] && { export GREP_OPTIONS='--color=always' ; export GREP_COLOR='1;35;40' ; }

if [ -z "$PS1" ]; then
   return
fi

export NVIM_LISTEN_ADDRESS="/Users/sm/nvimsocket"

export PATH="$PATH:$(brew --prefix)/opt/coreutils/libexec/gnubin"
#[ -f ~/.fzf.bash ] && source ~/.fzf.bash

eval "$(pyenv init -)"

if type brew &>/dev/null; then
  HOMEBREW_PREFIX="$(brew --prefix)"
  if [[ -r "${HOMEBREW_PREFIX}/etc/profile.d/bash_completion.sh" ]]; then
    source "${HOMEBREW_PREFIX}/etc/profile.d/bash_completion.sh"
  else
    for COMPLETION in "${HOMEBREW_PREFIX}/etc/bash_completion.d/"*; do
      [[ -r "$COMPLETION" ]] && source "$COMPLETION"
    done
  fi
fi

export EDITOR=vim
export VISUAL="$EDITOR"

host='solarmoves-mac-mini.local'; export host
Base_URL=/ww2; export Base_URL

if [ -r ~/.bc ]; then export BC_ENV_ARGS=~/.bc ; fi

alias dlng0="declare -a lng0=( en fr sk nl bg el es sl uk hu pl de it ru no pt hr ca fi sv cs da ro sr lt lv et tr )"

alias dlang="declare -a lang0=( en-gb fr-fr sk-sk nl-nl bg-bg el-gr es-es sl-SI uk-ua hu-hu pl-pl de-de it-it ru-ru no-no pt-pr hr-hr ca-es fi-fi sv-se cs-cz da-da ro-ro sr-RS lt-lt lv-lv et-ee tr-tr )"

alias dlng="declare -a lng=( "" en fr sk nl bg el es sl uk hu pl de it ru no pt hr ca fi sv cs da ro sr lt lv et tr ); export lng"
alias dlat="declare -a lat=( "" english french slovak dutch bulgarian greek spanish slovene ukrainian hungarian polish ngerman italian russian norsk portuguese croatian catalan finnish swedish czech danish romanian serbian lithuanian latvian estonian turkish ); export lat"  
alias dlan="declare -a languages=( "" en-gb fr-fr sk-sk nl-nl bg-bg el-gr es-es sl-SI uk-ua hu-hu pl-pl de-de it-it ru-ru no-no pt-pr hr-hr ca-es fi-fi sv-se cs-cz da-da ro-ro sr-RS lt-lt lv-lv et-ee tr-tr )"

alias bashman='open /usr/share/doc/bash/bashbug.pdf ; open /usr/share/doc/bash/bashref.pdf ; open /usr/share/doc/bash/builtins.pdf ; open /usr/share/doc/bash/rbash.pdf ; open ; open /usr/share/doc/bash/article.pdf ; open /usr/share/doc/bash/rose94.pdf'

schmd1=/Volumes/macOS10135HDD;export schmd1;
schmd2=/Library/WebServer/Documents/oc;export schmd2;
homedir=/Volumes/macOS10135HDD/Users/${USER:0:2};export homedir;
workdir=/Volumes/BCKHD/schmier/${USER:0:2};export workdir;
logdir=/Volumes/BCKHD/schmier;export logdir;

alias schmier='cd /Volumes/MacintoshHD/Users/sm/Downloads/pdf/schmierordner/'
alias schmierd='/Volumes/MacintoshHD/Users/sm/Downloads/pdf/schmierordner/'
alias ella2='cd /Volumes/MacintoshHD/Users/sm/Downloads/pdf/schmierordner/ella2'
alias ella1='cd /Volumes/Macintosh\ HD/Users/ella'

PS=1'\s-\!\$ '
PS1='\h:\W \u\!# '
PS=1'\s-\!\$ '
# make shorter
PS1='\W \!# '
# Make bash check its window size after a process completes
shopt -s checkwinsize

[ -r "/etc/bashrc_$TERM_PROGRAM" ] && . "/etc/bashrc_$TERM_PROGRAM"

vimm () {
 file=`echo "${1%}" | perl -F: -wane 'print $F[0]'`
 line=`echo "${1%}" | perl -F: -wane 'print $F[1]'`
 line=`expr $line - 1`
 echo vim \""+${line} normal "\" $file 
 vim "+${line} normal" $file 
}


alias   ocl='cd /Library/WebServer/Documents/oc/catalog/language'
alias    oc='cd /Library/WebServer/Documents/oc'
alias    ca='cd /Volumes/BCKSSD/DoNotDelete/cache/'
alias  schm='cd /Volumes/BCKHD/schmier'

alias   web='cd /Library/WebServer/Documents'

alias  tree="find . -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'"
alias tails="tail -n 30"


wtf(){
n0=$(whoami)
n1=$(uname -a | cut -f2 -d ' ')
n3=$(tty)
echo -n -e I am \'${n0}\' on \'${n1}\' with Shell-Version \'$BASH_VERSION\' in \'${n3}\'
if [ $# -gt 0 ] ; then
 n2=`echo "set  :" $(set | grep ${1})` # output is too long
 n2=''
 n3=`echo "env  :" $(env | grep ${1})`
 n4=`echo "shopt:" $(shopt | grep ${1})`
 n5=`echo "bind :" $(bind -p | grep ${1})`
 set "$n2" "$n3" "$n4" "$n5";
 for line in "$@"; do echo "${line}"; done
fi
}

export HISTSIZE=10000
export HISTFILESIZE=$HISTSIZE
export HISTIGNORE="&:[ ]*:exit"
export HISTCONTROL=ignorespace:ignoredups
#export HISTCONTROL=ignoreboth
shopt -s histappend
shopt -s histreedit
shopt -s histverify
shopt -s expand_aliases
#shopt -s globstar
stty discard undef
stty -ixon
alias ..="cd .."
alias la="ls -la"

function echos(){ while (( $# )); do eval echo -n \"$1\"=\\\'\"\$$1\"\\\'\'';'\' ; shift ; done ; } # from ~/.hhh/printff #FEB_SEP=',' ; FEB_SEP1=';' #echos "${!FEB_SEP@}" ; exit ; 
function repeat() { printf -- "$1"'%.s' $(eval "echo {1.."$(($2))"}"); }
function join_by1() { local IFS=$1; shift; echo "$*" | sed 's/$IFS/$IFS/g'; }
function join_byDollar() { usage $1; echo "$*" | tr " " "\n" | sed -e 's/^/\"$/' -e 's/$/\"/' | tr '\n' ' '; }
function join_byX() { echo "$*" | tr " " "\n" | sed -e 's/^/\"$/' -e 's/'$1'/\"/' | tr '\n' ' '; }
#function echosF() { eval echo -e "${!Fi_@}" \" \\\n \"$(join_byDollar "${!Fi_@}") ; }
function echosF() { echos $(echo joined_byDollar "${Fi_[@]}") ; }

g () { 
 grep "$@"
 }
_bash_history_sync () {
 builtin history -a
 HISTFILESIZE=$HISTSIZE
 builtin history -c
 builtin history -r
}
history () {
 #_bash_history_sync
 builtin history "$@"
}
PROMPT_COMMAND=_bash_history_sync
ho () {
 history "$@"
}
hmv () {
if [[ $# -eq 0 ]] ; then echo "hmv" sed-cmd-n-for-lines-only-one-line! perl-line-number-to-move-bash_history; exit; fi
#sed -n -e "${1}p" ~/.bash_history
lines_content_from=$(sed -n -e ${1}p ~/.bash_history)
lines_content_to=$(sed -n -e ${2}p ~/.bash_history)
#echo -e \$lines_content_from=$lines_content_from \$lines_content_to=$lines_content_to \$1=$1 \$2=$2
  #perl -i -pe 'print "'"${lines_content_from}"\\n""'" if $. == '${2}'; $.= 0 if eof'  ~/.bash_history
  #cmd=$(echo /usr/local/bin/perl -i -pe \"print ${lines_content_from@Q} if $. == ${2}\; $.= 0 if eof\"  ~/.bash_history)
  #echo $cmd
  #eval "$cmd"
  #"${cmd[@]}"
  IFS=$'\n' sorted=($(sort -n <<<"$*"))    ; unset IFS
   #printf "[%s]\n" "${sorted[@]}" ; return 0;
  set ${sorted[*]}

  cmd=$(echo "gsed -i -e '$1{h;d};$2{p;g}' ~/.bash_history")
  echo cmd="$cmd"
  eval "$cmd"
  #perl -i -pe "print \\\"${lines_content_from@Q}\\\" if $. == ${2}\; $.= 0 if eof"  ~/.bash_history
if [[ ${1} -gt ${2} ]] ; then 
 hd2 $((${1}+1))
elif [[ ${2} -gt ${1} ]] ; then 
 hd2 $((${1}+0))
fi
}

hh (){
ho | head -n 30 | column
}

hd () {
if [ "$1" = "-" ] ; then 
 set -- "-30"
fi
if [[ $1 -lt 0 ]] ; then
 if [[ $# -gt 0 ]] ; then
   if [[  ${2} -lt 1 ]] ; then 
    endd=$( cat ~/.bash_history | wc -l | bc )
   else
    endd=${2}
   fi
   
   too=$(expr $endd + $1 )
   too=$(expr $too + 1 )
   echo -n history -d
   for i in $(eval echo {$endd..$too}); do echo -n " "$i; 
   history -d $i; 
   done
   echo -n " "deleted
   history -w
 fi
elif [[ $1 -eq 0 ]] ; then 
 echo nonsense, type "'hd -HowManyLastEntriesToDelete | - {forDeletingTheLast30Entries | Unsorted Numbers To Delete {use 'hhh' for deleting bigger Chunks, use 'ha' to export to .hhh/-folder and keep the selected items from history forever } } "
else
 if [[ $# -gt 1 ]] ; then
   IFS=$'\n' sorted=($(sort -nr <<<"$*"))    ; unset IFS
    #printf "[%s]\n" "${sorted[@]}"
 set ${sorted[*]}
  echo -n history -d
  while [[ $# -ne  0 ]]
  do
    history -d "$1" 
    echo -n " $1" 
    shift 
  done
  echo -n " deleted"
  history -w 
  elif [[ $# -eq 1 ]] ; then
   history -d "$1"
   history -w 
 else
   echo argument fehlt!
  fi
fi
}

#none buggy
hd2 () {
 if [[ $# -eq 0 ]] ; then echo "hd2" with sed-cmd-for-lines; exit; fi
 sed -i.bak -e "${1}d" ~/.bash_history && hu
}

hu () {
 _bash_history_sync
}

h () { 
 history | tail "$@" | column
}

hhh () {
a='l'
while :
 do
  if [[ ${#a} -ne 0 ]]; then
   if [[ ${#2} -ge 1 ]]; then
    history | grep -n -E "$1" | grep "$2"| column
   else
    history | grep -n -E "$1" | column
   fi
  fi
  read -p "{number|[l]ist|[e]dit|[d]elete}||[du]elete duplicates|[ex]port}{e[x]it}: '${1}' '${2}' "  a b
   if     [[ $a == *"ex"* ]]; then
    sed -n -e "${a%%d}d" ~/.bash_history && hu
   elif   [[ $a == *"e"* ]]; then
     echo history -p !${a%%e}
    history -p !${a%%e}
   elif [[ $a == *"du"* ]]; then
    perl -i -ne 'print unless $dup{$_}++;' ~/.bash_history 
    _bash_history_sync
   elif [[ $a == *"d"* ]]; then
    sed -i.bak -e "${a%%d}d" ~/.bash_history && hu
   elif [[ $a == *"x"* ]]; then
    break;
   else
    `sed -n ${a}p ~/.bash_history`
   fi
 done
}

haf () {
[[ ${#1} == 0 ]] && exit;
    cd ~/.hhh ; fp "${1}"
#fp "${@}"
cd - > /dev/null
}

_debugFunc() {
 echo "Func BASH_SOURCE: ${!BASH_SOURCE[@]} ${BASH_SOURCE[@]}"
 echo "Func BASH_LINENO: ${!BASH_LINENO[@]} ${BASH_LINENO[@]}"
 echo "Func FUNCNAME: ${!FUNCNAME[@]} ${FUNCNAME[*]}"
 echo "Func LINENO: ${LINENO}"
}

function bcx { bc -l <<< ${@//[xX]/*}; };

fp () {
[[ "$#" -eq 0 || "$1" == "--help" ]]  && { 
    [[ $(type -t usage) == function ]] && { usage ; return 1 ; }  || 
    { 
cat << EOF
Usage: fp [-d PathToDirToSearchRecursivly] PerlRegExMatchString 
          [-c Cmd]                          type perldoc  -q ' '  FAQRegex 
          [-n NameOfFile]                   for more information
          [-v Verbose]
EOF
    return 1;
    }
}

CMDSET=0;
while getopts ":d:c:n:v:" OPTARG ; do
 case "$OPTARG" in 
  d)
   echo d"$OPTARG"d
   DIR1="$OPTARG";;
  c)
   echo c"$OPTARG"c
   CMD="$OPTARG";;
  n)
   echo n"$OPTARG"n
   NAM1="$OPTARG";;
  v)
   echo v"$OPTARG"v
   VER1="$OPTARG";;
  [?])
   echo usage
   exit 1;;
 esac
done

shift $(($OPTIND-1))

set "${*}"

if [[ $# -le 1 ]] ; then DIR1=`pwd`; fi
if [[ "${#CMD}" -gt 0 ]] ; then
 find "${DIR1}" -type f \( -iname "${NAM1:=*}" ! -name ".*" ! -name "*~" \) -exec perl -ne 'print "vimm \"$ARGV\:$.\"" if /'$1'/' {} \; | sed -n -e "${CMD}"p
 $(find "${DIR1}" -type f \( -iname "${NAM1:=*}" ! -name ".*" ! -name "*~" \) -exec perl -ne 'print "vimm \"$ARGV\:$.\"" if /'$1'/' {} \; | sed -n -e "${CMD}"p)
else 
 if [[ "${VER1}" -gt 0 ]] ; then 
  echo find "${DIR1}" -type f -iname "${NAM1:=*}" \( -iname "${NAM1:=*}" ! -name ".*" ! -name "*~" \) -exec perl -ne 'print "vimm \"$ARGV\:$.\" # $_" if /'$1'/' {} \;
 fi
 find "${DIR1}" -type f \( -iname "${NAM1:=*}" ! -name ".*" ! -name "*~" \) -exec perl -ne 'print "vimm \"$ARGV\:$.\" # $_" if /'$1'/' {} \;
 #find "${DIR1}" -type f \( -iname "${NAM1:=*}" ! -iname ".*" ! -iname "*~" \) | wc -l 
fi
}

ha () {
mkdir -p ~/.hhh
cd ~/.hhh	
if [[ $# -lt 1  ]] ; then echo usage: ha ARG1=NameOfCommandToRemember ARG2=!NoOfHistor[y\|ies]; return 1; fi
fnn=`printf "%-16s" $1 | tr ' ' '-'`
fn=${fnn}-$(eval date \"+%a %d %b %y \(%V\.te Woche\)\" | tr ' ' '-')".txt"
if [[ ! -x $fn ]] ; then touch "$fn"; echo creating $fn ; fi
shift
while [[ $# -ne  0 ]]
 do
   $(sed -n -e "${1}p" ~/.bash_history | tr '\n' '\t\t\t\t\t\t' >> $fn )
   echo -n \#`date "+%a-%d-%b-%HUhr-%y-" && whoami &&  uname -n ` | tr ' ' '\t' >> $fn
   echo -n -e "\t [line(s) ${1} added]" >> $fn
   shift 
   echo "" >> $fn
 done
ls -tl | head -n 2 && cat $fn
}

chr () {
 local val 
 [ "$1" -lt 256 ] || return 1
 while (( "$#" )); do
    printf -v val %o "$1"; printf "\\$val"
    shift  
 done
 }   

ord () {
[[ "$#" -ge 1 ]] && { t=$IFS ; IFS=$',' ; } || { t=$IFS ; IFS='' ; }
 while (( "$#" )); do
    LC_CTYPE=C printf %d"$IFS" "'$1"
    shift
 done
 }

function echos(){ while (( $# )); do eval echo -n \"$1\"=\\\'\"\$$1\"\\\'\'';'\' ; shift ; done ; }

urlencode() {
    # urlencode <string>
    old_lc_collate=$LC_COLLATE
    LC_COLLATE=C
    local length="${#1}"
    for (( i = 0; i < length; i++ )); do
        local c="${1:$i:1}"
        case $c in
            [a-zA-Z0-9.~_-]) printf '%s' "$c" ;;
            *) printf '%%%02X' "'$c" ;;
        esac
    done
    LC_COLLATE=$old_lc_collate
}

urldecode() {
    # urldecode <string>
    local url_encoded="${1//+/ }"
    printf '%b' "${url_encoded//%/\\x}"
}

googlesearchurl() {
    [[ "$#" -ne 1 ]] && { echo "$0: Aufruf darf nur ein Argument haben!"; exit 1 ; }
    gl='https://www.google.de/search?q=';
    result=$(echo -n $gl; urlencode "$1")
    echo $result
}

c () { local in="$(echo " $*" | sed -e 's/\[/(/g' -e 's/\]/)/g')";
       gawk -M -v PREC=201 -M 'BEGIN {printf("%.60g\n",'"${in-0}"')}' < /dev/null
     }
lgrep () { local s="$1"; shift ; grep -i -n -d skip --color=always "$s" "$@" | less -R ; }

vgrep () { local s="$1" ; shift ; vim -c "silent! /$s" -o "$@" ; }

function iso2ris () { # only apple menlo, monaco show correct Reg. Ind. Fonts
local new='🇦🇧🇨🇩🇪🇫🇬🇭🇮🇯🇰🇱🇲🇳🇴🇵🇶🇷🇸🇹🇺🇻🇼🇽🇾🇿'
local klein=abcdefghijklmnopqrstuvwxyz
local gross=ABCDEFGHIJKLMNOPQRSTUVWXYZ
local arr=(); arr=( "$@" ); echo "${arr[@]}"  | gsed -e 's/sv/se/g' -e 's/cs/cz/g' \
    -e 's/en/gb/g' -e 's/el/gr/g' -e 's/da/dk/g' -e 's/ca/es/g' \
    -e 's/uk/ua/g' --e "y/$klein/$new/" -e "y/$gross/$new/" ;
} # get national flags on the commandline, but not allowed to used fonts in printings!

function configLine {
  local OLD_LINE_PATTERN=$1; shift
  local NEW_LINE=$1; shift
  local FILE=$1
  local NEW=$(echo "${NEW_LINE}" | sed 's/\//\\\//g')
  touch "${FILE}"
  gsed -i '/'"${OLD_LINE_PATTERN}"'/{s/.*/'"${NEW}"'/;h};${x;/./{x;q100};x}' "${FILE}"
  if [[ $? -ne 100 ]] && [[ ${NEW_LINE} != '' ]]
  then
    echo "${NEW_LINE}" >> "${FILE}"
  fi
}
#configLine "$@"

For those who have interest, I bound my readline to my own small alexandria bib synced quasi pre-bibliothek, that means all iterm2 and terminal windows are synced when typed twice \n, the pre-bibliothek is located in ~/.hhh/ and contains a lot of re-usable pre snippets since macOS destroys approximately twice a quarter my ~/.bash_history when an update is effected. Very useful to wipeout mistakes and add useful one-liners is

As an example for re-using code a small example is given. I wrote a BASH programm to calculate fuses and heat distribution for manufacturing NMC-LiB. On a Mini-NUC for manufactoring a small linux distro with 10 to 50 MB does still have bash, thus dealing not SI-Units like µikro, Giga… is a potential source of failure deriving from fatigue, converting SI to scientific in pure BASH is needed and could be provided by a small SI-Unit-Conversion-Helper. A bash_SIUnits.sh is to big for a snippet and stored as ~/.hhh/Bash-SIUnits-Di-13-Aug-19-(33.te-Woche).txt.

#/usr/bin/env bash
SIPrefix=( G M K t m µ n p ) ; clear ; date +"%T"  # | tr '\n' ' ' 
SIPrefixUnitOfMeasement=( \*1e9 \*1e6 \*1e3 \*1e3 \*1e-3 \*1e-6 \*1e-9 \*1e-12 )
str=(12Gt 10M 20µ 30n 10K)
echo "${str[@]}" as a sum becomes in scientific notation to
for j in $( seq 0 "${#SIPrefix[@]}"  )
 do 
     str=( "${str[@]/${SIPrefix[$j]}/${SIPrefixUnitOfMeasement[$j]}}" )
done 
IFS=+
echo -n "${str[*]}="
awk "BEGIN { PREC = 113 ; print ${str[*]} }"

If you really want to co-write without having a risk, you need to restrict the wrapper for shell2bbinclude_wrapper.sh.

A secure basis should start with installed util-linux for using getopt --version which should respond something like 'getopt from util-linux 2.37' as well as GNU Core Utils, especially to restrict the incoming variables and parameters with a more secure solution: MyGetOpts.sh could be useful as a starting point.

MyGetOpts.sh

#!/usr/bin/env bash
#==============================================================================
# GNU `MyGetOpts' parse command line args long&short&safe 
#
# Usage: ./MyGetOpts.sh [OPTION] ...
#
# `MyGetOpts' complete script for util linux getopts 
# https://github.com/karelzak/util-linux/blob/master/misc-utils/getopt.c
 # Options:
 #   -v  --verbose          show verbose information
 #   -d  --debug="varname"  view details
 # 
 #       --help             display this help and exit
 #       --version          output version information and exit
 #
# 
# Umgebung: 
#        /usr/bin/env bash > 5.0, getopt util-linux > 2.37 in $PATH
# 
# Report bugs to <norman.heeg@icloud.com>.
# Notes: ---
#       
# Examples:
#    ./MyGetopts.sh --cmd="grep" --file="~/.vim/vimrc" -v                                     
#                   only long opts for clarity       
#    ./MyGetOpts.sh -vdCgrep --file="~/.vim/vimrc" -- Anotherprogname arg1 arg2 arg... 
#                   mixed short opts, note last of short is C big       
#
# [Version]
# GNU MyGetOpts 0.1 
#
# Copyright 2021 Free Software Foundation, Inc.
# This is free software;  see  the  source  for  copying  conditions.
# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
# 
# Written by  Norman R. Heeg (also solarmove), norman.heeg@icloud.com
# Ev. Landeskirche / Belm 14.06.2021
#==============================================================================
 

#-----------------------------------------------------------------------
# Check if we use util-linux getopt 
#-----------------------------------------------------------------------
getopt --test 2> /dev/null
if [[ $? -ne 4 ]]; then 
    echo "Wrong getopt Version: View httpd://frodo/looijaard.neame/project/getopt"
    exit 1
fi

#set -o nounset                            # Treat unset variables as an error
#see http://redsymbol.net/articles/unofficial-bash-strict-mode/ for info
set -euo pipefail   

#-----------------------------------------------------------------------
# Parse for the following long options: 
#-----------------------------------------------------------------------
ARGUMENT_LIST_LONG=(
   "debug"   # enter into debug mode  
   "file:"   # a optional file
   "help"    # display this help and exit
   "verbose" # show additional information on output
   "version" # display version and exit
   "cmd:"    # a command to execute
)

# -----------------------------------------------------------------------
# Parse for the following short options:
# -----------------------------------------------------------------------
ARGUMENT_LIST_SHORT=(
   "d"       # enter into debug mode
   "v"       # display verbose information
   "C:"      # a command to execute
)

#-----------------------------------------------------------------------
# Eventually check sanity of ARGUMENTS 
#-----------------------------------------------------------------------
#for i in ${!ARGUMENT_LIST_LONG[@]} ${!ARGUMENT_LIST_SHORT} ; do 
    #echo "'${ARGUMENT_LIST_LONG[$i]}'" points in --help to "'${ARGUMENT_LIST_SHORT[$i]}'" ; 
#done

# TODO https://www.thegeekstuff.com/2009/12/unix-sed-tutorial-7-examples-for-sed-hold-and-pattern-buffer-operations/

#-----------------------------------------------------------------------
#  Setting the Default Values for long arguments
#-----------------------------------------------------------------------
DEFAULT_DEFAULT=DEFAULT
DEFAULT_ARG_LNG_VALUE=${DEFAULT_DEFAULT}LNG
DEFAULT_ARG_SHT_VALUE=${DEFAULT_DEFAULT}SHT

#uncomment following if needed
#for i in ${ARGUMENT_LIST_LONG[@]} 
#do 
    #i=${i//:/}
    #eval ${i}=${DEFAULT_ARG_LNG_VALUE}
    #eval ${i^^}=${DEFAULT_ARG_LNG_VALUE}
#done
#for i in ${ARGUMENT_LIST_SHORT[@]}
#do 
    #i=${i//:/}
    #eval ${i^^}=$DEFAULT_ARG_SHT_VALUE
    #eval ${i}=$DEFAULT_ARG_SHT_VALUE
#done

#-----------------------------------------------------------------------
#  Initialaze variables 
#-----------------------------------------------------------------------
HELP=0
DEBUG=0
VERBOSE=0
CMD=
FILE=
declare -a EXTRA_ARGS
declare -a POSITIONAL
DISCARD_OPTS_AFTER_DOUBLEDASH=0 # 1=Discard, 0=Save opts afer -- to ${EXTRA_ARGS}

#-----------------------------------------------------------------------
#  Check number of command line arguments
#-----------------------------------------------------------------------
[ $# -lt 1 ] && { sed -n '4,6s/#//p'   $0 ; exit 1 ; } 

#-----------------------------------------------------------------------
#  --version
#-----------------------------------------------------------------------
[[ $1 == --version ]] && { sed -n '/Version/,36p ' "$0" | sed -n -e '2,/^ $/p' | sed -n -e 's/^# //p'; exit 1 ; }

#-----------------------------------------------------------------------
#  --help
#-----------------------------------------------------------------------
[[ $1 == --help ]] && { 
    #sed -n '2,/Version/p' "$0" | gsed -e 's/^[^#]//g' -e 's/^#[ ]\{0,1\}//' -e 's/=//g' -e 's/\[Version\]//'  
    gsed -n '2,/Version/p' "$0" | sed 's/^[^#].*//g' | \
        gsed -z 's/\n\{2,\}//g ; s/##/#/g ; s/# //g ; s/#[=]*//g ; s/\[Version.*// ; '
    echo -n "Options: " ; 
    gsed -n '/^ARGUMENT_LIST_SHORT/,/^)/p' "$0" | gsed '{ 
      s/"//g; 
      s/ \([a-zA-Z]\)/  -\1/ ; 
      s/#//g ; 

      s/"//g; s/^\(.*\)::\(.*\)$/\1\2 (MANDATORY)/g ; 
      s/"//g; s/^\(.*\):\(.*\)$/\1\2 (OPTIONAL)/g ; 

      s/^[^ ]*//g; 
      }'
    gsed -n '/^ARGUMENT_LIST_LONG/,/^)/p' "$0" | gsed '{ 
      s/"//g; 
      s/ \([a-zA-Z]\)/ --\1/ ; 
      s/#//g ; 

      s/"//g; s/^\(.*\)::\(.*\)$/\1  \2 (MANDATORY)/g ; 
      s/"//g; s/^\(.*\):\(.*\)$/\1 \2 (OPTIONAL)/g ; 

      s/^[^ ]*//g; 
      }' 
    exit 1 ; }

#-----------------------------------------------------------------------
#  Now get the long arguments via GNU getopt (and the short)
#-----------------------------------------------------------------------
PARSED=$(getopt --options -dvC: \
    --longoptions "$(printf "%s," "${ARGUMENT_LIST_LONG[@]}")" \
    --name "$(basename "$0")" \
    -- "$@"
)
#--options "$(printf "%s," "${ARGUMENT_LIST_SHORT[@]}")" \

eval set --"${PARSED}"
if [[ $? -ne 0 ]] ; then
    exit 2
fi

#echo "Getopt parsed arguments: ${PARSED}"
#echo "Effective arguments: $@"
#echo "Num args: $#"

dashes=0 #flag to track if we've parsed '--'
while [[ $# -gt 0 ]]; do
    echo "parsing arg: $1" 
    case "$1" in
        -h|--help) 
            HELP=1
            ;;

        -d|--debug) 
            DEBUG=1
            ;;

        -v|--verbose)
            VERBOSE=1
            ;;

        -C|--cmd) shift
            CMD="$1"
            ;;

        --file) shift
            FILE="$1"
            ;;
            
        --) dashes=1
            if [[ $DISCARD_OPTS_AFTER_DOUBLEDASH -eq 1 ]]; then break ; fi
            ;;

        *)
            if [[ $dashes -eq 0 ]]; then POSITIONAL+=("$1")
            else EXTRA_ARGS+=("$1"); fi
            ;;
    esac
    shift
done
set -- "${POSITIONAL[@]}"

#============================================================================
# here you can start to snip away
#============================================================================
echo "Parsed options:"
echo "help: ${HELP}, debug: ${DEBUG}, verbose: ${VERBOSE}"
echo "cmd:  ${CMD:-} file:  ${FILE:-}"

#exit;

#restore positional arguments as $1, $2, etc
echo "Listing positional arguments:"
while [[ $# -gt 0 ]]; do
    #here's where you can parse your positional arguments
    echo "$1"
    shift
done

echo "Extra arguments: (those after --)"
CMD=()
for i in ${!EXTRA_ARGS[@]}; do
    #here's the extra args you can pass to a wrapped utility
    echo "${EXTRA_ARGS[$i]}"
    CMD+=( "${EXTRA_ARGS[$i]}" )
done
echo "execute additional Arguments!"
eval $(printf "%s " "${CMD[@]}")

This is an example for www.solar-shop24.eu


  1. For BBEdit p. 299 - 313 in BBEdit 13.5.3 Manual online retrieved June 2021  ↩︎

  2. As a vim plugin: https://github.com/SirVer/ultisnips  ↩︎

  3. The so–called double Harberger tri–angles .  ↩︎

  4. A so–called second ETS will be established after ‘Fit For 55’ EC speaking, especially for heat and mobility.  ↩︎

  5. Once you know about Plasma physics and supposed you did your job in University quite well, you will not end up doing so…  ↩︎

  6. About Pinch–Point technique could be said a few words here. From a technical point of view, the energy transition is best described with the terms of technical chemistry and the pinch–point technology of BASF, i.e. by identifying the lead process, the following terms are deducted: power, energy and storage capacity, and these terms are hence to be optimized within the heat integration analysis. Roughly speaking, the ErsAut creates the ability to work and to organize family vacation, it expands the energy storage of the Puffer-BEV (PufAut) or the 29V 385A electric scooter with direct PV DC BUS under the seat (XPLASMBEV) and other Thermal Energy Storage (TES). Heat, electricity and cooling for the property are supplied by the use of Batteriewechselrichter (BWR) and the [>WPA]. Anyone who plans [>PVA], then [>BESSI], then [>WPA], is assigned extensive properties of a Verteilnetzbetreiber (DSO) (VNB), then a Steuerbox (digital cyber-war-safe) (STB), then a Steuereinrichtung (analog) (SER) and, as a result, still cannot safely load their [>BEV] or heat their house themselves with their own installed capacities. This technical Bermuda triangle probably applies internationally, regardless of the confusing words. Behind the word “heat integration analysis” there is a data–generating process – 3 years are 105,120 lines – with many interdependencies, few parameters and many interdependent variables. In other words: Anyone who has not understood the main special key chemical will cause a mega–chaos on the construction site, because although they may receive the same analysis behind them or even the same mathematically unambiguous result, they will end up with a different processing sequence – a sequence whose registrations are mostly irreversible.  ↩︎

  7. One has the PVA, BEV and BESSI in an attractive economic scaling, the other nation has the [>EELV🇩🇪]48. That is pure opposite of footnote Harberger.  ↩︎

  8. s.a. Glossar [?îlots économiques de la transition énergétique]: Stratégies de mise en œuvre particulièrement économiques et simples.  ↩︎

  9. s.a. Glossar [?christlich kulturellen Grundlagen]: …  ↩︎

  10. 4P: 🇩🇪 [?Four Play der Energiewende]: Die ‚Großen Vier‘ der Energiewende bestehen aus PVA, BESSI, BEV, WPA; 🇫🇷 [?Quatre Grandes de la transition énergétique]: Les « 4 P » sont les technologies qui doivent être installées dans les maisons et les entreprises à moyen terme afin de pouvoir devenir neutres en CO2, en effet ce soit PvÉ, SéàB, VéàB et PàC.  ↩︎

  11. Note that in June 2021 only one font-family, BabelStone Flags, could render as two 4-byte UTF-8 coded Chars correctly – but Google Noto Color Emoji and Apple Color Emoji both failed, review also Regional indicator symbols. Again a note: The origin reaches back to 2007, still all smartphones have different ‘symbols’ and none were accessible and/or unified.  ↩︎

  12. Dis-organisational organisations would be another description for sensing non-sense.  ↩︎

  13. graph theory is one tool, decomposition as well, to note only two.  ↩︎

  14. A short–circuit in Rankine cycle is used to generate water from air, just to compare the still ongoing–babel with ‘heat’, ‘cold’ and especially Rudolf Clausius ‘entropy’ (ἐν “in” τροπή “transformation”), just compare English Wiki with German Wiki. Only the German explicitly names ‘cold’, none of the both ‘short–circuit’. I was installing the Daikin‘s first FTXZ R–32 in Europe, even most intelligent ’Nerds' could not believe till the first 20 Liter were produced within 30 Minutes.  ↩︎

  15. You might look where that ancient word habitantes comes from.  ↩︎

  16. Here done with [IETE][formulationoftheproblemenergiewende] like proposed in MMD.  ↩︎

  17. For correctly jumping arround one still needs to stick to US Keyboard Layout, <CMD+]> links to forward, <CMD+[> to backward – in all applications like vim, BBEdit, Firefox, Chrome, Finder, Terminal, iTerm2… to just name some of them.  ↩︎

  18. Neither GNU Sed nor Perl’s utf8::encode and utf8::decode deliver this feature out-of-the-box.  ↩︎

  19. The '& % $ # _ { } ~ ^ ' are denoting the special chars in LaTeX and must be avoided, all other UTF8-chars can only be used when compiling with LuaLaTeX.  ↩︎

  20. View details for our dotfiles in the Appendix for how to setup vim, we will do this in PDF due to length restrictions of a typical HTML-file.  ↩︎

  21. or "*y to yank and "*p to paste.  ↩︎

  22. It was the first to cope via CPU with 4K. Nowadays, a Raspberry Pi 4 seems to be a good tool for development or writings.  ↩︎

  23. Here html and latex and later pdf.  ↩︎

  24. See Wiki Speed Reading  ↩︎

  25. So called ‘quer lesen’ is only without internal repitition.  ↩︎

  26. For e.g. combining Virtual Hosts which link each other. A false citation index – and a President being born on Twitter, cited, followed and buried with Twitter.  ↩︎

  27. At least in this MMD context here.  ↩︎

  28. translate engines are aspell, google, bing, spell, hunspell, apertium and yandex.  ↩︎

  29. Comprehensive TeX-Archive Network: Paracol, balanced means same endings, synchronised means same height of beginning paragraph.  ↩︎

  30. While multicol has the better control over floats, the paracol is the package of humantarian writers. I personally was reading a lot of European classic writings through bi-lingual books, which were dominant in the late 60’s and then parished even in old book stores.  ↩︎

  31. Another – or even better – method is explained at the end of transn.  ↩︎

  32. To only pop-up offline thesaurus items stay with vim’s <CTRL-x><CTRL-t>.  ↩︎

  33. Anlage, Anlage, Battery Electric Storage System intelligent and Battery Electric Vehicle  ↩︎

  34. Équipements de, [?Pompe à Chaleur], [?Système de Stockage électrique à Batterie] et [?Véhicule électrique à Batterie]  ↩︎

  35. namely photovoltaic, heat pump, battery electric storage system and battery electric vehicle  ↩︎

  36. carbon free investment with an amortisation time less than 6 months.  ↩︎

  37. BESS is a Battery Energy Storage System  ↩︎

  38. fotovoltaica (sistema), bombas de calor (sistema), sistema de almacenamiento eléctrico de batería inteligente y vehículo eléctrico de batería  ↩︎

  39. Battery Electric Storage System, la abreviatura en inglés es más precisa como ‘espacio de nombres’ que la entrada en Wikipedia wiki es batería de litio  ↩︎

  40. You need to pass landscape via the options in \documentclass[…]{} and use proper packages like \usepackage{pdfpages} and \usepackage{pdflscape} to print multi-lingual manuals – or even Erasmus books.  ↩︎

  41. Anlage, Anlage, Battery Electric Storage System intelligent and Battery Electric Vehicle  ↩︎

  42. Équipements de, [?Pompe à Chaleur], [?Système de Stockage électrique à Batterie] et [?Véhicule électrique à Batterie]  ↩︎

  43. namely photovoltaic, heat pump, battery electric storage system and battery electric vehicle  ↩︎

  44. carbon free investment with an amortisation time less than 6 months.  ↩︎

  45. BESS is a Battery Energy Storage System  ↩︎

  46. specially ‘grouping’ or ‘ordering’ information=knowledge should be done via bib2gls  ↩︎

  47. (_**underlined**_)  ↩︎

  48. s.a. Glossar [?extreme extra low voltage]: an extra low voltage where no plasma can happen.  ↩︎


  1. Anlage:

     ↩︎

  2. Anlage:

     ↩︎

  3. Équipements de:

     ↩︎

  4. Anlage:

     ↩︎

  5. Anlage:

     ↩︎

  6. Équipements de:

     ↩︎


  1. Barebones Inc., BBEdit User Manual, Version 13.5.7, 10/14 2020, Download  ↩︎