diff --git a/.idea/runConfigurations/document_build_pdf.xml b/.idea/runConfigurations/document_build_pdf.xml
new file mode 100644
index 0000000000000000000000000000000000000000..697e35db5edb5c5cba371186df47c5e16e30e36f
--- /dev/null
+++ b/.idea/runConfigurations/document_build_pdf.xml
@@ -0,0 +1,12 @@
+<component name="ProjectRunConfigurationManager">
+  <configuration default="false" name="document build pdf" type="GoApplicationRunConfiguration" factoryName="Go Application">
+    <module name="documentation-manager" />
+    <working_directory value="$PROJECT_DIR$/development/examples/example1" />
+    <parameters value="document pdf " />
+    <kind value="DIRECTORY" />
+    <directory value="$PROJECT_DIR$/application/source" />
+    <filePath value="$PROJECT_DIR$" />
+    <output_directory value="$PROJECT_DIR$/deployment/build" />
+    <method v="2" />
+  </configuration>
+</component>
\ No newline at end of file
diff --git a/README.md b/README.md
index db25e2008ed33f093f78bc8ada38849a320af0d9..b014f6dc39c580cee6cab32152d5eac1ef96f189 100644
--- a/README.md
+++ b/README.md
@@ -26,9 +26,50 @@ go generate translations/translations.go
 ```
 
 
+show font directories
 
+```bash
+kpsepath mf | sed -e 's/:/\n/g'
+```
+
+
+
+### Circled numbers
+
+[compsymb-1qyb3zd.pdf](https://math.uoregon.edu/wp-content/uploads/2014/12/compsymb-1qyb3zd.pdf)
+
+Insert the instructions before instruction ```\begin{document}```
 
+```latex
+\usepackage{pifont} % dingbats
+\usepackage{tikz}   % tikz
+\newcommand*\numcircledtikz[1]{\tikz[baseline=(char.base)]{
+    \node[shape=circle,draw,text=white,fill=black,inner sep=1.2pt] (char) {#1};}}
+```
+
+you can use the following command to insert the number
+
+```latex
+\ding{182}
+\numcircledtikz{1}
+```
+
+dingbats are not supported in the current version of TikZ.
+
+```plain
+① \ding{172} ❶ \ding{182} ➀ \ding{192} ➊ \ding{202}
+② \ding{173} ❷ \ding{183} ➁ \ding{193} ➋ \ding{203}
+③ \ding{174} ❸ \ding{184} ➂ \ding{194} ➌ \ding{204}
+④ \ding{175} ❹ \ding{185} ➃ \ding{195} ➍ \ding{205}
+⑤ \ding{176} ❺ \ding{186} ➄ \ding{196} ➎ \ding{206}
+⑥ \ding{177} ❻ \ding{187} ➅ \ding{197} ➏ \ding{207}
+⑦ \ding{178} ❼ \ding{188} ➆ \ding{198} ➐ \ding{208}
+⑧ \ding{179} ❽ \ding{189} ➇ \ding{199} ➑ \ding{209}
+⑨ \ding{180} ❾ \ding{190} ➈ \ding{200} ➒ \ding{210}
+⑩ \ding{181} ❿ \ding{191} ➉ \ding{201} ➓ \ding{211}
+```
 
+[](https://ctan.net/fonts/libertine/doc/libertine.pdf)
 
 
 
diff --git a/application/source/commands/06_definitions.go b/application/source/commands/01_definitions.go
similarity index 66%
rename from application/source/commands/06_definitions.go
rename to application/source/commands/01_definitions.go
index eaa8c83898d8ac00fb78d4263540db75c0f833c3..f1631d0739fd2713eb93a54c8fbb1b17bce2c9f2 100644
--- a/application/source/commands/06_definitions.go
+++ b/application/source/commands/01_definitions.go
@@ -6,3 +6,13 @@ type Definition struct {
 	Document          DocumentDefinition `command:"document" alias:"d"`
 	Server            ServerDefinition   `command:"server" alias:"s"`
 }
+
+func (d *Definition) GetConfigurationPath() string {
+	return d.ConfigurationPath
+}
+
+var definition *Definition
+
+func init() {
+	definition = &Definition{}
+}
diff --git a/application/source/commands/01_state.go b/application/source/commands/01_state.go
deleted file mode 100644
index 6ab43e4ac0020d3ff261840f6bfc06000e7decfb..0000000000000000000000000000000000000000
--- a/application/source/commands/01_state.go
+++ /dev/null
@@ -1,152 +0,0 @@
-package commands
-
-import (
-	"errors"
-	"github.com/jessevdk/go-flags"
-	"gitlab.schukai.com/oss/utilities/documentation-manager/translations"
-	"os"
-)
-
-type stateStruct struct {
-	info          InfoStruct
-	exitCode      int
-	warnings      []string
-	errors        []string
-	messages      []string
-	parser        *flags.Parser
-	definition    *Definition
-	configuration *Configuration
-}
-
-type StateInterface interface {
-	GetDocumentPath() string
-	GetDateFormat() string
-}
-
-type InfoStruct struct {
-	Version  string
-	Build    string
-	Mnemonic string
-}
-
-var state *stateStruct
-
-func init() {
-	state = &stateStruct{}
-}
-
-func exitWithError(code int, message string, a ...interface{}) {
-	state.setCode(code).addError(translations.T.Sprintf(message, a)).Exit()
-}
-
-func (e *stateStruct) addWarning(warning string) *stateStruct {
-	e.warnings = append(e.warnings, warning)
-	return e
-}
-
-func (e *stateStruct) addError(error string) *stateStruct {
-	e.errors = append(e.errors, error)
-	return e
-}
-
-func (e *stateStruct) addMessage(message string) *stateStruct {
-	e.messages = append(e.messages, message)
-	return e
-}
-
-func (e *stateStruct) setCode(code int) *stateStruct {
-	e.exitCode = code
-	return e
-}
-
-func (e *stateStruct) GetDateFormat() string {
-	if e.definition.Document.DateFormat != "" {
-		return e.definition.Document.DateFormat
-	}
-
-	if e.configuration.Document.DateFormat != "" {
-		return e.configuration.Document.DateFormat
-	}
-
-	return "2006-01-02"
-
-}
-
-func (e *stateStruct) GetDocumentPath() string {
-	if e.definition.Document.Path != "" {
-		return e.definition.Document.Path
-	}
-
-	if e.configuration.Document.Path != "" {
-		return e.configuration.Document.Path
-	}
-
-	path, err := os.Getwd()
-	CheckError(err)
-
-	return path
-
-}
-
-func evaluateTemplate(data string) string {
-	if data == "" {
-		return ""
-	}
-
-	// check if the template is a file
-	template, err := os.ReadFile(data)
-	if err == nil {
-		return string(template)
-	}
-
-	// weather the template is a string
-	if errors.Is(err, os.ErrNotExist) {
-		return data
-	}
-
-	CheckError(err)
-	return ""
-}
-
-func (e *stateStruct) getDocumentTemplate() string {
-
-	if t := evaluateTemplate(e.definition.Document.Add.Template); t != "" {
-		return t
-	}
-
-	if t := evaluateTemplate(e.configuration.Document.Add.Template); t != "" {
-		return t
-	}
-
-	return ""
-
-}
-
-const ExitWithCodeSymbol = "exit with code"
-
-func (e *stateStruct) Exit() {
-	PrintMessages()
-	panic(ExitWithCodeSymbol)
-}
-
-func Exit() {
-
-	for _, fkt := range handlers.shutdown {
-		f := *fkt
-		f()
-	}
-
-	os.Exit(state.exitCode)
-}
-
-func (e *stateStruct) getBuildPath() string {
-	if e.definition.Document.Build.Path != "" {
-		return e.definition.Document.Build.Path
-	}
-
-	if e.configuration.Document.Build.Path != "" {
-		return e.configuration.Document.Build.Path
-	}
-
-	return ""
-}
diff --git a/application/source/commands/02_command.go b/application/source/commands/02_command.go
index 55010e3e75d20a932a3ad2a7050b951ffeca931e..4b6f1ebed0b4d313f764c0a7aab56a063108e303 100644
--- a/application/source/commands/02_command.go
+++ b/application/source/commands/02_command.go
@@ -2,12 +2,13 @@ package commands
 
 import (
 	"github.com/jessevdk/go-flags"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/environment"
 	"strings"
 )
 
 func initCommands() {
 
-	for n, h := range handlers.executor {
+	for n, h := range environment.Handlers.Executor {
 		x := strings.Split(n, "-")
 
 		var c *flags.Command
@@ -15,10 +16,10 @@ func initCommands() {
 		for i, y := range x {
 
 			if i == 0 {
-				c = state.parser.Find(y)
+				c = environment.State.FindCommand(y)
 			} else {
 				if c == nil {
-					exitWithError(1, "Command %s not found", y)
+					environment.ExitWithError(1, "Command %s not found", y)
 				}
 
 				c = c.Find(y)
@@ -27,7 +28,7 @@ func initCommands() {
 		}
 
 		if c != nil {
-			h.init(c)
+			h.Init(c)
 		}
 
 	}
diff --git a/application/source/commands/02_handler.go b/application/source/commands/02_handler.go
deleted file mode 100644
index da3c67b13dd92facb10f94cdbe5dcdfc748c564f..0000000000000000000000000000000000000000
--- a/application/source/commands/02_handler.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package commands
-
-import "github.com/jessevdk/go-flags"
-
-type handlerStruct struct {
-	shutdown []*hook
-	executor map[string]handler
-}
-
-type hook func()
-
-type handler struct {
-	init    func(*flags.Command)
-	execute func(*flags.Command)
-}
-
-var handlers handlerStruct
-
-func init() {
-	handlers.executor = make(map[string]handler)
-	handlers.shutdown = make([]*hook, 0)
-}
-
-func (e *handlerStruct) removeShutdownHook(h *hook) *handlerStruct {
-	for i, f := range e.shutdown {
-		if f == h {
-			e.shutdown = append(e.shutdown[:i], e.shutdown[i+1:]...)
-			return e
-		}
-	}
-	return e
-}
-
-func (e *handlerStruct) addShutdownHook(h *hook) *handlerStruct {
-	e.shutdown = append(e.shutdown, h)
-	return e
-}
diff --git a/application/source/commands/03_errors.go b/application/source/commands/03_errors.go
index e93e9b86ad679dbe04e774c74058fd825df869aa..822f1b1167d5c66f5f172db83feeaea3a4192585 100644
--- a/application/source/commands/03_errors.go
+++ b/application/source/commands/03_errors.go
@@ -3,6 +3,7 @@ package commands
 import (
 	"errors"
 	"github.com/jessevdk/go-flags"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/environment"
 	"gitlab.schukai.com/oss/utilities/documentation-manager/translations"
 )
 
@@ -39,42 +40,42 @@ func checkFlagsError(err error) {
 	e := err.(*flags.Error)
 	switch e.Type {
 	case flags.ErrUnknown:
-		state.addError(translations.T.Sprintf("flag error unknown")).Exit()
+		environment.State.AddError(translations.T.Sprintf("flag error unknown")).Exit()
 	case flags.ErrExpectedArgument:
-		state.addError(translations.T.Sprintf("expected argument")).Exit()
+		environment.State.AddError(translations.T.Sprintf("expected argument")).Exit()
 	case flags.ErrUnknownFlag:
-		state.addError(translations.T.Sprintf("unknown flag")).Exit()
+		environment.State.AddError(translations.T.Sprintf("unknown flag")).Exit()
 	case flags.ErrUnknownGroup:
-		state.addError(translations.T.Sprintf("unknown group")).Exit()
+		environment.State.AddError(translations.T.Sprintf("unknown group")).Exit()
 	case flags.ErrMarshal:
-		state.addError(translations.T.Sprintf("marshal")).Exit()
+		environment.State.AddError(translations.T.Sprintf("marshal")).Exit()
 	case flags.ErrHelp:
-		state.Exit()
+		environment.State.Exit()
 	case flags.ErrNoArgumentForBool:
-		state.addError(translations.T.Sprintf("no argument for bool")).Exit()
+		environment.State.AddError(translations.T.Sprintf("no argument for bool")).Exit()
 	case flags.ErrRequired:
-		state.Exit()
+		environment.State.Exit()
 	case flags.ErrShortNameTooLong:
-		state.addError(translations.T.Sprintf("short name too long")).Exit()
+		environment.State.AddError(translations.T.Sprintf("short name too long")).Exit()
 	case flags.ErrDuplicatedFlag:
-		state.addError(translations.T.Sprintf("duplicated flag")).Exit()
+		environment.State.AddError(translations.T.Sprintf("duplicated flag")).Exit()
 	case flags.ErrTag:
-		state.addError(translations.T.Sprintf("tag %s", err.Error())).Exit()
+		environment.State.AddError(translations.T.Sprintf("tag %s", err.Error())).Exit()
 	case flags.ErrCommandRequired:
-		state.Exit()
+		environment.State.Exit()
 	case flags.ErrUnknownCommand:
-		state.addError(translations.T.Sprintf("unknown command")).Exit()
+		environment.State.AddError(translations.T.Sprintf("unknown command")).Exit()
 	case flags.ErrInvalidChoice:
-		state.addError(translations.T.Sprintf("invalid choice")).Exit()
+		environment.State.AddError(translations.T.Sprintf("invalid choice")).Exit()
 	case flags.ErrInvalidTag:
-		state.addError(translations.T.Sprintf("invalid tag")).Exit()
+		environment.State.AddError(translations.T.Sprintf("invalid tag")).Exit()
 	default:
-		state.addError(translations.T.Sprintf("unrecognized error type")).Exit()
+		environment.State.AddError(translations.T.Sprintf("unrecognized error type")).Exit()
 
 	}
 }
 
-func CheckError(err error) {
+func checkError(err error) {
 	if err == nil {
 		return
 	}
@@ -84,5 +85,5 @@ func CheckError(err error) {
 		checkFlagsError(err)
 	}
 
-	exitWithError(1, "Unknown Error: %s", err.Error())
+	environment.ExitWithError(1, "Unknown Error: %s", err.Error())
 }
diff --git a/application/source/commands/07_execute.go b/application/source/commands/07_execute.go
index b69ed43fda01a7ae632c2da22323243c7249bf59..8098a2c4009ff43a461d7443a982f758aea6bfc7 100644
--- a/application/source/commands/07_execute.go
+++ b/application/source/commands/07_execute.go
@@ -2,42 +2,42 @@ package commands
 
 import (
 	"github.com/jessevdk/go-flags"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/environment"
 	"gitlab.schukai.com/oss/utilities/documentation-manager/translations"
 	"strings"
 )
 
-func Execute(Info InfoStruct) {
+func Execute(Info environment.InfoStruct) {
 
-	state.info = Info
+	environment.State.SetInfo(Info)
 
 	initTerminalState()
 	initCommands()
 
-	_, err := state.parser.Parse()
-	CheckError(err)
+	_, err := environment.State.ParseArguments()
+	checkError(err)
 
-	initConfiguration()
+	environment.InitConfiguration(definition.ConfigurationPath)
 
-	a := state.parser.Command.Active
+	a := environment.State.GetParser().Command.Active
 	if a == nil {
-		exitWithError(1, "No active command found")
+		environment.ExitWithError(1, "No active command found")
 	}
 
 	queue := []string{}
-	runCommand(queue, state.parser.Command.Active)
+	runCommand(queue, environment.State.GetParser().Command.Active)
 
 }
 
 func initTerminalState() {
 
-	definition := &Definition{}
 	parser := flags.NewParser(definition, flags.Default)
 
 	parser.ShortDescription = translations.T.Sprintf("This program can be used to create documentation for your project.")
 	parser.LongDescription = translations.T.Sprintf("This program can be used to create documentation for your project.\nIt can be used to create a new documentation project,\nadd new documentation to an existing project, or to generate\ndocumentation from a source code project.")
 
-	state.parser = parser
-	state.definition = definition
+	environment.State.SetParser(parser)
+	//State.definition = definition
 
 }
 
@@ -52,10 +52,10 @@ func runCommand(queue []string, activeCommand *flags.Command) {
 
 	k := strings.Join(queue, "-")
 
-	if handler, ok := handlers.executor[k]; ok {
-		execute := handler.execute
+	if handler, ok := environment.Handlers.Executor[k]; ok {
+		execute := handler.Execute
 		execute(activeCommand)
 	} else {
-		exitWithError(1, "handler %s not found", k)
+		environment.ExitWithError(1, "handler %s not found", k)
 	}
 }
diff --git a/application/source/commands/08_document.go b/application/source/commands/08_document.go
index 34b671928898c4a5e6c2bf137b6822f80fe9e9f9..a9396477e567c3edbc8c50097783278ba217b2d3 100644
--- a/application/source/commands/08_document.go
+++ b/application/source/commands/08_document.go
@@ -2,6 +2,7 @@ package commands
 
 import (
 	"github.com/jessevdk/go-flags"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/environment"
 	"gitlab.schukai.com/oss/utilities/documentation-manager/translations"
 )
 
@@ -9,19 +10,20 @@ const documentSymbol = "document"
 
 func init() {
 
-	h := handler{
-		init: initDocument,
+	h := environment.Handler{
+		Init: initDocument,
 	}
 
-	handlers.executor[documentSymbol] = h
+	environment.Handlers.Executor[documentSymbol] = h
 
 }
 
 type DocumentDefinition struct {
-	Path       string                  `long:"path" short:"p"`
+	SourcePath string                  `long:"path" short:"p"`
 	DateFormat string                  `long:"date-format" short:"d"`
 	Add        DocumentAddDefinition   `command:"add" alias:"a"`
 	Build      DocumentBuildDefinition `command:"build" alias:"b"`
+	PDF        DocumentPDFDefinition   `command:"pdf"`
 }
 
 func initDocument(command *flags.Command) {
diff --git a/application/source/commands/08_document_add.go b/application/source/commands/08_document_add.go
index 79dda5f14650b3ffa78a602258ff2c402f30fef4..a86c4a8707496fa469ba66d033e0d7bd25ad15a1 100644
--- a/application/source/commands/08_document_add.go
+++ b/application/source/commands/08_document_add.go
@@ -2,11 +2,9 @@ package commands
 
 import (
 	"github.com/jessevdk/go-flags"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/document"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/environment"
 	"gitlab.schukai.com/oss/utilities/documentation-manager/translations"
-	"os"
-	"path"
-	"path/filepath"
-	"strings"
 	"time"
 )
 
@@ -38,12 +36,12 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 
 func init() {
 
-	h := handler{
-		init:    initDocumentAdd,
-		execute: runDocumentAdd,
+	h := environment.Handler{
+		Init:    initDocumentAdd,
+		Execute: runDocumentAdd,
 	}
 
-	handlers.executor[documentAddSymbol] = h
+	environment.Handlers.Executor[documentAddSymbol] = h
 
 }
 
@@ -76,42 +74,25 @@ func initDocumentAdd(command *flags.Command) {
 
 }
 
-func createNewDocument(name string) {
+func runDocumentAdd(command *flags.Command) {
 
-	root := state.GetDocumentPath()
-	path := path.Join(root, name)
+	names := definition.Document.Add.Positional.Name
 
-	fileExtension := filepath.Ext(path)
-	if fileExtension == "" {
-		path += ".md"
-	} else if fileExtension != ".md" {
-		exitWithError(1, "file extension %s is not supported", fileExtension)
+	if len(names) == 0 {
+		environment.ExitWithError(1, "no document name given")
 	}
 
-	template := state.getDocumentTemplate()
+	root := environment.State.GetDocumentPath(definition.Document.SourcePath)
+	template := environment.State.GetDocumentTemplate(definition.Document.Add.Template)
+
+	date := time.Now().Format(environment.State.GetDocumentDateFormat(definition.Document.DateFormat))
 
 	if template == "" {
 		template = newDocumentTemplate
 	}
 
-	date := time.Now().Format(state.GetDateFormat())
-	template = strings.Replace(template, "%%CREATED%%", date, -1)
-
-	err := os.WriteFile(path, []byte(template), 0644)
-	CheckError(err)
-
-}
-
-func runDocumentAdd(command *flags.Command) {
-
-	names := state.definition.Document.Add.Positional.Name
-
-	if len(names) == 0 {
-		exitWithError(1, "no document name given")
-	}
-
 	for _, name := range names {
-		createNewDocument(name)
+		document.CreateNewDocument(name, root, template, date)
 	}
 
 }
diff --git a/application/source/commands/08_document_build.go b/application/source/commands/08_document_build.go
index c305381dc9223466bda3940c7a026e7cafaca40a..a76327c75e8660b51f1a3ac71442d5c6d2287c11 100644
--- a/application/source/commands/08_document_build.go
+++ b/application/source/commands/08_document_build.go
@@ -3,6 +3,7 @@ package commands
 import (
 	"github.com/jessevdk/go-flags"
 	"gitlab.schukai.com/oss/utilities/documentation-manager/document"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/environment"
 	"gitlab.schukai.com/oss/utilities/documentation-manager/translations"
 	"os"
 	"path"
@@ -15,18 +16,19 @@ const documentBuildSymbol = "document-build"
 
 func init() {
 
-	h := handler{
-		init:    initDocumentBuild,
-		execute: runDocumentBuild,
+	h := environment.Handler{
+		Init:    initDocumentBuild,
+		Execute: runDocumentBuild,
 	}
 
-	handlers.executor[documentBuildSymbol] = h
+	environment.Handlers.Executor[documentBuildSymbol] = h
 
 }
 
 type DocumentBuildDefinition struct {
 	Template string `long:"template" short:"t"`
-	Path     string `long:"output" short:"o"`
+	Output   string `long:"output" short:"o"`
+	Format   string `long:"format" short:"f" choice:"html" choice:"pdf" default:"html" `
 }
 
 func initDocumentBuild(command *flags.Command) {
@@ -40,6 +42,8 @@ func initDocumentBuild(command *flags.Command) {
 			opt.Description = translations.T.Sprintf("template for the new document")
 		case "output":
 			opt.Description = translations.T.Sprintf("directory in which the finished documentation is to be written")
+		case "format":
+			opt.Description = translations.T.Sprintf("format of the finished documentation")
 		}
 	}
 
@@ -47,34 +51,37 @@ func initDocumentBuild(command *flags.Command) {
 
 func buildDocumentation(name string) {
 
-	root := state.GetDocumentPath()
+	root := environment.State.GetDocumentPath(definition.Document.SourcePath)
 	path := path.Join(root, name)
 
 	fileExtension := filepath.Ext(path)
 	if fileExtension == "" {
 		path += ".md"
 	} else if fileExtension != ".md" {
-		exitWithError(1, "file extension %s is not supported", fileExtension)
+		environment.ExitWithError(1, "file extension %s is not supported", fileExtension)
 	}
 
-	template := state.getDocumentTemplate()
+	template := environment.State.GetDocumentTemplate(definition.Document.Build.Template)
 
 	if template == "" {
 		template = newDocumentTemplate
 	}
 
-	date := time.Now().Format(state.GetDateFormat())
+	date := time.Now().Format(environment.State.GetDocumentDateFormat(definition.Document.DateFormat))
 	template = strings.Replace(template, "%%CREATED%%", date, -1)
 
 	err := os.WriteFile(path, []byte(template), 0644)
-	CheckError(err)
+	checkError(err)
 
 }
 
 func runDocumentBuild(command *flags.Command) {
 
-	//	buildDocumentation(name)
+	document.Build(document.BuildEnvironment{
+		DateFormat: environment.State.GetDocumentDateFormat(definition.Document.DateFormat),
+		SourcePath: environment.State.GetDocumentPath(definition.Document.SourcePath),
+	})
 
-	document.Import(state.GetDocumentPath())
+	//	buildDocumentation(name)
 
 }
diff --git a/application/source/commands/08_document_pdf.go b/application/source/commands/08_document_pdf.go
new file mode 100644
index 0000000000000000000000000000000000000000..14419cbb0d4753146464af0fbf99c9b924bbc082
--- /dev/null
+++ b/application/source/commands/08_document_pdf.go
@@ -0,0 +1,60 @@
+package commands
+
+import (
+	"github.com/jessevdk/go-flags"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/document"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/environment"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/translations"
+)
+
+const documentPdfSymbol = "document-pdf"
+
+func init() {
+
+	h := environment.Handler{
+		Init:    initDocumentPDF,
+		Execute: runDocumentPDF,
+	}
+
+	environment.Handlers.Executor[documentPdfSymbol] = h
+
+}
+
+type DocumentPDFDefinition struct {
+	LatexTemplate    string `long:"latex-template" short:"l"`
+	MarkdownTemplate string `long:"markdown-template" short:"m"`
+	OutputPath       string `long:"output" short:"o"`
+}
+
+func initDocumentPDF(command *flags.Command) {
+	const text = "Build the documentation as PDF"
+	command.ShortDescription = translations.T.Sprintf(text)
+	command.LongDescription = translations.T.Sprintf(text)
+
+	for _, opt := range command.Options() {
+		switch opt.LongName {
+		case "template":
+			opt.Description = translations.T.Sprintf("template for the new document")
+		case "output":
+			opt.Description = translations.T.Sprintf("directory in which the finished documentation is to be written")
+		case "format":
+			opt.Description = translations.T.Sprintf("format of the finished documentation")
+		}
+	}
+
+}
+
+func runDocumentPDF(command *flags.Command) {
+
+	env := document.BuildPdfEnvironment{
+		DateFormat: environment.State.GetDocumentDateFormat(definition.Document.DateFormat),
+		SourcePath: environment.State.GetDocumentPath(definition.Document.SourcePath),
+		OutputPath: environment.State.GetDocumentPDFOutputPath(definition.Document.PDF.OutputPath),
+	}
+
+	env.Templates.Latex = environment.State.GetPDFLatexTemplatePath(definition.Document.PDF.LatexTemplate)
+	env.Templates.Markdown = environment.State.GetPDFMarkdownTemplatePath(definition.Document.PDF.MarkdownTemplate)
+
+	document.BuildPDF(env)
+
+}
diff --git a/application/source/commands/08_version.go b/application/source/commands/08_version.go
index 82abbba91e49596c44a65c1809cab8d4954c66b9..b4bc78e88c8a267ce670fd0ee1a540e0c1b4e98c 100644
--- a/application/source/commands/08_version.go
+++ b/application/source/commands/08_version.go
@@ -2,6 +2,7 @@ package commands
 
 import (
 	"github.com/jessevdk/go-flags"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/environment"
 	"gitlab.schukai.com/oss/utilities/documentation-manager/translations"
 )
 
@@ -9,12 +10,12 @@ const versionSymbol = "version"
 
 func init() {
 
-	h := handler{
-		init:    initVersion,
-		execute: runVersion,
+	h := environment.Handler{
+		Init:    initVersion,
+		Execute: runVersion,
 	}
 
-	handlers.executor[versionSymbol] = h
+	environment.Handlers.Executor[versionSymbol] = h
 
 }
 
@@ -28,6 +29,6 @@ func initVersion(command *flags.Command) {
 }
 
 func runVersion(command *flags.Command) {
-	translations.T.Printf("version: %s\n", state.info.Version)
-	translations.T.Printf("build: %s\n", state.info.Build)
+	translations.T.Printf("version: %s\n", environment.State.GetVersion())
+	translations.T.Printf("build: %s\n", environment.State.GetBuild())
 }
diff --git a/application/source/commands/09_server.go b/application/source/commands/09_server.go
index d102c31e5b52b84c1ae1211deb668dafaf72685e..6dc2ef6d76441eee618c7ef3b03bc38faf6ef4e9 100644
--- a/application/source/commands/09_server.go
+++ b/application/source/commands/09_server.go
@@ -2,6 +2,7 @@ package commands
 
 import (
 	"github.com/jessevdk/go-flags"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/environment"
 	"gitlab.schukai.com/oss/utilities/documentation-manager/translations"
 )
 
@@ -9,11 +10,11 @@ const serverSymbol = "server"
 
 func init() {
 
-	h := handler{
-		init: initServer,
+	h := environment.Handler{
+		Init: initServer,
 	}
 
-	handlers.executor[serverSymbol] = h
+	environment.Handlers.Executor[serverSymbol] = h
 
 }
 
diff --git a/application/source/commands/09_server_serve.go b/application/source/commands/09_server_serve.go
index 92b123dd7fee2d0b7910f1134174c655736cf606..df17870e01e95f802afb26434fc3404a9bbcf00a 100644
--- a/application/source/commands/09_server_serve.go
+++ b/application/source/commands/09_server_serve.go
@@ -3,6 +3,7 @@ package commands
 import (
 	"fmt"
 	"github.com/jessevdk/go-flags"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/environment"
 	"gitlab.schukai.com/oss/utilities/documentation-manager/translations"
 )
 
@@ -10,12 +11,12 @@ const serverServeSymbol = "server-serve"
 
 func init() {
 
-	h := handler{
-		init:    initServerServe,
-		execute: runServerServe,
+	h := environment.Handler{
+		Init:    initServerServe,
+		Execute: runServerServe,
 	}
 
-	handlers.executor[serverServeSymbol] = h
+	environment.Handlers.Executor[serverServeSymbol] = h
 
 }
 
diff --git a/application/source/document/build.go b/application/source/document/build.go
index 93ead8d5551f1f30951721787adf3c5ebb4b8a35..25ace36b59cdb164b84de4a0bb8ec58fa6a1c034 100644
--- a/application/source/document/build.go
+++ b/application/source/document/build.go
@@ -2,61 +2,20 @@ package document
 
 import (
 	"fmt"
-	"gitlab.schukai.com/oss/utilities/documentation-manager/commands"
-	"io/ioutil"
-	"os"
-	"path"
-	"path/filepath"
 )
 
-func Import(state commands.StateInterface, path string) error {
-	definitions, err := getFiles(path)
-	if err != nil {
-		return err
-	}
-	fmt.Println(definitions)
-	return nil
+type BuildEnvironment struct {
+	SourcePath string
+	DateFormat string
 }
 
-func getFiles(source string) ([]*Definition, error) {
-
-	def := []*Definition{}
-
-	err := filepath.Walk(source,
-		func(current string, info os.FileInfo, err error) error {
-			if err != nil {
-				return err
-			}
-
-			if info.IsDir() {
-				return nil
-			}
-
-			ext := filepath.Ext(current)
-			if ext != ".md" {
-				return nil
-			}
+func Build(env BuildEnvironment) error {
+	dateFormat = env.DateFormat
 
-			cp := path.Clean(current)
-
-			c, err := ioutil.ReadFile(cp)
-			if err != nil {
-				return err
-			}
-
-			err, p := evaluateDocumentContent(c)
-
-			if err != nil {
-				return err
-			}
-
-			def = append(def, NewDefinition(current, info, p))
-			return nil
-		})
+	definitions, err := getFiles(env.SourcePath)
 	if err != nil {
-		return def, err
+		return err
 	}
-
-	return def, err
-
+	fmt.Println(definitions)
+	return nil
 }
diff --git a/application/source/document/create.go b/application/source/document/create.go
new file mode 100644
index 0000000000000000000000000000000000000000..d271a4b0aa7bc9be74362736322ea46ccdb39643
--- /dev/null
+++ b/application/source/document/create.go
@@ -0,0 +1,27 @@
+package document
+
+import (
+	"gitlab.schukai.com/oss/utilities/documentation-manager/environment"
+	"os"
+	"path"
+	"path/filepath"
+	"strings"
+)
+
+func CreateNewDocument(name string, root string, template string, date string) {
+
+	path := path.Join(root, name)
+
+	fileExtension := filepath.Ext(path)
+	if fileExtension == "" {
+		path += ".md"
+	} else if fileExtension != ".md" {
+		environment.ExitWithError(1, "file extension %s is not supported", fileExtension)
+	}
+
+	template = strings.Replace(template, "%%CREATED%%", date, -1)
+
+	err := os.WriteFile(path, []byte(template), 0644)
+	checkError(err)
+
+}
diff --git a/application/source/document/definition.go b/application/source/document/definition.go
deleted file mode 100644
index a2cd36bee2bd6f353a8e1150d201c4cf5cce0518..0000000000000000000000000000000000000000
--- a/application/source/document/definition.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package document
-
-import "os"
-
-type Definition struct {
-	sourcePath string
-	targetPath string
-	fileInfo   os.FileInfo
-	textMeta   textMetaStruct
-}
-
-func NewDefinition(sourcePath string, info os.FileInfo, textMeta textMetaStruct) *Definition {
-	return &Definition{
-		sourcePath: sourcePath,
-		fileInfo:   info,
-		textMeta:   textMeta,
-	}
-}
-
-func (d *Definition) GetSourcePath() string {
-	return d.sourcePath
-}
-
-func (d *Definition) GetTargetPath() string {
-	return d.targetPath
-}
diff --git a/application/source/document/errors.go b/application/source/document/errors.go
new file mode 100644
index 0000000000000000000000000000000000000000..2f6e03b077fb7fea0d12cbaf4acbdd256311c57a
--- /dev/null
+++ b/application/source/document/errors.go
@@ -0,0 +1,49 @@
+package document
+
+import (
+	"errors"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/environment"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/translations"
+)
+
+const (
+	// Generic codes.
+	CodeOK      = 0 // success
+	CodeErr     = 1 // generic error
+	CodeHelpErr = 2 // command is invoked with -help or -h flag but no such flag is defined
+
+	// Codes as defined in /usr/include/sysexits.h on *nix systems.
+	CodeUsage       = 64 // command line usage error
+	CodeDataErr     = 65 // data format error
+	CodeNoInput     = 66 // cannot open input
+	CodeNoUser      = 67 // addressee unknown
+	CodeNoHost      = 68 // host name unknown
+	CodeUnavailable = 69 // service unavailable
+	CodeSoftware    = 70 // internal software error
+	CodeOSErr       = 71 // system error (e.g., can't fork)
+	CodeOSFile      = 72 // critical OS file missing
+	CodeCantCreat   = 73 // can't create (user) output file
+	CodeIOErr       = 74 // input/output error
+	CodeTempFail    = 75 // temp failure; user is invited to retry
+	CodeProtocol    = 76 // remote error in protocol
+	CodeNoPerm      = 77 // permission denied
+	CodeConfig      = 78 // configuration error
+
+)
+
+var (
+	notPermittedError = errors.New(translations.T.Sprintf("Not permitted"))
+)
+
+func checkError(err error) {
+	if err == nil {
+		return
+	}
+
+	//switch err.(type) {
+	//case *flags.Error:
+	//	checkFlagsError(err)
+	//}
+	//
+	environment.ExitWithError(1, "Unknown Error: %s", err.Error())
+}
diff --git a/application/source/document/files.go b/application/source/document/files.go
new file mode 100644
index 0000000000000000000000000000000000000000..c6b89726fd6afe00444d85b239b37eb297e7eb99
--- /dev/null
+++ b/application/source/document/files.go
@@ -0,0 +1,84 @@
+package document
+
+import (
+	"io/ioutil"
+	"os"
+	"path"
+	"path/filepath"
+	"sort"
+)
+
+type SourceFileMap map[string]*SourceFile
+
+func (m SourceFileMap) get(key string) *SourceFile {
+	return m[key]
+}
+
+func (m SourceFileMap) findByRelativePath(rel string) *SourceFile {
+	for _, v := range m {
+		if v.relSourcePath == rel {
+			return v
+			break
+		}
+	}
+	return nil
+}
+
+func buildFileMap(files []*SourceFile) (SourceFileMap, []string) {
+
+	keys := make([]string, 0, len(files))
+	mapFiles := make(map[string]*SourceFile)
+	for _, file := range files {
+		keys = append(keys, file.absSourcePath)
+		mapFiles[file.absSourcePath] = file
+	}
+
+	sort.Strings(keys)
+
+	return mapFiles, keys
+
+}
+
+func getFiles(sourcePath string) ([]*SourceFile, error) {
+
+	def := []*SourceFile{}
+
+	err := filepath.Walk(sourcePath,
+		func(current string, info os.FileInfo, err error) error {
+			if err != nil {
+				return err
+			}
+
+			if info.IsDir() {
+				return nil
+			}
+
+			ext := filepath.Ext(current)
+			if ext != ".md" {
+				return nil
+			}
+
+			cp := path.Clean(current)
+
+			c, err := ioutil.ReadFile(cp)
+			if err != nil {
+				return err
+			}
+
+			err, p := evaluateDocumentContent(c)
+
+			if err != nil {
+				return err
+			}
+
+			def = append(def, NewDefinition(sourcePath, current, info, p))
+			return nil
+		})
+
+	if err != nil {
+		return def, err
+	}
+
+	return def, err
+
+}
diff --git a/application/source/document/mapping.go b/application/source/document/mapping.go
new file mode 100644
index 0000000000000000000000000000000000000000..0b1b2e079be6e4d01a4d60d9f7b9f8807c127e0b
--- /dev/null
+++ b/application/source/document/mapping.go
@@ -0,0 +1,200 @@
+package document
+
+import (
+	"fmt"
+	"regexp"
+	"strings"
+)
+
+var kbdMapping = map[string]string{
+	"ctrl":     "\\LKeyStrg",
+	"tux":      "\\LKeyTux",
+	"win":      "\\LKeyWin",
+	"menu":     "\\LKeyMenu",
+	"strg":     "\\LKeyStrg",
+	"alt":      "\\LKeyAlt",
+	"altgr":    "\\LKeyAltGr",
+	"shift":    "\\LKeyShift",
+	"enter":    "\\LKeyEnter",
+	"tab":      "\\LKeyTab",
+	"capslock": "\\LKeyCapsLock",
+	"pos":      "\\LKeyPos",
+	"entf":     "\\LKeyEntf",
+	"del":      "\\LKeyDel",
+	"ins":      "\\LKeyIns",
+	"einf":     "\\LKeyEinf",
+	"leer":     "\\LKeyLeer",
+	"space":    "\\LKeySpace",
+	"esc":      "\\LKeyEsc",
+	"ende":     "\\LKeyEnde",
+	"back":     "\\LKeyBack",
+	"up":       "\\LKeyUp",
+	"dwon":     "\\LKeyDown",
+	"left":     "\\LKeyLeft",
+	"right":    "\\LKeyRight",
+	"pgup":     "\\LKeyPgUp",
+	"pgdown":   "\\LKeyPgDown",
+}
+
+/**
+
+\DeclareRobustCommand*\LKeyStrg{\BiolinumKeyGlyph{Strg}}
+\DeclareRobustCommand*\LKeyAlt{\BiolinumKeyGlyph{Alt}}
+\DeclareRobustCommand*\LKeyAltApple{\biolinumKeyGlyph{"2325}}
+\DeclareRobustCommand*\LKeyAltGr{\BiolinumKeyGlyph{AltGr}}
+\DeclareRobustCommand*\LKeyShift{\BiolinumKeyGlyph{Shift}}
+\DeclareRobustCommand*\LKeyTab{\BiolinumKeyGlyph{Tab}}
+\DeclareRobustCommand*\LKeyEnter{\BiolinumKeyGlyph{Enter}}
+\DeclareRobustCommand*\LKeyCapslock{\BiolinumKeyGlyph{Capslock}}
+\DeclareRobustCommand*\LKeyPos{\BiolinumKeyGlyph{Pos1}}
+\DeclareRobustCommand*\LKeyEntf{\BiolinumKeyGlyph{Entf}}
+\DeclareRobustCommand*\LKeyEinf{\BiolinumKeyGlyph{Einf}}
+\DeclareRobustCommand*\LKeyLeer{\BiolinumKeyGlyph{Leer}}
+\let\LKeySpace\LKeyLeer
+\DeclareRobustCommand*\LKeyEsc{\BiolinumKeyGlyph{Esc}}
+\DeclareRobustCommand*\LKeyEnde{\BiolinumKeyGlyph{Ende}}
+%\DeclareRobustCommand*\LKeyTux{\BiolinumKeyGlyph{Tux}}
+\DeclareRobustCommand*\LKeyWin{\BiolinumKeyGlyph{Windows}}
+\DeclareRobustCommand*\LKeyMenu{\biolinumKeyGlyph{"E104}}
+\DeclareRobustCommand*\LKeyCtrl{\BiolinumKeyGlyph{Ctrl}}
+\DeclareRobustCommand*\LKeyOptionKey{\BiolinumKeyGlyph{Fn}}
+\DeclareRobustCommand*\LKeyBack{\BiolinumKeyGlyph{Back}}
+\DeclareRobustCommand*\LKeyUp{\biolinumKeyGlyph{"2191}}
+\DeclareRobustCommand*\LKeyDown{\biolinumKeyGlyph{"2193}}
+\DeclareRobustCommand*\LKeyLeft{\biolinumKeyGlyph{"2190}}
+\DeclareRobustCommand*\LKeyRight{\biolinumKeyGlyph{"2192}}
+\DeclareRobustCommand*\LKeyBildUp{\BiolinumKeyGlyph{Buildup}}
+\DeclareRobustCommand*\LKeyBildDown{\BiolinumKeyGlyph{Builddown}}
+\DeclareRobustCommand*\LKeyAt{\biolinumKeyGlyph{"0040}}
+\DeclareRobustCommand*\LKeyFn{\BiolinumKeyGlyph{Fn}}
+\DeclareRobustCommand*\LKeyHome{\BiolinumKeyGlyph{Home}}
+\DeclareRobustCommand*\LKeyDel{\BiolinumKeyGlyph{Del}}
+\DeclareRobustCommand*\LKeyIns{\BiolinumKeyGlyph{Ins}}
+\DeclareRobustCommand*\LKeyEnd{\BiolinumKeyGlyph{End}}
+\DeclareRobustCommand*\LKeyGNU{\BiolinumKeyGlyph{GNU}}
+\DeclareRobustCommand*\LKeyPageUp{\BiolinumKeyGlyph{Pageup}}
+\DeclareRobustCommand*\LKeyPageDown{\BiolinumKeyGlyph{Pagedown}}
+\DeclareRobustCommand*\LKeyWindows{\BiolinumKeyGlyph{Windows}}
+
+\@namedef{libertine@key@F@1}{\BiolinumKeyGlyph{F1}}
+\@namedef{libertine@key@F@2}{\BiolinumKeyGlyph{F2}}
+\@namedef{libertine@key@F@3}{\BiolinumKeyGlyph{F3}}
+\@namedef{libertine@key@F@4}{\BiolinumKeyGlyph{F4}}
+\@namedef{libertine@key@F@5}{\BiolinumKeyGlyph{F5}}
+\@namedef{libertine@key@F@6}{\BiolinumKeyGlyph{F6}}
+\@namedef{libertine@key@F@7}{\BiolinumKeyGlyph{F7}}
+\@namedef{libertine@key@F@8}{\BiolinumKeyGlyph{F8}}
+\@namedef{libertine@key@F@9}{\BiolinumKeyGlyph{F9}}
+\@namedef{libertine@key@F@10}{\BiolinumKeyGlyph{F10}}
+\@namedef{libertine@key@F@11}{\BiolinumKeyGlyph{F11}}
+\@namedef{libertine@key@F@12}{\BiolinumKeyGlyph{F12}}
+\@namedef{libertine@key@F@13}{\BiolinumKeyGlyph{F13}}
+\@namedef{libertine@key@F@14}{\BiolinumKeyGlyph{F14}}
+\@namedef{libertine@key@F@15}{\BiolinumKeyGlyph{F15}}
+\@namedef{libertine@key@F@16}{\BiolinumKeyGlyph{F16}}
+\DeclareRobustCommand*\LKeyF[1]{\@nameuse{libertine@key@F@#1}}
+%
+\DeclareRobustCommand*\LKeyAltF[1]{\LKeyAlt+\@nameuse{libertine@key@F@#1}}
+\DeclareRobustCommand*\LKeyStrgAltF[1]{\LKeyStrg+\LKeyAlt+\@nameuse{libertine@key@F@#1}}
+\DeclareRobustCommand*\LKeyStrgX[1]{\LKeyStrg+\LKey{#1}}
+\DeclareRobustCommand*\LKeyShiftX[1]{\LKeyShift+\LKey{#1}}
+\DeclareRobustCommand*\LKeyAltX[1]{\LKeyAlt+\LKey{#1}}
+\DeclareRobustCommand*\LKeyAltAppleX[1]{\LKeyAltApple+\LKey{#1}}
+\DeclareRobustCommand*\LKeyAltGrX[1]{\LKeyAltGr+\LKey{#1}}
+\DeclareRobustCommand*\LKeyShiftStrgX[1]{\LKeyShift+\LKeyStrg+\LKey{#1}}
+\DeclareRobustCommand*\LKeyShiftAltX[1]{\LKeyShift+\LKeyAlt+\LKey{#1}}
+\DeclareRobustCommand*\LKeyShiftAltGrX[1]{\LKeyShift+\LKeyAltGr+\LKey{#1}}
+\DeclareRobustCommand*\LKeyStrgAltX[1]{\LKeyStrg+\LKeyAlt+\LKey{#1}}
+\DeclareRobustCommand*\LKeyStrgAltEntf{\LKeyStrg+\LKeyAlt+\LKeyEntf}
+\let\LKeyReset\LKeyStrgAltEntf
+%
+\@namedef{libertine@key@Pad@0}{\BiolinumKeyGlyph{Pad0}}
+\@namedef{libertine@key@Pad@1}{\BiolinumKeyGlyph{Pad1}}
+\@namedef{libertine@key@Pad@2}{\BiolinumKeyGlyph{Pad2}}
+\@namedef{libertine@key@Pad@3}{\BiolinumKeyGlyph{Pad3}}
+\@namedef{libertine@key@Pad@4}{\BiolinumKeyGlyph{Pad4}}
+\@namedef{libertine@key@Pad@5}{\BiolinumKeyGlyph{Pad5}}
+\@namedef{libertine@key@Pad@6}{\BiolinumKeyGlyph{Pad6}}
+\@namedef{libertine@key@Pad@7}{\BiolinumKeyGlyph{Pad7}}
+\@namedef{libertine@key@Pad@8}{\BiolinumKeyGlyph{Pad8}}
+\@namedef{libertine@key@Pad@9}{\BiolinumKeyGlyph{Pad9}}
+%\@namedef{libertine@key@Pad@10}{\BiolinumKeyGlyph{"E1AA}}
+%\@namedef{libertine@key@Pad@11}{\BiolinumKeyGlyph{"E1AB}}
+%\@namedef{libertine@key@Pad@12}{\BiolinumKeyGlyph{"E1AC}}
+%\@namedef{libertine@key@Pad@13}{\BiolinumKeyGlyph{"E1AD}}
+%\@namedef{libertine@key@Pad@14}{\BiolinumKeyGlyph{"E1AE}}
+\DeclareRobustCommand*\LKeyPad[1]{\@nameuse{libertine@key@Pad@#1}}
+%
+% Maus
+%
+\iffalse
+\DeclareRobustCommand*\LMouseEmpty{\biolinumKeyGlyph{"E130}}
+\DeclareRobustCommand*\LMouseN{\biolinumKeyGlyph{"E131}}
+\DeclareRobustCommand*\LMouseL{\biolinumKeyGlyph{"E132}}
+\DeclareRobustCommand*\LMouseM{\biolinumKeyGlyph{"E133}}
+\DeclareRobustCommand*\LMouseR{\biolinumKeyGlyph{"E134}}
+\DeclareRobustCommand*\LMouseLR{\biolinumKeyGlyph{"E135}}
+\DeclareRobustCommand*\LMouseIIEmpty{\biolinumKeyGlyph{"E138}}
+\DeclareRobustCommand*\LMouseIIN{\biolinumKeyGlyph{"E139}}
+\DeclareRobustCommand*\LMouseIIL{\biolinumKeyGlyph{"E13A}}
+\DeclareRobustCommand*\LMouseIIR{\biolinumKeyGlyph{"E13C}}
+\DeclareRobustCommand*\LMouseIILR{\biolinumKeyGlyph{"E13D}}
+\fi
+%
+
+*/
+
+func replaceKbd(content string) string {
+
+	regEx := regexp.MustCompile(`(?P<match><kbd[^>]*>(?P<key>[^<]*)</kbd>)`)
+
+	matches := regEx.FindAllStringSubmatch(content, -1)
+	if matches == nil {
+		return content
+	}
+
+	for _, match := range matches {
+		result := make(map[string]string)
+		for i, name := range regEx.SubexpNames() {
+			if i != 0 && name != "" {
+				result[name] = match[i]
+			}
+		}
+
+		r, ok := kbdMapping[strings.ToLower(result["key"])]
+		if !ok {
+			runes := []rune(result["key"])
+			for _, k := range runes {
+				h := strings.ToUpper(fmt.Sprintf("%x", k))
+				h = "uni00" + h
+
+				r += fmt.Sprintf("\\biolinumKeyGlyph{%s}", h)
+			}
+		}
+
+		content = strings.Replace(content, result["match"], r, -1)
+
+	}
+
+	return content
+	//	result := make(map[string]string)
+	//	for i, name := range todoRegEx.SubexpNames() {
+	//		if i != 0 && name != "" {
+	//			result[name] = match[i]
+	//		}
+	//	}
+	//
+	//	if filepath.IsAbs(result["path"]) {
+	//		continue
+	//	}
+	//
+	//
+	//
+	//
+
+	//
+	//
+	//map[string]string{
+
+	//}
+}
diff --git a/application/source/document/pandoc.go b/application/source/document/pandoc.go
new file mode 100644
index 0000000000000000000000000000000000000000..ad421c2929acfd11c76216902b8d9c9ccdc28348
--- /dev/null
+++ b/application/source/document/pandoc.go
@@ -0,0 +1,54 @@
+package document
+
+import (
+	"fmt"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/environment"
+	"os/exec"
+)
+
+func runPandoc(source string, outputName string, latexPath string, luaFilter string) error {
+
+	arguments := "/bin/env pandoc "
+
+	arguments += "--number-sections "
+	arguments += "--variable \"geometry:a4paper,margin=2cm\" "
+	arguments += "--variable fontsize=12pt "
+	arguments += "--variable version=2.0 "
+	arguments += source + " "
+	arguments += "--pdf-engine=xelatex "
+	arguments += "--from markdown "
+	arguments += "--to pdf "
+	arguments += "--listings "
+
+	if latexPath != "" {
+		arguments += "--template=" + latexPath + " "
+	}
+
+	if luaFilter != "" {
+		arguments += "--lua-filter=" + luaFilter + " "
+	}
+
+	arguments += "--columns=5 "
+	arguments += "--highlight-style espresso "
+	arguments += "--toc "
+	arguments += "--output=" + outputName + " "
+
+	fmt.Println(arguments)
+
+	cmd, err := exec.Command("bash", "-c", arguments).Output()
+	fmt.Println(string(cmd))
+	if err != nil {
+
+		exitErr, ok := err.(*exec.ExitError)
+		if ok {
+			environment.ExitWithError(2, string(exitErr.Stderr))
+
+		} else {
+			environment.ExitWithError(2, err.Error())
+		}
+
+	}
+
+	return err
+
+}
diff --git a/application/source/document/pdf.go b/application/source/document/pdf.go
new file mode 100644
index 0000000000000000000000000000000000000000..6b59e149ec92c4af77598905832ae543807448f0
--- /dev/null
+++ b/application/source/document/pdf.go
@@ -0,0 +1,284 @@
+package document
+
+import (
+	"fmt"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/environment"
+	"io/ioutil"
+	"os"
+	"path"
+	"path/filepath"
+	"regexp"
+	"strings"
+	"text/template"
+)
+
+type BuildPdfEnvironment struct {
+	SourcePath string
+	DateFormat string
+	OutputPath string
+	Templates  struct {
+		Latex    string
+		Markdown string
+	}
+}
+
+type PdfDataset struct {
+	Documents string
+}
+
+func NewPdfDataset(env BuildPdfEnvironment) (*PdfDataset, error) {
+
+	files, err := getFiles(env.SourcePath)
+	if err != nil {
+		return nil, err
+	}
+
+	mapFiles, keys := buildFileMap(files)
+
+	d := &PdfDataset{}
+
+	docs := []string{}
+	for _, key := range keys {
+
+		text := mapFiles[key].textMeta.text
+		text = convertImages(text, env.SourcePath)
+		text = convertCircledNumbers(text)
+		text = replaceKbd(text)
+		text = replaceRelativeLinks(text, mapFiles[key].hash, mapFiles)
+
+		docs = append(docs, "\\newpage"+text)
+	}
+
+	d.Documents = strings.Join(docs, "\n")
+
+	fmt.Println(d.Documents)
+
+	return d, nil
+}
+
+func BuildPDF(env BuildPdfEnvironment) error {
+
+	output := env.OutputPath
+
+	if env.DateFormat != "" {
+		dateFormat = env.DateFormat
+	}
+
+	if !filepath.IsAbs(output) {
+		pwd := os.Getenv("PWD")
+		output = path.Clean(path.Join(pwd, output))
+	}
+
+	if output == "" {
+		environment.ExitWithError(2, "if the type is pdf, the output option must be specified")
+	}
+
+	file, err := ioutil.TempFile(os.TempDir(), environment.State.GetInfo().Mnemonic)
+	checkError(err)
+
+	defer func() {
+		file.Close()
+		os.Remove(file.Name())
+	}()
+
+	content := environment.ReadTemplate(env.Templates.Markdown)
+	t, err := template.New("pdf").Parse(content)
+	checkError(err)
+
+	d, err := NewPdfDataset(env)
+	checkError(err)
+
+	err = t.Execute(file, d)
+	checkError(err)
+
+	luaFilter := createLuaFile()
+	defer func() {
+		if luaFilter != nil {
+			luaFilter.Close()
+			os.Remove(luaFilter.Name())
+		}
+	}()
+
+	runPandoc(file.Name(), output, env.Templates.Latex, luaFilter.Name())
+	return nil
+
+}
+
+func replaceRelativeLinks(content, hash string, fileMap SourceFileMap) string {
+
+	label := "link_" + hash
+	content = "\\hypertarget{" + label + "}{ } \n" + strings.TrimSpace(content) + "\n"
+
+	regEx := regexp.MustCompile(`(?:^|[^!])(?P<match>\[(?P<label>[^]]*)\]\((?P<path>[^)]*)\))`)
+	matches := regEx.FindAllStringSubmatch(content, -1)
+	if matches == nil {
+		return content
+	}
+
+	for _, match := range matches {
+		result := make(map[string]string)
+		for i, name := range regEx.SubexpNames() {
+			if i != 0 && name != "" {
+				result[name] = match[i]
+			}
+		}
+
+		if filepath.IsAbs(result["path"]) {
+			continue
+		}
+
+		s := fileMap.findByRelativePath(result["path"])
+		replace := "\\hyperlink{link_" + s.hash + "}{" + result["label"] + "}"
+		content = strings.Replace(content, result["match"], replace, -1)
+
+	}
+
+	return content
+}
+
+func createLuaFile() *os.File {
+
+	tmp, err := ioutil.TempFile(os.TempDir(), "lua-raw-block")
+	if err != nil {
+		environment.ExitWithError(2, "A temporary file cannot be created", err.Error())
+	}
+
+	tmp.WriteString(`
+function RawBlock (raw)
+	return raw.format:match 'html'
+	and pandoc.read(raw.text, 'html').blocks
+	or raw
+end
+`)
+
+	return tmp
+
+}
+
+func convertCircledNumbers(content string) string {
+
+	circleMap := map[string]string{
+		"➊": "\\large\\libertineGlyph{uni2776}\\normalsize",
+		"➋": "\\large\\libertineGlyph{uni2777}\\normalsize",
+		"➌": "\\large\\libertineGlyph{uni2778}\\normalsize",
+		"➍": "\\large\\libertineGlyph{uni2779}\\normalsize",
+		"➎": "\\large\\libertineGlyph{uni277A}\\normalsize",
+		"➏": "\\large\\libertineGlyph{uni277B}\\normalsize",
+		"➐": "\\large\\libertineGlyph{uni277C}\\normalsize",
+		"➑": "\\large\\libertineGlyph{uni277D}\\normalsize",
+		"➒": "\\large\\libertineGlyph{uni277E}\\normalsize",
+		"➓": "\\large\\libertineGlyph{uni277F}\\normalsize",
+		"⓫": "\\large\\libertineGlyph{uni24EB}\\normalsize",
+		"⓬": "\\large\\libertineGlyph{uni24EC}\\normalsize",
+		"⓭": "\\large\\libertineGlyph{uni24ED}\\normalsize",
+		"⓮": "\\large\\libertineGlyph{uni24EE}\\normalsize",
+		"⓯": "\\large\\libertineGlyph{uni24EF}\\normalsize",
+		"⓰": "\\large\\libertineGlyph{uni24F0}\\normalsize",
+		"⓱": "\\large\\libertineGlyph{uni24F1}\\normalsize",
+		"⓲": "\\large\\libertineGlyph{uni24F2}\\normalsize",
+		"⓳": "\\large\\libertineGlyph{uni24F3}\\normalsize",
+		"⓴": "\\large\\libertineGlyph{uni24F4}\\normalsize",
+	}
+
+	for k, v := range circleMap {
+		content = strings.Replace(content, k, v, -1)
+	}
+
+	return content
+}
+
+func convertImages(content string, absolute string) string {
+
+	todoRegEx := regexp.MustCompile(`(?P<match>\!\[(?P<label>[^]]*)\]\((?P<path>[^)]*)\))`)
+
+	matches := todoRegEx.FindAllStringSubmatch(content, -1)
+	if matches == nil {
+		return content
+	}
+
+	for _, match := range matches {
+		result := make(map[string]string)
+		for i, name := range todoRegEx.SubexpNames() {
+			if i != 0 && name != "" {
+				result[name] = match[i]
+			}
+		}
+
+		if filepath.IsAbs(result["path"]) {
+			continue
+		}
+
+		path := path.Clean(absolute + "/" + result["path"])
+		content = strings.Replace(content, result["match"], "!["+result["label"]+"]("+path+")", -1)
+
+	}
+
+	return content
+}
+
+func convertTemplateLogo(content string, absolute string) string {
+	todoRegEx := regexp.MustCompile(`(?m)^(?P<match>logo:\s*"?(?P<path>[^"\n]*)"?\s*)$`)
+
+	matches := todoRegEx.FindAllStringSubmatch(content, -1)
+	if matches == nil {
+		return content
+	}
+
+	for _, match := range matches {
+		result := make(map[string]string)
+		for i, name := range todoRegEx.SubexpNames() {
+			if i != 0 && name != "" {
+				result[name] = match[i]
+			}
+		}
+
+		if filepath.IsAbs(result["path"]) {
+			continue
+		}
+
+		path := path.Clean(absolute + "/" + result["path"])
+		content = strings.Replace(content, result["match"], "logo: \""+path+"\"", -1)
+
+	}
+
+	return content
+}
+
+func convertTemplateLatexLogo(content string, absolute string) string {
+	todoRegEx := regexp.MustCompile(`(?m)(?P<match>\\includegraphics[^{]*\{(?P<path>[^}]*)\})`)
+
+	matches := todoRegEx.FindAllStringSubmatch(content, -1)
+	if matches == nil {
+		return content
+	}
+
+	for _, match := range matches {
+		result := make(map[string]string)
+		for i, name := range todoRegEx.SubexpNames() {
+			if i != 0 && name != "" {
+				result[name] = match[i]
+			}
+		}
+
+		if filepath.IsAbs(result["path"]) {
+			continue
+		}
+
+		path := path.Clean(absolute + "/" + result["path"])
+		a := strings.Replace(result["match"], result["path"], path, -1)
+
+		content = strings.Replace(content, result["match"], a, -1)
+
+	}
+
+	return content
+}
+
+//
+//func convertTemplateImages(content string, absolute string) string {
+//	content = convertTemplateLogo(content, absolute)
+//	content = convertTemplateLatexLogo(content, absolute)
+//
+//	return content
+//
+//}
diff --git a/application/source/document/source.go b/application/source/document/source.go
new file mode 100644
index 0000000000000000000000000000000000000000..eda6734680da3594c164b745efb5d26396d58f4b
--- /dev/null
+++ b/application/source/document/source.go
@@ -0,0 +1,42 @@
+package document
+
+import (
+	"crypto/md5"
+	"fmt"
+	"os"
+	"path/filepath"
+)
+
+type SourceFile struct {
+	//dateFormat string
+	absSourcePath string
+	relSourcePath string
+	//targetPath string
+	fileInfo os.FileInfo
+	textMeta textMetaStruct
+	hash     string
+}
+
+func NewDefinition(root string, sourcePath string, info os.FileInfo, textMeta textMetaStruct) *SourceFile {
+
+	r, _ := filepath.Rel(root, sourcePath)
+
+	s := &SourceFile{
+		relSourcePath: r,
+		absSourcePath: sourcePath,
+		fileInfo:      info,
+		textMeta:      textMeta,
+	}
+
+	s.hash = fmt.Sprintf("%x", md5.Sum([]byte(r)))
+
+	return s
+}
+
+func (d *SourceFile) GetSourcePath() string {
+	return d.absSourcePath
+}
+
+//func (d *SourceFile) GetTargetPath() string {
+//	return d.targetPath
+//}
diff --git a/application/source/document/yaml.go b/application/source/document/yaml.go
index bee5724975304d884e86ea8e35857ffefc879097..743333434f6617875d8af2a408c8ad22e70902ec 100644
--- a/application/source/document/yaml.go
+++ b/application/source/document/yaml.go
@@ -9,6 +9,8 @@ import (
 	"time"
 )
 
+var dateFormat = "2006-01-02"
+
 type textMetaStruct struct {
 	text string
 	meta document
@@ -24,8 +26,12 @@ func (l *LocaleTime) UnmarshalYAML(unmarshal func(interface{}) error) error {
 		return err
 	}
 
-	t, err := time.Parse(, s)
+	t, err := time.Parse(dateFormat, s)
 	if err != nil {
+		t, err = time.Parse("2006-01-02", s)
+		if err != nil {
+			return err
+		}
 		return err
 	}
 
@@ -44,18 +50,23 @@ func evaluateDocumentContent(content []byte) (error, textMetaStruct) {
 	before, remaining, found := strings.Cut(origin, "---")
 	if !found {
 
-		t := strings.TrimSpace(origin)
-		if len(t) == 0 {
-			return errors.New("the file is empty"), textMetaStruct{
-				text: origin,
-				meta: document{},
-			}
-		}
-
-		return errors.New("the file does not contain a definition block"), textMetaStruct{
-			text: origin,
-			meta: document{},
-		}
+		req := textMetaStruct{}
+		req.text = origin
+		
+		return nil, req
+
+		//t := strings.TrimSpace(origin)
+		//if len(t) == 0 {
+		//	return errors.New("the file is empty"), textMetaStruct{
+		//		text: origin,
+		//		meta: document{},
+		//	}
+		//}
+		//
+		//return errors.New("the file does not contain a definition block"), textMetaStruct{
+		//	text: origin,
+		//	meta: document{},
+		//}
 	}
 
 	text += before
diff --git a/application/source/commands/01_config.go b/application/source/environment/config.go
similarity index 59%
rename from application/source/commands/01_config.go
rename to application/source/environment/config.go
index 8a773e627a3d657642f15d971c624995e37f0095..c51dee12af4834d29b4c0d5e901de3c31d3e6a16 100644
--- a/application/source/commands/01_config.go
+++ b/application/source/environment/config.go
@@ -1,4 +1,4 @@
-package commands
+package environment
 
 import (
 	"github.com/kelseyhightower/envconfig"
@@ -18,8 +18,15 @@ type Configuration struct {
 			Template string `yaml:"Template" envconfig:"NEW_TEMPLATE"`
 		}
 		Build struct {
-			Path string `yaml:"Path" envconfig:"BUILD_PATH"`
+			//Path string `yaml:"Path" envconfig:"BUILD_PATH"`
 		} `yaml:"Build"`
+		PDF struct {
+			Output   string `yaml:"Output" envconfig:"PDF_OUTPUT"`
+			Teplates struct {
+				Latex    string `yaml:"Latex" envconfig:"PDF_LATEX_TEMPLATE"`
+				Markdown string `yaml:"Markdown" envconfig:"PDF_MARKDOWN_TEMPLATE"`
+			} `yaml:"Templates"`
+		} `yaml:"PDF"`
 	} `yaml:"Document"`
 }
 
@@ -36,7 +43,7 @@ func checkAndInitConfiguration(name string) bool {
 	defer ptr.Close()
 
 	decoder := yaml.NewDecoder(ptr)
-	err = decoder.Decode(state.configuration)
+	err = decoder.Decode(State.configuration)
 
 	if err != nil {
 		return false
@@ -45,13 +52,13 @@ func checkAndInitConfiguration(name string) bool {
 	return true
 }
 
-func initConfiguration() {
+func InitConfiguration(configPath string) {
 
 	userConfig := ""
 
 	usr, err := user.Current()
 	if err == nil {
-		userConfig = usr.HomeDir + "/.config/" + state.info.Mnemonic + "/" + configFileName
+		userConfig = usr.HomeDir + "/.config/" + State.info.Mnemonic + "/" + configFileName
 	}
 
 	current, err := os.Getwd()
@@ -59,15 +66,15 @@ func initConfiguration() {
 		current = current + "/" + configFileName
 	}
 
-	state.configuration = &Configuration{}
-	err = envconfig.Process(strings.ToUpper(state.info.Mnemonic), state.configuration)
-	CheckError(err)
+	State.configuration = &Configuration{}
+	err = envconfig.Process(strings.ToUpper(State.info.Mnemonic), State.configuration)
+	checkError(err)
 
 	for _, path := range []string{
-		state.definition.ConfigurationPath,
+		configPath,
 		current,
 		userConfig,
-		"/etc/" + state.info.Mnemonic + "/" + configFileName} {
+		"/etc/" + State.info.Mnemonic + "/" + configFileName} {
 		if checkAndInitConfiguration(path) {
 			return
 		}
diff --git a/application/source/environment/errors.go b/application/source/environment/errors.go
new file mode 100644
index 0000000000000000000000000000000000000000..18468b015c162fdfd6a3b781115e05e147ec8eab
--- /dev/null
+++ b/application/source/environment/errors.go
@@ -0,0 +1,48 @@
+package environment
+
+import (
+	"errors"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/translations"
+)
+
+const (
+	// Generic codes.
+	CodeOK      = 0 // success
+	CodeErr     = 1 // generic error
+	CodeHelpErr = 2 // command is invoked with -help or -h flag but no such flag is defined
+
+	// Codes as defined in /usr/include/sysexits.h on *nix systems.
+	CodeUsage       = 64 // command line usage error
+	CodeDataErr     = 65 // data format error
+	CodeNoInput     = 66 // cannot open input
+	CodeNoUser      = 67 // addressee unknown
+	CodeNoHost      = 68 // host name unknown
+	CodeUnavailable = 69 // service unavailable
+	CodeSoftware    = 70 // internal software error
+	CodeOSErr       = 71 // system error (e.g., can't fork)
+	CodeOSFile      = 72 // critical OS file missing
+	CodeCantCreat   = 73 // can't create (user) output file
+	CodeIOErr       = 74 // input/output error
+	CodeTempFail    = 75 // temp failure; user is invited to retry
+	CodeProtocol    = 76 // remote error in protocol
+	CodeNoPerm      = 77 // permission denied
+	CodeConfig      = 78 // configuration error
+
+)
+
+var (
+	notPermittedError = errors.New(translations.T.Sprintf("Not permitted"))
+)
+
+func checkError(err error) {
+	if err == nil {
+		return
+	}
+
+	//switch err.(type) {
+	//case *flags.Error:
+	//	checkFlagsError(err)
+	//}
+	//
+	ExitWithError(1, "Unknown Error: %s", err.Error())
+}
diff --git a/application/source/environment/handler.go b/application/source/environment/handler.go
new file mode 100644
index 0000000000000000000000000000000000000000..4340f3919707bf306766d111f51e2c33e207d39f
--- /dev/null
+++ b/application/source/environment/handler.go
@@ -0,0 +1,37 @@
+package environment
+
+import "github.com/jessevdk/go-flags"
+
+type HandlerStruct struct {
+	Shutdown []*Hook
+	Executor map[string]Handler
+}
+
+type Hook func()
+
+type Handler struct {
+	Init    func(*flags.Command)
+	Execute func(*flags.Command)
+}
+
+var Handlers HandlerStruct
+
+func init() {
+	Handlers.Executor = make(map[string]Handler)
+	Handlers.Shutdown = make([]*Hook, 0)
+}
+
+func (e *HandlerStruct) RemoveShutdownHook(h *Hook) *HandlerStruct {
+	for i, f := range e.Shutdown {
+		if f == h {
+			e.Shutdown = append(e.Shutdown[:i], e.Shutdown[i+1:]...)
+			return e
+		}
+	}
+	return e
+}
+
+func (e *HandlerStruct) AddShutdownHook(h *Hook) *HandlerStruct {
+	e.Shutdown = append(e.Shutdown, h)
+	return e
+}
diff --git a/application/source/commands/03_messages.go b/application/source/environment/messages.go
similarity index 63%
rename from application/source/commands/03_messages.go
rename to application/source/environment/messages.go
index 0581ad790ed920e38cd2a39e0c5cf2a4144eb26a..65d5d2944e4eb195cd877ef90e4c3597a99fff7a 100644
--- a/application/source/commands/03_messages.go
+++ b/application/source/environment/messages.go
@@ -1,4 +1,4 @@
-package commands
+package environment
 
 import (
 	"github.com/gookit/color"
@@ -10,33 +10,33 @@ func PrintMessages() {
 
 	const indent = "  "
 
-	if len(state.errors) > 0 {
+	if len(State.errors) > 0 {
 		color.Error.Println(strings.ToUpper(translations.T.Sprintf("Error")) + ":")
 	}
 
-	for _, message := range state.errors {
+	for _, message := range State.errors {
 		color.Error.Println(indent + message)
 	}
 
-	if len(state.warnings) > 0 {
+	if len(State.warnings) > 0 {
 		color.Warn.Println(strings.ToUpper(translations.T.Sprintf("Warn")) + ":")
 	}
 
-	for _, message := range state.warnings {
+	for _, message := range State.warnings {
 		color.Warn.Println(indent + message)
 	}
 
-	if len(state.messages) > 0 {
+	if len(State.messages) > 0 {
 		color.Info.Println(strings.ToUpper(translations.T.Sprintf("Info")) + ":")
 	}
 
-	for _, message := range state.messages {
+	for _, message := range State.messages {
 		color.Info.Println(indent + message)
 	}
 
 	// reset
-	state.messages = []string{}
-	state.warnings = []string{}
-	state.errors = []string{}
+	State.messages = []string{}
+	State.warnings = []string{}
+	State.errors = []string{}
 
 }
diff --git a/application/source/environment/state.go b/application/source/environment/state.go
new file mode 100644
index 0000000000000000000000000000000000000000..2b6d496e85a8099d913b5fcdd64d4cb69a5c5946
--- /dev/null
+++ b/application/source/environment/state.go
@@ -0,0 +1,109 @@
+package environment
+
+import (
+	"errors"
+	"github.com/jessevdk/go-flags"
+	"os"
+)
+
+type stateStruct struct {
+	info          InfoStruct
+	exitCode      int
+	warnings      []string
+	errors        []string
+	messages      []string
+	parser        *flags.Parser
+	configuration *Configuration
+}
+
+type DefinitionInterface interface {
+	GetDocumentPath() string
+	GetDateFormat() string
+}
+
+type InfoStruct struct {
+	Version  string
+	Build    string
+	Mnemonic string
+}
+
+var State *stateStruct
+
+func init() {
+	State = &stateStruct{}
+}
+
+func (e *stateStruct) SetParser(parser *flags.Parser) *stateStruct {
+	e.parser = parser
+	return e
+}
+
+func (e *stateStruct) GetInfo() InfoStruct {
+	return e.info
+}
+
+func (e *stateStruct) SetInfo(info InfoStruct) *stateStruct {
+	e.info = info
+	return e
+}
+
+func (e *stateStruct) GetParser() *flags.Parser {
+	return e.parser
+}
+
+func (e *stateStruct) ParseArguments() ([]string, error) {
+	return e.parser.Parse()
+}
+
+func (e *stateStruct) FindCommand(name string) *flags.Command {
+	return State.parser.Find(name)
+}
+
+func (e *stateStruct) AddWarning(warning string) *stateStruct {
+	e.warnings = append(e.warnings, warning)
+	return e
+}
+
+func (e *stateStruct) AddError(error string) *stateStruct {
+	e.errors = append(e.errors, error)
+	return e
+}
+
+func (e *stateStruct) AddMessage(message string) *stateStruct {
+	e.messages = append(e.messages, message)
+	return e
+}
+
+func (e *stateStruct) SetCode(code int) *stateStruct {
+	e.exitCode = code
+	return e
+}
+
+func (e *stateStruct) GetVersion() string {
+	return e.info.Version
+}
+
+func (e *stateStruct) GetBuild() string {
+	return e.info.Build
+
+}
+
+func evaluateTemplate(data string) string {
+	if data == "" {
+		return ""
+	}
+
+	// check if the template is a file
+	template, err := os.ReadFile(data)
+	if err == nil {
+		return string(template)
+	}
+
+	// weather the template is a string
+	if errors.Is(err, os.ErrNotExist) {
+		return data
+	}
+
+	checkError(err)
+	return ""
+}
diff --git a/application/source/environment/state_document.go b/application/source/environment/state_document.go
new file mode 100644
index 0000000000000000000000000000000000000000..33368733e3175e613cdeb750da808c429710cb82
--- /dev/null
+++ b/application/source/environment/state_document.go
@@ -0,0 +1,47 @@
+package environment
+
+import "os"
+
+func (e *stateStruct) GetDocumentDateFormat(arg string) string {
+	if arg != "" {
+		return arg
+	}
+
+	if e.configuration.Document.DateFormat != "" {
+		return e.configuration.Document.DateFormat
+	}
+
+	return "2006-01-02"
+
+}
+
+func (e *stateStruct) GetDocumentPath(arg string) string {
+	if arg != "" {
+		return arg
+	}
+
+	if e.configuration.Document.Path != "" {
+		return e.configuration.Document.Path
+	}
+
+	path, err := os.Getwd()
+	checkError(err)
+
+	return path
+}
+
+func (e *stateStruct) GetDocumentTemplate(arg string) string {
+
+	if arg != "" {
+		if t := evaluateTemplate(arg); t != "" {
+			return t
+		}
+	}
+
+	if t := evaluateTemplate(e.configuration.Document.Add.Template); t != "" {
+		return t
+	}
+
+	return ""
+
+}
diff --git a/application/source/environment/state_exit.go b/application/source/environment/state_exit.go
new file mode 100644
index 0000000000000000000000000000000000000000..fd21bf95c8fc6504cd51b147bc61476dc04f0bc6
--- /dev/null
+++ b/application/source/environment/state_exit.go
@@ -0,0 +1,27 @@
+package environment
+
+import (
+	"gitlab.schukai.com/oss/utilities/documentation-manager/translations"
+	"os"
+)
+
+const ExitWithCodeSymbol = "exit with code"
+
+func (e *stateStruct) Exit() {
+	PrintMessages()
+	panic(ExitWithCodeSymbol)
+}
+
+func Exit() {
+
+	for _, fkt := range Handlers.Shutdown {
+		f := *fkt
+		f()
+	}
+
+	os.Exit(State.exitCode)
+}
+
+func ExitWithError(code int, message string, a ...interface{}) {
+	State.SetCode(code).AddError(translations.T.Sprintf(message, a)).Exit()
+}
diff --git a/application/source/environment/state_pdf.go b/application/source/environment/state_pdf.go
new file mode 100644
index 0000000000000000000000000000000000000000..2a86cd91e60edcb51e35820fd8e2ad3ce8746870
--- /dev/null
+++ b/application/source/environment/state_pdf.go
@@ -0,0 +1,40 @@
+package environment
+
+func (e *stateStruct) GetPDFOutputPath() string {
+	return e.configuration.Document.PDF.Output
+}
+
+func (e *stateStruct) GetPDFLatexTemplatePath(arg string) string {
+	if arg != "" {
+		return arg
+	}
+
+	if e.configuration.Document.PDF.Teplates.Latex != "" {
+		return e.configuration.Document.PDF.Teplates.Latex
+	}
+
+	return ""
+}
+
+func (e *stateStruct) GetPDFMarkdownTemplatePath(arg string) string {
+	if arg != "" {
+		return arg
+	}
+
+	if e.configuration.Document.PDF.Teplates.Markdown != "" {
+		return e.configuration.Document.PDF.Teplates.Markdown
+	}
+
+	return ""
+}
+func (e *stateStruct) GetDocumentPDFOutputPath(arg string) string {
+	if arg != "" {
+		return arg
+	}
+
+	if e.configuration.Document.PDF.Output != "" {
+		return e.configuration.Document.PDF.Output
+	}
+
+	return ""
+}
diff --git a/application/source/environment/template.go b/application/source/environment/template.go
new file mode 100644
index 0000000000000000000000000000000000000000..5967d6ca3305705b8a89aebe57859e618ba1e104
--- /dev/null
+++ b/application/source/environment/template.go
@@ -0,0 +1,214 @@
+package environment
+
+import (
+	"os"
+	"path"
+	"path/filepath"
+	"regexp"
+	"strings"
+)
+
+func ReadTemplate(argPath string) string {
+
+	current, err := os.Getwd()
+	if err != nil {
+		ExitWithError(2, "The current directory cannot be read")
+	}
+
+	p := argPath
+
+	if !filepath.IsAbs(p) {
+		p = path.Clean(current + "/" + p)
+	}
+
+	template, err := os.ReadFile(p)
+	if err != nil {
+		ExitWithError(2, "The file %s cannot be read", p)
+	}
+
+	return convertTemplateImages(string(template), path.Dir(p))
+}
+
+func convertTemplateImages(content string, absolute string) string {
+	content = convertTemplateLogo(content, absolute)
+	content = convertTemplateLatexLogo(content, absolute)
+
+	return content
+
+}
+
+func convertTemplateLogo(content string, absolute string) string {
+	todoRegEx := regexp.MustCompile(`(?m)^(?P<match>logo:\s*"?(?P<path>[^"\n]*)"?\s*)$`)
+
+	matches := todoRegEx.FindAllStringSubmatch(content, -1)
+	if matches == nil {
+		return content
+	}
+
+	for _, match := range matches {
+		result := make(map[string]string)
+		for i, name := range todoRegEx.SubexpNames() {
+			if i != 0 && name != "" {
+				result[name] = match[i]
+			}
+		}
+
+		if filepath.IsAbs(result["path"]) {
+			continue
+		}
+
+		path := path.Clean(absolute + "/" + result["path"])
+		content = strings.Replace(content, result["match"], "logo: \""+path+"\"", -1)
+
+	}
+
+	return content
+}
+
+func convertTemplateLatexLogo(content string, absolute string) string {
+	todoRegEx := regexp.MustCompile(`(?m)(?P<match>\\includegraphics[^{]*\{(?P<path>[^}]*)\})`)
+
+	matches := todoRegEx.FindAllStringSubmatch(content, -1)
+	if matches == nil {
+		return content
+	}
+
+	for _, match := range matches {
+		result := make(map[string]string)
+		for i, name := range todoRegEx.SubexpNames() {
+			if i != 0 && name != "" {
+				result[name] = match[i]
+			}
+		}
+
+		if filepath.IsAbs(result["path"]) {
+			continue
+		}
+
+		path := path.Clean(absolute + "/" + result["path"])
+		a := strings.Replace(result["match"], result["path"], path, -1)
+
+		content = strings.Replace(content, result["match"], a, -1)
+
+	}
+
+	return content
+}
+
+/**
+
+func CreatePDF() error {
+
+	err, pageData := collectStructureFromFiles(config.Path)
+	if err != nil {
+		return err
+	}
+
+	d, err := getDataset(pageData, flagInitChangelog|flagInitTasks|flagInitDocuments)
+	if err != nil {
+		return err
+	}
+
+	outputName := arguments.Build.PDF.Output
+
+	if outputName == "" {
+		printErrorAndExit(2, "if the type is pdf, the output option must be specified")
+	}
+
+	file, err := ioutil.TempFile(os.TempDir(), "docman")
+	if err != nil {
+		printErrorAndExit(2, "A temporary file cannot be created", err.Error())
+	}
+	defer os.Remove(file.Name())
+
+	t, err := template.New("pdf").Parse(config.PDF.Template.Internal.MarkdownContent)
+	if err != nil {
+		return err
+	}
+
+	err = t.Execute(file, d)
+	if err != nil {
+		return err
+	}
+
+	createLuaFile()
+	runPandoc(file.Name(), outputName, config.PDF.Template.Latex)
+
+	if luaRawBlockFile != nil {
+		luaRawBlockFile.Close()
+	}
+
+	return nil
+
+}
+
+var luaRawBlockFile *os.File
+
+func createLuaFile() {
+	var err error
+
+	luaRawBlockFile, err = ioutil.TempFile(os.TempDir(), "lua-raw-block")
+	if err != nil {
+		printErrorAndExit(2, "A temporary file cannot be created", err.Error())
+	}
+
+	luaRawBlockFile.WriteString(`
+function RawBlock (raw)
+	return raw.format:match 'html'
+	and pandoc.read(raw.text, 'html').blocks
+	or raw
+end
+`)
+
+}
+
+func getAdjustedContent(absolute string) string {
+
+	content, err := os.ReadFile(absolute)
+	if err != nil {
+		printError("The file cannot be read", absolute)
+		return ""
+	}
+
+	err, def := splitYamlParts(content)
+	if err != nil {
+		printError(err.Error())
+		return ""
+	}
+
+	s := convertImages(def.text, path.Dir(absolute))
+
+	return s
+}
+
+func convertImages(content string, absolute string) string {
+
+	todoRegEx := regexp.MustCompile(`(?P<match>\!\[(?P<label>[^]]*)\]\((?P<path>[^)]*)\))`)
+
+	matches := todoRegEx.FindAllStringSubmatch(content, -1)
+	if matches == nil {
+		return content
+	}
+
+	for _, match := range matches {
+		result := make(map[string]string)
+		for i, name := range todoRegEx.SubexpNames() {
+			if i != 0 && name != "" {
+				result[name] = match[i]
+			}
+		}
+
+		if filepath.IsAbs(result["path"]) {
+			continue
+		}
+
+		path := path.Clean(absolute + "/" + result["path"])
+		content = strings.Replace(content, result["match"], "!["+result["label"]+"]("+path+")", -1)
+
+	}
+
+	return content
+}
+
+
+*/
diff --git a/application/source/go.mod b/application/source/go.mod
index 7f00a8b08b8cd6e066733f4a64b12c2ab5a44505..148a075a529cc249f95829e84abe0a0193b395eb 100644
--- a/application/source/go.mod
+++ b/application/source/go.mod
@@ -15,9 +15,10 @@ require (
 	github.com/go-chi/chi/v5 v5.0.7 // indirect
 	github.com/go-chi/docgen v1.2.0 // indirect
 	github.com/go-chi/httprate v0.5.3 // indirect
+	github.com/gomarkdown/markdown v0.0.0-20220627144906-e9a81102ebeb // indirect
 	github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
 	go.uber.org/atomic v1.9.0 // indirect
 	go.uber.org/multierr v1.8.0 // indirect
 	go.uber.org/zap v1.21.0 // indirect
-	golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e // indirect
+	golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d // indirect
 )
diff --git a/application/source/go.sum b/application/source/go.sum
index aef7b50f3a0f07fe6798495dcc4749bd192b6fa5..b5afc737c380636fa6e9203ec1a1e3bb88f395e5 100644
--- a/application/source/go.sum
+++ b/application/source/go.sum
@@ -11,6 +11,8 @@ github.com/go-chi/docgen v1.2.0/go.mod h1:G9W0G551cs2BFMSn/cnGwX+JBHEloAgo17MBhy
 github.com/go-chi/httprate v0.5.3 h1:5HPWb0N6ymIiuotMtCfOGpQKiKeqXVzMexHh1W1yXPc=
 github.com/go-chi/httprate v0.5.3/go.mod h1:kYR4lorHX3It9tTh4eTdHhcF2bzrYnCrRNlv5+IBm2M=
 github.com/go-chi/render v1.0.1/go.mod h1:pq4Rr7HbnsdaeHagklXub+p6Wd16Af5l9koip1OvJns=
+github.com/gomarkdown/markdown v0.0.0-20220627144906-e9a81102ebeb h1:5b/eFaSaKPFG9ygDBaPKkydKU5nFJYk08g9jPIVogMg=
+github.com/gomarkdown/markdown v0.0.0-20220627144906-e9a81102ebeb/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
 github.com/gookit/color v1.5.1 h1:Vjg2VEcdHpwq+oY63s/ksHrgJYCTo0bwWvmmYWdE9fQ=
 github.com/gookit/color v1.5.1/go.mod h1:wZFzea4X8qN6vHOSP2apMb4/+w/orMznEzYsIHPaqKM=
 github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
@@ -59,6 +61,8 @@ golang.org/x/sys v0.0.0-20220702020025-31831981b65f h1:xdsejrW/0Wf2diT5CPp3XmKUN
 golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e h1:CsOuNlbOuf0mzxJIefr6Q4uAUetRUwZE4qt7VfzP+xo=
 golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d h1:/m5NbqQelATgoSPVC2Z23sR4kVNokFwDDyWh/3rGY+I=
+golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
diff --git a/application/source/main.go b/application/source/main.go
index 729e4a37b3814f7ce68fdc7e69e1317af0e13e12..4b5205e4f19d1cfa1776674e640223cc2a721d42 100644
--- a/application/source/main.go
+++ b/application/source/main.go
@@ -2,6 +2,7 @@ package main
 
 import (
 	"gitlab.schukai.com/oss/utilities/documentation-manager/commands"
+	"gitlab.schukai.com/oss/utilities/documentation-manager/environment"
 )
 
 // Used when building per
@@ -18,13 +19,13 @@ func main() {
 
 	defer func() {
 		if r := recover(); r != nil &&
-			r != commands.ExitWithCodeSymbol {
+			r != environment.ExitWithCodeSymbol {
 			panic(r)
 		}
-		commands.Exit()
+		environment.Exit()
 	}()
 
-	commands.Execute(commands.InfoStruct{
+	commands.Execute(environment.InfoStruct{
 		Version:  version,
 		Build:    build,
 		Mnemonic: mnemonic,
diff --git a/application/source/translations/catalog.go b/application/source/translations/catalog.go
index 466ed33552173f1dd08b6dfa35cdd8a4fdd657ad..96f3554fd805490c3d3343102dd71ab3bc9a9dca 100644
--- a/application/source/translations/catalog.go
+++ b/application/source/translations/catalog.go
@@ -39,40 +39,53 @@ func init() {
 }
 
 var messageKeyToIndex = map[string]int{
-	"Adds a new document": 24,
-	"Error":               0,
-	"Functions for creating and editing documents": 22,
+	"A temporary file cannot be created":           40,
+	"Adds a new document":                          26,
+	"Build the documentation as PDF":               34,
+	"Builds the documentation":                     30,
+	"Command %s not found":                         3,
+	"Error":                                        0,
+	"Functions for creating and editing documents": 23,
 	"Info":                    2,
-	"No active command found": 18,
-	"Not permitted":           3,
-	"Prints the version and build information":                           28,
-	"This program can be used to create documentation for your project.": 19,
-	"This program can be used to create documentation for your project.\nIt can be used to create a new documentation project,\nadd new documentation to an existing project, or to generate\ndocumentation from a source code project.": 20,
-	"Unknown Error: %s": 17,
+	"No active command found": 19,
+	"Not permitted":           4,
+	"Prints the version and build information": 35,
+	"Server command":                       38,
+	"The current directory cannot be read": 41,
+	"The file %s cannot be read":           42,
+	"This program can be used to create documentation for your project.": 20,
+	"This program can be used to create documentation for your project.\nIt can be used to create a new documentation project,\nadd new documentation to an existing project, or to generate\ndocumentation from a source code project.": 21,
+	"Unknown Error: %s": 18,
 	"Warn":              1,
-	"base directory in which the documents are saved": 23,
-	"build: %s\n":                        30,
-	"duplicated flag":                    11,
-	"expected argument":                  5,
-	"file extension %s is not supported": 26,
-	"file names of the new documents, separated by spaces": 25,
-	"flag error unknown":      4,
-	"handler %s not found":    21,
-	"invalid choice":          14,
-	"invalid tag":             15,
-	"marshal":                 8,
-	"no argument for bool":    9,
-	"no document name given":  27,
-	"short name too long":     10,
-	"tag %s":                  12,
-	"unknown command":         13,
-	"unknown flag":            6,
-	"unknown group":           7,
-	"unrecognized error type": 16,
-	"version: %s\n":           29,
+	"base directory in which the documents are saved": 24,
+	"build: %s\n":                       37,
+	"date format for the creation date": 25,
+	"directory in which the finished documentation is to be written": 31,
+	"duplicated flag":                                         12,
+	"expected argument":                                       6,
+	"file extension %s is not supported":                      33,
+	"file names of the new documents, separated by spaces":    28,
+	"flag error unknown":                                      5,
+	"format of the finished documentation":                    32,
+	"handler %s not found":                                    22,
+	"if the type is pdf, the output option must be specified": 39,
+	"invalid choice":                                          15,
+	"invalid tag":                                             16,
+	"marshal":                                                 9,
+	"no argument for bool":                                    10,
+	"no document name given":                                  29,
+	"short name too long":                                     11,
+	"tag %s":                                                  13,
+	"template for the new document":                           27,
+	"unknown command":                                         14,
+	"unknown flag":                                            7,
+	"unknown group":                                           8,
+	"unrecognized error type":                                 17,
+	"version: %s\n":                                           36,
 }
 
-var deIndex = []uint32{ // 32 elements
+var deIndex = []uint32{ // 44 elements
+	// Entry 0 - 1F
 	0x00000000, 0x00000007, 0x0000000f, 0x00000014,
 	0x00000014, 0x00000014, 0x00000014, 0x00000014,
 	0x00000014, 0x00000014, 0x00000014, 0x00000014,
@@ -81,36 +94,53 @@ var deIndex = []uint32{ // 32 elements
 	0x00000014, 0x00000014, 0x00000014, 0x00000014,
 	0x00000014, 0x00000014, 0x00000014, 0x00000014,
 	0x00000014, 0x00000014, 0x00000014, 0x00000014,
-} // Size: 152 bytes
+	// Entry 20 - 3F
+	0x00000014, 0x00000014, 0x00000014, 0x00000014,
+	0x00000014, 0x00000014, 0x00000014, 0x00000014,
+	0x00000014, 0x00000014, 0x00000014, 0x00000014,
+} // Size: 200 bytes
 
 const deData string = "\x02Fehler\x02Warnung\x02Info"
 
-var enIndex = []uint32{ // 32 elements
+var enIndex = []uint32{ // 44 elements
+	// Entry 0 - 1F
 	0x00000000, 0x00000006, 0x0000000b, 0x00000010,
-	0x0000001e, 0x00000031, 0x00000043, 0x00000050,
-	0x0000005e, 0x00000066, 0x0000007b, 0x0000008f,
-	0x0000009f, 0x000000a9, 0x000000b9, 0x000000c8,
-	0x000000d4, 0x000000ec, 0x00000101, 0x00000119,
-	0x0000015c, 0x0000023c, 0x00000254, 0x00000281,
-	0x000002b1, 0x000002de, 0x00000313, 0x00000339,
-	0x00000350, 0x0000037d, 0x00000391, 0x000003a3,
-} // Size: 152 bytes
+	0x00000028, 0x00000036, 0x00000049, 0x0000005b,
+	0x00000068, 0x00000076, 0x0000007e, 0x00000093,
+	0x000000a7, 0x000000b7, 0x000000c1, 0x000000d1,
+	0x000000e0, 0x000000ec, 0x00000104, 0x00000119,
+	0x00000131, 0x00000174, 0x00000254, 0x0000026c,
+	0x00000299, 0x000002c9, 0x000002eb, 0x00000318,
+	0x00000336, 0x0000036b, 0x00000382, 0x000003af,
+	// Entry 20 - 3F
+	0x000003ee, 0x00000413, 0x00000439, 0x00000466,
+	0x00000493, 0x000004a7, 0x000004b9, 0x000004e6,
+	0x0000051e, 0x00000541, 0x00000566, 0x00000584,
+} // Size: 200 bytes
 
-const enData string = "" + // Size: 931 bytes
-	"\x02Error\x02Warn\x02Info\x02Not permitted\x02flag error unknown\x02expe" +
-	"cted argument\x02unknown flag\x02unknown group\x02marshal\x02no argument" +
-	" for bool\x02short name too long\x02duplicated flag\x02tag %[1]s\x02unkn" +
-	"own command\x02invalid choice\x02invalid tag\x02unrecognized error type" +
-	"\x02Unknown Error: %[1]s\x02No active command found\x02This program can " +
-	"be used to create documentation for your project.\x02This program can be" +
-	" used to create documentation for your project.\x0aIt can be used to cre" +
-	"ate a new documentation project,\x0aadd new documentation to an existing" +
-	" project, or to generate\x0adocumentation from a source code project." +
-	"\x02handler %[1]s not found\x02Functions for creating and editing docume" +
-	"nts\x02base directory in which the documents are saved\x02Functions for " +
-	"creating and editing documents\x02file names of the new documents, separ" +
-	"ated by spaces\x02file extension %[1]s is not supported\x02no document n" +
-	"ame given\x02Functions for creating and editing documents\x04\x00\x01" +
-	"\x0a\x0f\x02version: %[1]s\x04\x00\x01\x0a\x0d\x02build: %[1]s"
+const enData string = "" + // Size: 1412 bytes
+	"\x02Error\x02Warn\x02Info\x02Command %[1]s not found\x02Not permitted" +
+	"\x02flag error unknown\x02expected argument\x02unknown flag\x02unknown g" +
+	"roup\x02marshal\x02no argument for bool\x02short name too long\x02duplic" +
+	"ated flag\x02tag %[1]s\x02unknown command\x02invalid choice\x02invalid t" +
+	"ag\x02unrecognized error type\x02Unknown Error: %[1]s\x02No active comma" +
+	"nd found\x02This program can be used to create documentation for your pr" +
+	"oject.\x02This program can be used to create documentation for your proj" +
+	"ect.\x0aIt can be used to create a new documentation project,\x0aadd new" +
+	" documentation to an existing project, or to generate\x0adocumentation f" +
+	"rom a source code project.\x02handler %[1]s not found\x02Functions for c" +
+	"reating and editing documents\x02base directory in which the documents a" +
+	"re saved\x02date format for the creation date\x02Functions for creating " +
+	"and editing documents\x02template for the new document\x02file names of " +
+	"the new documents, separated by spaces\x02no document name given\x02Func" +
+	"tions for creating and editing documents\x02directory in which the finis" +
+	"hed documentation is to be written\x02format of the finished documentati" +
+	"on\x02file extension %[1]s is not supported\x02Functions for creating an" +
+	"d editing documents\x02Functions for creating and editing documents\x04" +
+	"\x00\x01\x0a\x0f\x02version: %[1]s\x04\x00\x01\x0a\x0d\x02build: %[1]s" +
+	"\x02Functions for creating and editing documents\x02if the type is pdf, " +
+	"the output option must be specified\x02A temporary file cannot be create" +
+	"d\x02The current directory cannot be read\x02The file %[1]s cannot be re" +
+	"ad"
 
-	// Total table size 1255 bytes (1KiB); checksum: 9B4E79C0
+	// Total table size 1832 bytes (1KiB); checksum: 75DC5101
diff --git a/application/source/translations/locales/de/out.gotext.json b/application/source/translations/locales/de/out.gotext.json
index 863850b2bcdf5803985c2f0d2f0750d05676069b..e8c216340bd5bacc7c2868b1bab5c7ddd6dc470a 100644
--- a/application/source/translations/locales/de/out.gotext.json
+++ b/application/source/translations/locales/de/out.gotext.json
@@ -1,6 +1,20 @@
 {
     "language": "de",
     "messages": [
+        {
+            "id": "Command {Arg_1} not found",
+            "message": "Command {Arg_1} not found",
+            "translation": "",
+            "placeholders": [
+                {
+                    "id": "Arg_1",
+                    "string": "%[1]s",
+                    "type": "",
+                    "underlyingType": "string",
+                    "argNum": 1
+                }
+            ]
+        },
         {
             "id": "Not permitted",
             "message": "Not permitted",
@@ -95,21 +109,6 @@
                 }
             ]
         },
-        {
-            "id": "Error",
-            "message": "Error",
-            "translation": "Fehler"
-        },
-        {
-            "id": "Warn",
-            "message": "Warn",
-            "translation": "Warnung"
-        },
-        {
-            "id": "Info",
-            "message": "Info",
-            "translation": "Info"
-        },
         {
             "id": "No active command found",
             "message": "No active command found",
@@ -152,11 +151,36 @@
             "message": "base directory in which the documents are saved",
             "translation": ""
         },
+        {
+            "id": "date format for the creation date",
+            "message": "date format for the creation date",
+            "translation": ""
+        },
+        {
+            "id": "template for the new document",
+            "message": "template for the new document",
+            "translation": ""
+        },
         {
             "id": "file names of the new documents, separated by spaces",
             "message": "file names of the new documents, separated by spaces",
             "translation": ""
         },
+        {
+            "id": "no document name given",
+            "message": "no document name given",
+            "translation": ""
+        },
+        {
+            "id": "directory in which the finished documentation is to be written",
+            "message": "directory in which the finished documentation is to be written",
+            "translation": ""
+        },
+        {
+            "id": "format of the finished documentation",
+            "message": "format of the finished documentation",
+            "translation": ""
+        },
         {
             "id": "file extension {Arg_1} is not supported",
             "message": "file extension {Arg_1} is not supported",
@@ -171,11 +195,6 @@
                 }
             ]
         },
-        {
-            "id": "no document name given",
-            "message": "no document name given",
-            "translation": ""
-        },
         {
             "id": "version: {Version}",
             "message": "version: {Version}",
@@ -187,7 +206,7 @@
                     "type": "string",
                     "underlyingType": "string",
                     "argNum": 1,
-                    "expr": "state.info.Version"
+                    "expr": "environment.State.GetVersion()"
                 }
             ]
         },
@@ -202,7 +221,51 @@
                     "type": "string",
                     "underlyingType": "string",
                     "argNum": 1,
-                    "expr": "state.info.Build"
+                    "expr": "environment.State.GetBuild()"
+                }
+            ]
+        },
+        {
+            "id": "if the type is pdf, the output option must be specified",
+            "message": "if the type is pdf, the output option must be specified",
+            "translation": ""
+        },
+        {
+            "id": "A temporary file cannot be created",
+            "message": "A temporary file cannot be created",
+            "translation": ""
+        },
+        {
+            "id": "Error",
+            "message": "Error",
+            "translation": "Fehler"
+        },
+        {
+            "id": "Warn",
+            "message": "Warn",
+            "translation": "Warnung"
+        },
+        {
+            "id": "Info",
+            "message": "Info",
+            "translation": "Info"
+        },
+        {
+            "id": "The current directory cannot be read",
+            "message": "The current directory cannot be read",
+            "translation": ""
+        },
+        {
+            "id": "The file {Arg_1} cannot be read",
+            "message": "The file {Arg_1} cannot be read",
+            "translation": "",
+            "placeholders": [
+                {
+                    "id": "Arg_1",
+                    "string": "%[1]s",
+                    "type": "",
+                    "underlyingType": "string",
+                    "argNum": 1
                 }
             ]
         }
diff --git a/application/source/translations/locales/en/out.gotext.json b/application/source/translations/locales/en/out.gotext.json
index 58f01296c683ee33e64356fcccb1b052abe37cfb..2b5c0d29239935e34d92aaa1990929ab4dd78c27 100644
--- a/application/source/translations/locales/en/out.gotext.json
+++ b/application/source/translations/locales/en/out.gotext.json
@@ -1,6 +1,22 @@
 {
     "language": "en",
     "messages": [
+        {
+            "id": "Command {Arg_1} not found",
+            "message": "Command {Arg_1} not found",
+            "translation": "Command {Arg_1} not found",
+            "translatorComment": "Copied from source.",
+            "placeholders": [
+                {
+                    "id": "Arg_1",
+                    "string": "%[1]s",
+                    "type": "",
+                    "underlyingType": "string",
+                    "argNum": 1
+                }
+            ],
+            "fuzzy": true
+        },
         {
             "id": "Not permitted",
             "message": "Not permitted",
@@ -125,27 +141,6 @@
             ],
             "fuzzy": true
         },
-        {
-            "id": "Error",
-            "message": "Error",
-            "translation": "Error",
-            "translatorComment": "Copied from source.",
-            "fuzzy": true
-        },
-        {
-            "id": "Warn",
-            "message": "Warn",
-            "translation": "Warn",
-            "translatorComment": "Copied from source.",
-            "fuzzy": true
-        },
-        {
-            "id": "Info",
-            "message": "Info",
-            "translation": "Info",
-            "translatorComment": "Copied from source.",
-            "fuzzy": true
-        },
         {
             "id": "No active command found",
             "message": "No active command found",
@@ -200,6 +195,20 @@
             "translatorComment": "Copied from source.",
             "fuzzy": true
         },
+        {
+            "id": "date format for the creation date",
+            "message": "date format for the creation date",
+            "translation": "date format for the creation date",
+            "translatorComment": "Copied from source.",
+            "fuzzy": true
+        },
+        {
+            "id": "template for the new document",
+            "message": "template for the new document",
+            "translation": "template for the new document",
+            "translatorComment": "Copied from source.",
+            "fuzzy": true
+        },
         {
             "id": "file names of the new documents, separated by spaces",
             "message": "file names of the new documents, separated by spaces",
@@ -207,6 +216,27 @@
             "translatorComment": "Copied from source.",
             "fuzzy": true
         },
+        {
+            "id": "no document name given",
+            "message": "no document name given",
+            "translation": "no document name given",
+            "translatorComment": "Copied from source.",
+            "fuzzy": true
+        },
+        {
+            "id": "directory in which the finished documentation is to be written",
+            "message": "directory in which the finished documentation is to be written",
+            "translation": "directory in which the finished documentation is to be written",
+            "translatorComment": "Copied from source.",
+            "fuzzy": true
+        },
+        {
+            "id": "format of the finished documentation",
+            "message": "format of the finished documentation",
+            "translation": "format of the finished documentation",
+            "translatorComment": "Copied from source.",
+            "fuzzy": true
+        },
         {
             "id": "file extension {Arg_1} is not supported",
             "message": "file extension {Arg_1} is not supported",
@@ -223,13 +253,6 @@
             ],
             "fuzzy": true
         },
-        {
-            "id": "no document name given",
-            "message": "no document name given",
-            "translation": "no document name given",
-            "translatorComment": "Copied from source.",
-            "fuzzy": true
-        },
         {
             "id": "version: {Version}",
             "message": "version: {Version}",
@@ -242,7 +265,7 @@
                     "type": "string",
                     "underlyingType": "string",
                     "argNum": 1,
-                    "expr": "state.info.Version"
+                    "expr": "environment.State.GetVersion()"
                 }
             ],
             "fuzzy": true
@@ -259,7 +282,65 @@
                     "type": "string",
                     "underlyingType": "string",
                     "argNum": 1,
-                    "expr": "state.info.Build"
+                    "expr": "environment.State.GetBuild()"
+                }
+            ],
+            "fuzzy": true
+        },
+        {
+            "id": "if the type is pdf, the output option must be specified",
+            "message": "if the type is pdf, the output option must be specified",
+            "translation": "if the type is pdf, the output option must be specified",
+            "translatorComment": "Copied from source.",
+            "fuzzy": true
+        },
+        {
+            "id": "A temporary file cannot be created",
+            "message": "A temporary file cannot be created",
+            "translation": "A temporary file cannot be created",
+            "translatorComment": "Copied from source.",
+            "fuzzy": true
+        },
+        {
+            "id": "Error",
+            "message": "Error",
+            "translation": "Error",
+            "translatorComment": "Copied from source.",
+            "fuzzy": true
+        },
+        {
+            "id": "Warn",
+            "message": "Warn",
+            "translation": "Warn",
+            "translatorComment": "Copied from source.",
+            "fuzzy": true
+        },
+        {
+            "id": "Info",
+            "message": "Info",
+            "translation": "Info",
+            "translatorComment": "Copied from source.",
+            "fuzzy": true
+        },
+        {
+            "id": "The current directory cannot be read",
+            "message": "The current directory cannot be read",
+            "translation": "The current directory cannot be read",
+            "translatorComment": "Copied from source.",
+            "fuzzy": true
+        },
+        {
+            "id": "The file {Arg_1} cannot be read",
+            "message": "The file {Arg_1} cannot be read",
+            "translation": "The file {Arg_1} cannot be read",
+            "translatorComment": "Copied from source.",
+            "placeholders": [
+                {
+                    "id": "Arg_1",
+                    "string": "%[1]s",
+                    "type": "",
+                    "underlyingType": "string",
+                    "argNum": 1
                 }
             ],
             "fuzzy": true
diff --git a/development/examples/example1/config.yaml b/development/examples/example1/config.yaml
index f7d33d4e6a5ed6d37926c17a185d7556be828702..b9f02061f504b303ce19f3fb6cd2a6a4ee33cf4f 100644
--- a/development/examples/example1/config.yaml
+++ b/development/examples/example1/config.yaml
@@ -1,3 +1,29 @@
 Document:
   Path: /home/volker.schukai/projekte/gitlab/oss/utilities/documentation-manager/development/examples/example2
   DateFormat: 02.01.2006
+ 
+  PDF:
+    Output: /home/volker.schukai/projekte/gitlab/oss/utilities/documentation-manager/development/examples/example1/out/my.pdf
+    Templates:
+      Latex: /home/volker.schukai/projekte/gitlab/oss/utilities/documentation-manager/development/examples/example1/templates/my.latex
+      Markdown: /home/volker.schukai/projekte/gitlab/oss/utilities/documentation-manager/development/examples/example1/templates/my.md
+  
+  
+  
+#  Document struct {
+#  Path       string `yaml:"Path" envconfig:"PATH"`
+#  DateFormat string `yaml:"DateFormat" envconfig:"DATE_FORMAT"`
+#  Add        struct {
+#  Template string `yaml:"Template" envconfig:"NEW_TEMPLATE"`
+#}
+#  Build struct {
+#  //Path string `yaml:"Path" envconfig:"BUILD_PATH"`
+#} `yaml:"Build"`
+#  PDF struct {
+#  Output   string `yaml:"Output" envconfig:"PDF_OUTPUT"`
+#  Teplates struct {
+#  Latex    string `yaml:"Latex" envconfig:"PDF_LATEX_TEMPLATE"`
+#  Markdown string `yaml:"Markdown" envconfig:"PDF_MARKDOWN_TEMPLATE"`
+#  } `yaml:"Templates"`
+#} `yaml:"PDF"`
+#} `yaml:"Document"`
\ No newline at end of file
diff --git a/development/examples/example1/doc.pdf b/development/examples/example1/doc.pdf
deleted file mode 100644
index 8ad413ac277a4914b5ee448a41c55a20194435cb..0000000000000000000000000000000000000000
Binary files a/development/examples/example1/doc.pdf and /dev/null differ
diff --git a/development/examples/example1/missfont.log b/development/examples/example1/missfont.log
new file mode 100644
index 0000000000000000000000000000000000000000..f182ee4f0128d666a6a0563f72bc580d39f2a0c2
--- /dev/null
+++ b/development/examples/example1/missfont.log
@@ -0,0 +1,15 @@
+mktextfm QTVagaRound
+mktextfm QTVagaRound
+mktextfm QTVagaRound
+mktextfm QTVagaRound
+mktextfm QTVagaRound
+mktextfm QTVagaRound
+mktextfm QTVagaRound
+mktextfm QTVagaRound
+mktextfm QTVagaRound
+mktextfm VagaRound
+mktextfm VagaRound
+mktextfm VagaRound
+mktextfm QTVagaRound
+mktextfm QTVagaRound
+mktextfm QTVagaRound
diff --git a/development/examples/example1/out/my-1_1.png b/development/examples/example1/out/my-1_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..44e7fcb7a5310bd4bce975808fcb71acd4341773
Binary files /dev/null and b/development/examples/example1/out/my-1_1.png differ
diff --git a/development/examples/example1/out/my-3_1.png b/development/examples/example1/out/my-3_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..61107a89f7fc3914d66d3a8c594b27369db5311e
Binary files /dev/null and b/development/examples/example1/out/my-3_1.png differ
diff --git a/development/examples/example1/out/my.html b/development/examples/example1/out/my.html
new file mode 100644
index 0000000000000000000000000000000000000000..9b40d8310db393d976d23fc91e8e083928984215
--- /dev/null
+++ b/development/examples/example1/out/my.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Allgemeine Vertragsbedingungen zur Auftragsverarbeitung</title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+<meta name="generator" content="pdftohtml 0.36"/>
+<meta name="keywords" content="Auftragsverarbeitung, DSGVO, shopcloud"/>
+<meta name="date" content="2022-07-08T13:14:54+00:00"/>
+</head>
+<frameset cols="100,*">
+<frame name="links" src="my_ind.html"/>
+<frame name="contents" src="mys.html"/>
+</frameset>
+</html>
diff --git a/development/examples/example1/out/my.pdf b/development/examples/example1/out/my.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..68296146c964b9293e9a9e8d2642e976bbb06591
Binary files /dev/null and b/development/examples/example1/out/my.pdf differ
diff --git a/development/examples/example1/out/my_ind.html b/development/examples/example1/out/my_ind.html
new file mode 100644
index 0000000000000000000000000000000000000000..edfd51ddf5c44a2418e8cb6237b097c16b77abfe
--- /dev/null
+++ b/development/examples/example1/out/my_ind.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
+<head>
+<title></title>
+</head>
+<body>
+<a href="mys.html#outline" target="contents">Outline</a><br/><a href="mys.html#1" target="contents" >Page 1</a><br/>
+<a href="mys.html#2" target="contents" >Page 2</a><br/>
+<a href="mys.html#3" target="contents" >Page 3</a><br/>
+</body>
+</html>
diff --git a/development/examples/example1/out/mys.html b/development/examples/example1/out/mys.html
new file mode 100644
index 0000000000000000000000000000000000000000..476ef41d812e091e1802a9632d342d5823d3915e
--- /dev/null
+++ b/development/examples/example1/out/mys.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html><html>
+<head>
+<title></title>
+<style type="text/css">
+<!--
+.xflip {
+    -moz-transform: scaleX(-1);
+    -webkit-transform: scaleX(-1);
+    -o-transform: scaleX(-1);
+    transform: scaleX(-1);
+    filter: fliph;
+}
+.yflip {
+    -moz-transform: scaleY(-1);
+    -webkit-transform: scaleY(-1);
+    -o-transform: scaleY(-1);
+    transform: scaleY(-1);
+    filter: flipv;
+}
+.xyflip {
+    -moz-transform: scaleX(-1) scaleY(-1);
+    -webkit-transform: scaleX(-1) scaleY(-1);
+    -o-transform: scaleX(-1) scaleY(-1);
+    transform: scaleX(-1) scaleY(-1);
+    filter: fliph + flipv;
+}
+-->
+</style>
+</head>
+<body>
+<a name=1></a><img src="my-1_1.png"/><br/>
+<b>Allgemeine</b><br/>
+<b>Vertragsbedingungen&#160;zur</b><br/>
+<b>Auftragsverarbeitung</b><br/>
+nach&#160;Art.&#160;28&#160;DSGVO&#160;durch&#160;die&#160;schukai&#160;GmbH,<br/>Eichenstraße&#160;26,&#160;82290&#160;Landsberied&#160;im<br/>Rahmen&#160;der&#160;Nutzung&#160;der&#160;shopcloud<br/>
+6.&#160;Juni&#160;2022<br/>
+<hr/>
+<a name=2></a>Allgemeine&#160;Vertragsbedingungen&#160;zur&#160;Auftragsverarbeitung<br/>
+6.&#160;Juni&#160;2022<br/>
+<b>Inhaltsverzeichnis</b><br/>
+<a href="mys.html#3">0.1</a><br/>
+<a href="mys.html#3">New&#160;Document&#160;</a>.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.<br/>
+3<br/>
+<a href="mys.html#3">0.2</a><br/>
+<a href="mys.html#3">New&#160;Document&#160;</a>.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.<br/>
+3<br/>
+<a href="mys.html#3">0.3</a><br/>
+<a href="mys.html#3">New&#160;Document&#160;</a>.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.&#160;.<br/>
+3<br/>
+Vertraulich<br/>
+2<br/>
+<hr/>
+<a name=3></a><img src="my-3_1.png"/><br/>
+Allgemeine&#160;Vertragsbedingungen&#160;zur&#160;Auftragsverarbeitung<br/>
+6.&#160;Juni&#160;2022<br/>
+<b>0.1&#160;New&#160;Document</b><br/>
+Lorem&#160;ipsum&#160;dolor&#160;sit&#160;amet,&#160;consectetur&#160;adipiscing&#160;elit.<br/>
+Das&#160;ist&#160;ein&#160;Tuxa<br/>
+❹<br/>
+Strg+Alt+F9<br/>
+↑<br/>
+das&#160;ist&#160;ein&#160;test&#160;❶für&#160;⓯und&#160;!<br/>❶❷❸❹❺❻❼❽❾❿‼‼&#160;⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴⁇?<br/>
+IMG&#160;END<br/>
+<b>0.2&#160;New&#160;Document</b><br/>
+Lorem&#160;ipsum&#160;dolor&#160;sit&#160;amet,&#160;consectetur&#160;adipiscing&#160;elit.<br/>
+DOC&#160;2<br/>
+<b>0.3&#160;New&#160;Document</b><br/>
+Lorem&#160;ipsum&#160;dolor&#160;sit&#160;amet,&#160;consectetur&#160;adipiscing&#160;elit.<br/>
+DOC&#160;3<br/>
+Vertraulich<br/>
+3<br/>
+<hr/>
+<a name="outline"></a><h1>Document Outline</h1>
+<ul>
+<li><a href="mys.html#3">New Document</a></li>
+<li><a href="mys.html#3">New Document</a></li>
+<li><a href="mys.html#3">New Document</a></li>
+</ul>
+<hr/>
+</body>
+</html>
diff --git a/development/examples/example1/templates/my.latex b/development/examples/example1/templates/my.latex
new file mode 100644
index 0000000000000000000000000000000000000000..e79c80882ce8a18d0f5ff9ad7a341b03faadd845
--- /dev/null
+++ b/development/examples/example1/templates/my.latex
@@ -0,0 +1,1074 @@
+%%
+% Copyright (c) 2017 - 2021, Pascal Wagler;
+% Copyright (c) 2014 - 2021, John MacFarlane
+%
+% All rights reserved.
+%
+% Redistribution and use in source and binary forms, with or without
+% modification, are permitted provided that the following conditions
+% are met:
+%
+% - Redistributions of source code must retain the above copyright
+% notice, this list of conditions and the following disclaimer.
+%
+% - Redistributions in binary form must reproduce the above copyright
+% notice, this list of conditions and the following disclaimer in the
+% documentation and/or other materials provided with the distribution.
+%
+% - Neither the name of John MacFarlane nor the names of other
+% contributors may be used to endorse or promote products derived
+% from this software without specific prior written permission.
+%
+% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+% "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+% LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+% FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+% COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+% INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+% BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+% LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+% CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+% LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+% ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+% POSSIBILITY OF SUCH DAMAGE.
+%%
+
+%%
+% This is the Eisvogel pandoc LaTeX template.
+%
+% For usage information and examples visit the official GitHub page:
+% https://github.com/Wandmalfarbe/pandoc-latex-template
+%%
+
+% Options for packages loaded elsewhere
+\PassOptionsToPackage{unicode$for(hyperrefoptions)$,$hyperrefoptions$$endfor$}{hyperref}
+\PassOptionsToPackage{hyphens}{url}
+\PassOptionsToPackage{dvipsnames,svgnames*,x11names*,table}{xcolor}
+$if(dir)$
+$if(latex-dir-rtl)$
+\PassOptionsToPackage{RTLdocument}{bidi}
+$endif$
+$endif$
+$if(CJKmainfont)$
+\PassOptionsToPackage{space}{xeCJK}
+$endif$
+%
+\documentclass[
+$if(fontsize)$
+  $fontsize$,
+$endif$
+$if(lang)$
+  $babel-lang$,
+$endif$
+$if(papersize)$
+  $papersize$paper,
+$else$
+  paper=a4,
+$endif$
+$if(beamer)$
+  ignorenonframetext,
+$if(handout)$
+  handout,
+$endif$
+$if(aspectratio)$
+  aspectratio=$aspectratio$,
+$endif$
+$endif$
+$for(classoption)$
+  $classoption$$sep$,
+$endfor$
+  ,captions=tableheading
+]{$if(beamer)$$documentclass$$else$$if(book)$scrbook$else$scrartcl$endif$$endif$}
+$if(beamer)$
+$if(background-image)$
+\usebackgroundtemplate{%
+  \includegraphics[width=\paperwidth]{$background-image$}%
+}
+$endif$
+\usepackage{pgfpages}
+\usepackage{ngerman}
+\setbeamertemplate{caption}[numbered]
+\setbeamertemplate{caption label separator}{: }
+\setbeamercolor{caption name}{fg=normal text.fg}
+\beamertemplatenavigationsymbols$if(navigation)$$navigation$$else$empty$endif$
+$for(beameroption)$
+\setbeameroption{$beameroption$}
+$endfor$
+% Prevent slide breaks in the middle of a paragraph
+\widowpenalties 1 10000
+\raggedbottom
+$if(section-titles)$
+\setbeamertemplate{part page}{
+  \centering
+  \begin{beamercolorbox}[sep=16pt,center]{part title}
+    \usebeamerfont{part title}\insertpart\par
+  \end{beamercolorbox}
+}
+\setbeamertemplate{section page}{
+  \centering
+  \begin{beamercolorbox}[sep=12pt,center]{part title}
+    \usebeamerfont{section title}\insertsection\par
+  \end{beamercolorbox}
+}
+\setbeamertemplate{subsection page}{
+  \centering
+  \begin{beamercolorbox}[sep=8pt,center]{part title}
+    \usebeamerfont{subsection title}\insertsubsection\par
+  \end{beamercolorbox}
+}
+\AtBeginPart{
+  \frame{\partpage}
+}
+\AtBeginSection{
+  \ifbibliography
+  \else
+    \frame{\sectionpage}
+  \fi
+}
+\AtBeginSubsection{
+  \frame{\subsectionpage}
+}
+$endif$
+$endif$
+$if(beamerarticle)$
+\usepackage{beamerarticle} % needs to be loaded first
+$endif$
+\usepackage{amsmath,amssymb}
+$if(fontfamily)$
+\usepackage[$for(fontfamilyoptions)$$fontfamilyoptions$$sep$,$endfor$]{$fontfamily$}
+$else$
+\usepackage{lmodern}
+$endif$
+$if(linestretch)$
+\usepackage{setspace}
+$else$
+\usepackage{setspace}
+\setstretch{1.2}
+$endif$
+\usepackage{ifxetex,ifluatex}
+\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
+  \usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc}
+  \usepackage[utf8]{inputenc}
+  \usepackage{textcomp} % provide euro and other symbols
+\else % if luatex or xetex
+$if(mathspec)$
+  \ifxetex
+    \usepackage{mathspec}
+  \else
+    \usepackage{unicode-math}
+  \fi
+$else$
+  \usepackage{unicode-math}
+$endif$
+  \defaultfontfeatures{Scale=MatchLowercase}
+  \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}
+$if(mainfont)$
+  \setmainfont[$for(mainfontoptions)$$mainfontoptions$$sep$,$endfor$]{$mainfont$}
+$endif$
+$if(sansfont)$
+  \setsansfont[$for(sansfontoptions)$$sansfontoptions$$sep$,$endfor$]{$sansfont$}
+$endif$
+$if(monofont)$
+  \setmonofont[$for(monofontoptions)$$monofontoptions$$sep$,$endfor$]{$monofont$}
+$endif$
+$for(fontfamilies)$
+  \newfontfamily{$fontfamilies.name$}[$for(fontfamilies.options)$$fontfamilies.options$$sep$,$endfor$]{$fontfamilies.font$}
+$endfor$
+$if(mathfont)$
+$if(mathspec)$
+  \ifxetex
+    \setmathfont(Digits,Latin,Greek)[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$}
+  \else
+    \setmathfont[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$}
+  \fi
+$else$
+  \setmathfont[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$}
+$endif$
+$endif$
+$if(CJKmainfont)$
+  \ifxetex
+    \usepackage{xeCJK}
+    \setCJKmainfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$}
+  \fi
+$endif$
+$if(luatexjapresetoptions)$
+  \ifluatex
+    \usepackage[$for(luatexjapresetoptions)$$luatexjapresetoptions$$sep$,$endfor$]{luatexja-preset}
+  \fi
+$endif$
+$if(CJKmainfont)$
+  \ifluatex
+    \usepackage[$for(luatexjafontspecoptions)$$luatexjafontspecoptions$$sep$,$endfor$]{luatexja-fontspec}
+    \setmainjfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$}
+  \fi
+$endif$
+\fi
+$if(beamer)$
+$if(theme)$
+\usetheme[$for(themeoptions)$$themeoptions$$sep$,$endfor$]{$theme$}
+$endif$
+$if(colortheme)$
+\usecolortheme{$colortheme$}
+$endif$
+$if(fonttheme)$
+\usefonttheme{$fonttheme$}
+$endif$
+$if(mainfont)$
+\usefonttheme{serif} % use mainfont rather than sansfont for slide text
+$endif$
+$if(innertheme)$
+\useinnertheme{$innertheme$}
+$endif$
+$if(outertheme)$
+\useoutertheme{$outertheme$}
+$endif$
+$endif$
+% Use upquote if available, for straight quotes in verbatim environments
+\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
+\IfFileExists{microtype.sty}{% use microtype if available
+  \usepackage[$for(microtypeoptions)$$microtypeoptions$$sep$,$endfor$]{microtype}
+  \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts
+}{}
+$if(indent)$
+$else$
+\makeatletter
+\@ifundefined{KOMAClassName}{% if non-KOMA class
+  \IfFileExists{parskip.sty}{%
+    \usepackage{parskip}
+  }{% else
+    \setlength{\parindent}{0pt}
+    \setlength{\parskip}{6pt plus 2pt minus 1pt}}
+}{% if KOMA class
+  \KOMAoptions{parskip=half}}
+\makeatother
+$endif$
+$if(verbatim-in-note)$
+\usepackage{fancyvrb}
+$endif$
+\usepackage{xcolor}
+\definecolor{default-linkcolor}{HTML}{A50000}
+\definecolor{default-filecolor}{HTML}{A50000}
+\definecolor{default-citecolor}{HTML}{4077C0}
+\definecolor{default-urlcolor}{HTML}{4077C0}
+\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available
+$if(footnotes-pretty)$
+% load footmisc in order to customize footnotes (footmisc has to be loaded before hyperref, cf. https://tex.stackexchange.com/a/169124/144087)
+\usepackage[hang,flushmargin,bottom,multiple]{footmisc}
+\setlength{\footnotemargin}{0.8em} % set space between footnote nr and text
+\setlength{\footnotesep}{\baselineskip} % set space between multiple footnotes
+\setlength{\skip\footins}{0.3cm} % set space between page content and footnote
+\setlength{\footskip}{0.9cm} % set space between footnote and page bottom
+$endif$
+\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}}
+\hypersetup{
+$if(title-meta)$
+  pdftitle={$title-meta$},
+$endif$
+$if(author-meta)$
+  pdfauthor={$author-meta$},
+$endif$
+$if(lang)$
+  pdflang={$lang$},
+$endif$
+$if(subject)$
+  pdfsubject={$subject$},
+$endif$
+$if(keywords)$
+  pdfkeywords={$for(keywords)$$keywords$$sep$, $endfor$},
+$endif$
+$if(colorlinks)$
+  colorlinks=true,
+  linkcolor=$if(linkcolor)$$linkcolor$$else$default-linkcolor$endif$,
+  filecolor=$if(filecolor)$$filecolor$$else$default-filecolor$endif$,
+  citecolor=$if(citecolor)$$citecolor$$else$default-citecolor$endif$,
+  urlcolor=$if(urlcolor)$$urlcolor$$else$default-urlcolor$endif$,
+$else$
+  hidelinks,
+$endif$
+  breaklinks=true,
+  pdfcreator={reqman PDF export; LaTeX via pandoc with the Eisvogel template}}
+\urlstyle{same} % disable monospaced font for URLs
+$if(verbatim-in-note)$
+\VerbatimFootnotes % allow verbatim text in footnotes
+$endif$
+$if(geometry)$
+$if(beamer)$
+\geometry{$for(geometry)$$geometry$$sep$,$endfor$}
+$else$
+\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry}
+$endif$
+$else$
+$if(beamer)$
+$else$
+\usepackage[margin=2.5cm,includehead=true,includefoot=true,centering,$for(geometry)$$geometry$$sep$,$endfor$]{geometry}
+$endif$
+$endif$
+$if(logo)$
+\usepackage[export]{adjustbox}
+\usepackage{graphicx}
+$endif$
+$if(beamer)$
+\newif\ifbibliography
+$endif$
+$if(listings)$
+\usepackage{listings}
+\newcommand{\passthrough}[1]{#1}
+\lstset{defaultdialect=[5.3]Lua}
+\lstset{defaultdialect=[x86masm]Assembler}
+$endif$
+$if(listings-no-page-break)$
+\usepackage{etoolbox}
+\BeforeBeginEnvironment{lstlisting}{\par\noindent\begin{minipage}{\linewidth}}
+\AfterEndEnvironment{lstlisting}{\end{minipage}\par\addvspace{\topskip}}
+$endif$
+$if(lhs)$
+\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}
+$endif$
+$if(highlighting-macros)$
+$highlighting-macros$
+
+% Workaround/bugfix from jannick0.
+% See https://github.com/jgm/pandoc/issues/4302#issuecomment-360669013)
+% or https://github.com/Wandmalfarbe/pandoc-latex-template/issues/2
+%
+% Redefine the verbatim environment 'Highlighting' to break long lines (with
+% the help of fvextra). Redefinition is necessary because it is unlikely that
+% pandoc includes fvextra in the default template.
+\usepackage{fvextra}
+\DefineVerbatimEnvironment{Highlighting}{Verbatim}{breaklines,fontsize=$if(code-block-font-size)$$code-block-font-size$$else$\small$endif$,commandchars=\\\{\}}
+
+$endif$
+$if(tables)$
+\usepackage{longtable,booktabs,array}
+$if(multirow)$
+\usepackage{multirow}
+$endif$
+\usepackage{calc} % for calculating minipage widths
+$if(beamer)$
+\usepackage{caption}
+% Make caption package work with longtable
+\makeatletter
+\def\fnum@table{\tablename~\thetable}
+\makeatother
+$else$
+% Correct order of tables after \paragraph or \subparagraph
+\usepackage{etoolbox}
+\makeatletter
+\patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{}
+\makeatother
+% Allow footnotes in longtable head/foot
+\IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}}
+\makesavenoteenv{longtable}
+$endif$
+$endif$
+% add backlinks to footnote references, cf. https://tex.stackexchange.com/questions/302266/make-footnote-clickable-both-ways
+$if(footnotes-disable-backlinks)$
+$else$
+\usepackage{footnotebackref}
+$endif$
+$if(graphics)$
+\usepackage{graphicx}
+\makeatletter
+\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi}
+\def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi}
+\makeatother
+% Scale images if necessary, so that they will not overflow the page
+% margins by default, and it is still possible to overwrite the defaults
+% using explicit options in \includegraphics[width, height, ...]{}
+\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio}
+% Set default figure placement to htbp
+\makeatletter
+\def\fps@figure{htbp}
+\makeatother
+$endif$
+$if(links-as-notes)$
+% Make links footnotes instead of hotlinks:
+\DeclareRobustCommand{\href}[2]{#2\footnote{\url{#1}}}
+$endif$
+$if(strikeout)$
+\usepackage[normalem]{ulem}
+% Avoid problems with \sout in headers with hyperref
+\pdfstringdefDisableCommands{\renewcommand{\sout}{}}
+$endif$
+\setlength{\emergencystretch}{3em} % prevent overfull lines
+\providecommand{\tightlist}{%
+  \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
+$if(numbersections)$
+\setcounter{secnumdepth}{$if(secnumdepth)$$secnumdepth$$else$5$endif$}
+$else$
+\setcounter{secnumdepth}{-\maxdimen} % remove section numbering
+$endif$
+$if(beamer)$
+$else$
+$if(block-headings)$
+% Make \paragraph and \subparagraph free-standing
+\ifx\paragraph\undefined\else
+  \let\oldparagraph\paragraph
+  \renewcommand{\paragraph}[1]{\oldparagraph{#1}\mbox{}}
+\fi
+\ifx\subparagraph\undefined\else
+  \let\oldsubparagraph\subparagraph
+  \renewcommand{\subparagraph}[1]{\oldsubparagraph{#1}\mbox{}}
+\fi
+$endif$
+$endif$
+$if(pagestyle)$
+\pagestyle{$pagestyle$}
+$endif$
+
+% Make use of float-package and set default placement for figures to H.
+% The option H means 'PUT IT HERE' (as  opposed to the standard h option which means 'You may put it here if you like').
+\usepackage{float}
+\floatplacement{figure}{$if(float-placement-figure)$$float-placement-figure$$else$H$endif$}
+
+$for(header-includes)$
+$header-includes$
+$endfor$
+$if(lang)$
+\ifxetex
+  $if(mainfont)$
+  $else$
+  % See issue https://github.com/reutenauer/polyglossia/issues/127
+  \renewcommand*\familydefault{\sfdefault}
+  $endif$
+  % Load polyglossia as late as possible: uses bidi with RTL langages (e.g. Hebrew, Arabic)
+  \usepackage{polyglossia}
+  \setmainlanguage[$for(polyglossia-lang.options)$$polyglossia-lang.options$$sep$,$endfor$]{$polyglossia-lang.name$}
+$for(polyglossia-otherlangs)$
+  \setotherlanguage[$for(polyglossia-otherlangs.options)$$polyglossia-otherlangs.options$$sep$,$endfor$]{$polyglossia-otherlangs.name$}
+$endfor$
+\else
+  \usepackage[$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=$babel-lang$]{babel}
+% get rid of language-specific shorthands (see #6817):
+\let\LanguageShortHands\languageshorthands
+\def\languageshorthands#1{}
+$if(babel-newcommands)$
+  $babel-newcommands$
+$endif$
+\fi
+$endif$
+\ifluatex
+  \usepackage{selnolig}  % disable illegal ligatures
+\fi
+$if(dir)$
+\ifxetex
+  % Load bidi as late as possible as it modifies e.g. graphicx
+  \usepackage{bidi}
+\fi
+\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
+  \TeXXeTstate=1
+  \newcommand{\RL}[1]{\beginR #1\endR}
+  \newcommand{\LR}[1]{\beginL #1\endL}
+  \newenvironment{RTL}{\beginR}{\endR}
+  \newenvironment{LTR}{\beginL}{\endL}
+\fi
+$endif$
+$if(natbib)$
+\usepackage[$natbiboptions$]{natbib}
+\bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$}
+$endif$
+$if(biblatex)$
+\usepackage[$if(biblio-style)$style=$biblio-style$,$endif$$for(biblatexoptions)$$biblatexoptions$$sep$,$endfor$]{biblatex}
+$for(bibliography)$
+\addbibresource{$bibliography$}
+$endfor$
+$endif$
+$if(csl-refs)$
+\newlength{\cslhangindent}
+\setlength{\cslhangindent}{1.5em}
+\newlength{\csllabelwidth}
+\setlength{\csllabelwidth}{3em}
+\newenvironment{CSLReferences}[2] % #1 hanging-ident, #2 entry spacing
+ {% don't indent paragraphs
+  \setlength{\parindent}{0pt}
+  % turn on hanging indent if param 1 is 1
+  \ifodd #1 \everypar{\setlength{\hangindent}{\cslhangindent}}\ignorespaces\fi
+  % set entry spacing
+  \ifnum #2 > 0
+  \setlength{\parskip}{#2\baselineskip}
+  \fi
+ }%
+ {}
+\usepackage{calc}
+\newcommand{\CSLBlock}[1]{#1\hfill\break}
+\newcommand{\CSLLeftMargin}[1]{\parbox[t]{\csllabelwidth}{#1}}
+\newcommand{\CSLRightInline}[1]{\parbox[t]{\linewidth - \csllabelwidth}{#1}\break}
+\newcommand{\CSLIndent}[1]{\hspace{\cslhangindent}#1}
+$endif$
+$if(csquotes)$
+\usepackage{csquotes}
+$endif$
+
+$if(title)$
+\title{$title$$if(thanks)$\thanks{$thanks$}$endif$}
+$endif$
+$if(subtitle)$
+$if(beamer)$
+$else$
+\usepackage{etoolbox}
+\makeatletter
+\providecommand{\subtitle}[1]{% add subtitle to \maketitle
+  \apptocmd{\@title}{\par {\large #1 \par}}{}{}
+}
+\makeatother
+$endif$
+\subtitle{$subtitle$}
+$endif$
+\author{$for(author)$$author$$sep$ \and $endfor$}
+\date{$date$}
+$if(beamer)$
+$if(institute)$
+\institute{$for(institute)$$institute$$sep$ \and $endfor$}
+$endif$
+$if(titlegraphic)$
+\titlegraphic{\includegraphics{$titlegraphic$}}
+$endif$
+$if(logo)$
+\logo{\includegraphics{$logo$}}
+$endif$
+$endif$
+
+
+
+%%
+%% added
+%%
+\usepackage[absolute,overlay]{textpos}
+%
+% language specification
+%
+% If no language is specified, use English as the default main document language.
+%
+$if(lang)$$else$
+\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
+  \usepackage[shorthands=off,$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=english]{babel}
+$if(babel-newcommands)$
+  $babel-newcommands$
+$endif$
+\else
+  $if(mainfont)$
+  $else$
+  % Workaround for bug in Polyglossia that breaks `\familydefault` when `\setmainlanguage` is used.
+  % See https://github.com/Wandmalfarbe/pandoc-latex-template/issues/8
+  % See https://github.com/reutenauer/polyglossia/issues/186
+  % See https://github.com/reutenauer/polyglossia/issues/127
+  \renewcommand*\familydefault{\sfdefault}
+  $endif$
+  % load polyglossia as late as possible as it *could* call bidi if RTL lang (e.g. Hebrew or Arabic)
+  \usepackage{polyglossia}
+  \setmainlanguage[]{english}
+$for(polyglossia-otherlangs)$
+  \setotherlanguage[$polyglossia-otherlangs.options$]{$polyglossia-otherlangs.name$}
+$endfor$
+\fi
+$endif$
+
+$if(page-background)$
+\usepackage[pages=all]{background}
+$endif$
+
+%
+% for the background color of the title page
+%
+$if(titlepage)$
+\usepackage{pagecolor}
+\usepackage{afterpage}
+$if(titlepage-background)$
+\usepackage{tikz}
+$endif$
+$if(geometry)$
+$else$
+\usepackage[margin=2.5cm,includehead=true,includefoot=true,centering]{geometry}
+$endif$
+$endif$
+
+%
+% break urls
+%
+\PassOptionsToPackage{hyphens}{url}
+
+%
+% When using babel or polyglossia with biblatex, loading csquotes is recommended
+% to ensure that quoted texts are typeset according to the rules of your main language.
+%
+\usepackage{csquotes}
+
+%
+% captions
+%
+\definecolor{caption-color}{HTML}{777777}
+$if(beamer)$
+$else$
+\usepackage[font={stretch=1.2}, textfont={color=caption-color}, position=top, skip=4mm, labelfont=bf, singlelinecheck=false, justification=$if(caption-justification)$$caption-justification$$else$raggedright$endif$]{caption}
+\setcapindent{0em}
+$endif$
+
+%
+% blockquote
+%
+\definecolor{blockquote-border}{RGB}{221,221,221}
+\definecolor{blockquote-text}{RGB}{119,119,119}
+\usepackage{mdframed}
+\newmdenv[rightline=false,bottomline=false,topline=false,linewidth=3pt,linecolor=blockquote-border,skipabove=\parskip]{customblockquote}
+\renewenvironment{quote}{\begin{customblockquote}\list{}{\rightmargin=0em\leftmargin=0em}%
+\item\relax\color{blockquote-text}\ignorespaces}{\unskip\unskip\endlist\end{customblockquote}}
+
+%
+% Source Sans Pro as the de­fault font fam­ily
+% Source Code Pro for monospace text
+%
+% 'default' option sets the default
+% font family to Source Sans Pro, not \sfdefault.
+%
+\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
+  $if(fontfamily)$
+  $else$
+  \usepackage[default]{sourcesanspro}
+  \usepackage{sourcecodepro}
+  $endif$
+\else % if not pdftex
+  $if(mainfont)$
+  $else$
+  \usepackage[default]{sourcesanspro}
+  \usepackage{sourcecodepro}
+
+  % XeLaTeX specific adjustments for straight quotes: https://tex.stackexchange.com/a/354887
+  % This issue is already fixed (see https://github.com/silkeh/latex-sourcecodepro/pull/5) but the
+  % fix is still unreleased.
+  % TODO: Remove this workaround when the new version of sourcecodepro is released on CTAN.
+  \ifxetex
+    \makeatletter
+    \defaultfontfeatures[\ttfamily]
+      { Numbers   = \sourcecodepro@figurestyle,
+        Scale     = \SourceCodePro@scale,
+        Extension = .otf }
+    \setmonofont
+      [ UprightFont    = *-\sourcecodepro@regstyle,
+        ItalicFont     = *-\sourcecodepro@regstyle It,
+        BoldFont       = *-\sourcecodepro@boldstyle,
+        BoldItalicFont = *-\sourcecodepro@boldstyle It ]
+      {SourceCodePro}
+    \makeatother
+  \fi
+  $endif$
+\fi
+
+%
+% heading color
+%
+\definecolor{heading-color}{RGB}{40,40,40}
+$if(beamer)$
+$else$
+\addtokomafont{section}{\color{heading-color}}
+$endif$
+% When using the classes report, scrreprt, book,
+% scrbook or memoir, uncomment the following line.
+%\addtokomafont{chapter}{\color{heading-color}}
+
+%
+% variables for title, author and date
+%
+$if(beamer)$
+$else$
+\usepackage{titling}
+\title{$title$}
+\author{$for(author)$$author$$sep$, $endfor$}
+\date{$date$}
+$endif$
+
+%
+% tables
+%
+$if(tables)$
+
+\definecolor{table-row-color}{HTML}{F5F5F5}
+\definecolor{table-rule-color}{HTML}{999999}
+
+%\arrayrulecolor{black!40}
+\arrayrulecolor{table-rule-color}     % color of \toprule, \midrule, \bottomrule
+\setlength\heavyrulewidth{0.3ex}      % thickness of \toprule, \bottomrule
+\renewcommand{\arraystretch}{1.3}     % spacing (padding)
+
+$if(table-use-row-colors)$
+% TODO: This doesn't work anymore. I don't know why.
+% Reset rownum counter so that each table
+% starts with the same row colors.
+% https://tex.stackexchange.com/questions/170637/restarting-rowcolors
+%
+% Unfortunately the colored cells extend beyond the edge of the
+% table because pandoc uses @-expressions (@{}) like so:
+%
+% \begin{longtable}[]{@{}ll@{}}
+% \end{longtable}
+%
+% https://en.wikibooks.org/wiki/LaTeX/Tables#.40-expressions
+\let\oldlongtable\longtable
+\let\endoldlongtable\endlongtable
+\renewenvironment{longtable}{
+\rowcolors{3}{}{table-row-color!100}  % row color
+\oldlongtable} {
+\endoldlongtable
+\global\rownum=0\relax}
+$endif$
+$endif$
+
+%
+% remove paragraph indention
+%
+\setlength{\parindent}{0pt}
+\setlength{\parskip}{6pt plus 2pt minus 1pt}
+\setlength{\emergencystretch}{3em}  % prevent overfull lines
+
+%
+%
+% Listings
+%
+%
+
+$if(listings)$
+
+%
+% general listing colors
+%
+\definecolor{listing-background}{HTML}{F7F7F7}
+\definecolor{listing-rule}{HTML}{B3B2B3}
+\definecolor{listing-numbers}{HTML}{B3B2B3}
+\definecolor{listing-text-color}{HTML}{000000}
+\definecolor{listing-keyword}{HTML}{435489}
+\definecolor{listing-keyword-2}{HTML}{1284CA} % additional keywords
+\definecolor{listing-keyword-3}{HTML}{9137CB} % additional keywords
+\definecolor{listing-identifier}{HTML}{435489}
+\definecolor{listing-string}{HTML}{00999A}
+\definecolor{listing-comment}{HTML}{8E8E8E}
+
+\lstdefinestyle{eisvogel_listing_style}{
+  language         = java,
+$if(listings-disable-line-numbers)$
+  xleftmargin      = 0.6em,
+  framexleftmargin = 0.4em,
+$else$
+  numbers          = left,
+  xleftmargin      = 2.7em,
+  framexleftmargin = 2.5em,
+$endif$
+  backgroundcolor  = \color{listing-background},
+  basicstyle       = \color{listing-text-color}\linespread{1.0}$if(code-block-font-size)$$code-block-font-size$$else$\small$endif$\ttfamily{},
+  breaklines       = true,
+  frame            = single,
+  framesep         = 0.19em,
+  rulecolor        = \color{listing-rule},
+  frameround       = ffff,
+  tabsize          = 4,
+  numberstyle      = \color{listing-numbers},
+  aboveskip        = 1.0em,
+  belowskip        = 0.1em,
+  abovecaptionskip = 0em,
+  belowcaptionskip = 1.0em,
+  keywordstyle     = {\color{listing-keyword}\bfseries},
+  keywordstyle     = {[2]\color{listing-keyword-2}\bfseries},
+  keywordstyle     = {[3]\color{listing-keyword-3}\bfseries\itshape},
+  sensitive        = true,
+  identifierstyle  = \color{listing-identifier},
+  commentstyle     = \color{listing-comment},
+  stringstyle      = \color{listing-string},
+  showstringspaces = false,
+  escapeinside     = {/*@}{@*/}, % Allow LaTeX inside these special comments
+  literate         =
+  {á}{{\'a}}1 {é}{{\'e}}1 {í}{{\'i}}1 {ó}{{\'o}}1 {ú}{{\'u}}1
+  {Á}{{\'A}}1 {É}{{\'E}}1 {Í}{{\'I}}1 {Ó}{{\'O}}1 {Ú}{{\'U}}1
+  {à}{{\`a}}1 {è}{{\'e}}1 {ì}{{\`i}}1 {ò}{{\`o}}1 {ù}{{\`u}}1
+  {À}{{\`A}}1 {È}{{\'E}}1 {Ì}{{\`I}}1 {Ò}{{\`O}}1 {Ù}{{\`U}}1
+  {ä}{{\"a}}1 {ë}{{\"e}}1 {ï}{{\"i}}1 {ö}{{\"o}}1 {ü}{{\"u}}1
+  {Ä}{{\"A}}1 {Ë}{{\"E}}1 {Ï}{{\"I}}1 {Ö}{{\"O}}1 {Ü}{{\"U}}1
+  {â}{{\^a}}1 {ê}{{\^e}}1 {î}{{\^i}}1 {ô}{{\^o}}1 {û}{{\^u}}1
+  {Â}{{\^A}}1 {Ê}{{\^E}}1 {Î}{{\^I}}1 {Ô}{{\^O}}1 {Û}{{\^U}}1
+  {œ}{{\oe}}1 {Œ}{{\OE}}1 {æ}{{\ae}}1 {Æ}{{\AE}}1 {ß}{{\ss}}1
+  {ç}{{\c c}}1 {Ç}{{\c C}}1 {ø}{{\o}}1 {å}{{\r a}}1 {Å}{{\r A}}1
+  {€}{{\EUR}}1 {£}{{\pounds}}1 {«}{{\guillemotleft}}1
+  {»}{{\guillemotright}}1 {ñ}{{\~n}}1 {Ñ}{{\~N}}1 {¿}{{?`}}1
+  {…}{{\ldots}}1 {≥}{{>=}}1 {≤}{{<=}}1 {„}{{\glqq}}1 {“}{{\grqq}}1
+  {”}{{''}}1
+}
+\lstset{style=eisvogel_listing_style}
+
+%
+% Java (Java SE 12, 2019-06-22)
+%
+\lstdefinelanguage{Java}{
+  morekeywords={
+    % normal keywords (without data types)
+    abstract,assert,break,case,catch,class,continue,default,
+    do,else,enum,exports,extends,final,finally,for,if,implements,
+    import,instanceof,interface,module,native,new,package,private,
+    protected,public,requires,return,static,strictfp,super,switch,
+    synchronized,this,throw,throws,transient,try,volatile,while,
+    % var is an identifier
+    var
+  },
+  morekeywords={[2] % data types
+    % primitive data types
+    boolean,byte,char,double,float,int,long,short,
+    % String
+    String,
+    % primitive wrapper types
+    Boolean,Byte,Character,Double,Float,Integer,Long,Short
+    % number types
+    Number,AtomicInteger,AtomicLong,BigDecimal,BigInteger,DoubleAccumulator,DoubleAdder,LongAccumulator,LongAdder,Short,
+    % other
+    Object,Void,void
+  },
+  morekeywords={[3] % literals
+    % reserved words for literal values
+    null,true,false,
+  },
+  sensitive,
+  morecomment  = [l]//,
+  morecomment  = [s]{/*}{*/},
+  morecomment  = [s]{/**}{*/},
+  morestring   = [b]",
+  morestring   = [b]',
+}
+
+\lstdefinelanguage{XML}{
+  morestring      = [b]",
+  moredelim       = [s][\bfseries\color{listing-keyword}]{<}{\ },
+  moredelim       = [s][\bfseries\color{listing-keyword}]{</}{>},
+  moredelim       = [l][\bfseries\color{listing-keyword}]{/>},
+  moredelim       = [l][\bfseries\color{listing-keyword}]{>},
+  morecomment     = [s]{<?}{?>},
+  morecomment     = [s]{<!--}{-->},
+  commentstyle    = \color{listing-comment},
+  stringstyle     = \color{listing-string},
+  identifierstyle = \color{listing-identifier}
+}
+$endif$
+
+%
+% header and footer
+%
+$if(beamer)$
+$else$
+$if(disable-header-and-footer)$
+$else$
+\usepackage{fancyhdr}
+
+\fancypagestyle{eisvogel-header-footer}{
+  \fancyhead{}
+  \fancyfoot{}
+  \lhead{$title$}
+  \rhead{$date$}
+  \lfoot{$footer-text$} 
+  \rfoot{\thepage}
+  \renewcommand{\headrulewidth}{0.4pt}
+  \renewcommand{\footrulewidth}{0.4pt}
+}
+\pagestyle{eisvogel-header-footer}
+$if(page-background)$
+\backgroundsetup{
+scale=1,
+color=black,
+opacity=$if(page-background-opacity)$$page-background-opacity$$else$0.2$endif$,
+angle=0,
+contents={%
+  \includegraphics[width=\paperwidth,height=\paperheight]{$page-background$}
+  }%
+}
+$endif$
+$endif$
+$endif$
+
+%%
+%% end added
+%%
+
+
+\usepackage{tikz}
+\newcommand*\circlednumbers[1]{\tikz[baseline=(char.base)]{
+\node[shape=circle,draw,text=white,fill=black,inner sep=2pt] (char) {#1};}}
+
+\usepackage{libertine}
+
+
+
+\begin{document}
+
+%%
+%% begin titlepage
+%%
+$if(beamer)$
+$else$
+$if(titlepage)$
+\begin{titlepage}
+$if(titlepage-background)$
+\newgeometry{top=2cm, right=4cm, bottom=3cm, left=4cm}
+$else$
+\newgeometry{left=6cm}
+$endif$
+$if(titlepage-color)$
+\definecolor{titlepage-color}{HTML}{$titlepage-color$}
+\newpagecolor{titlepage-color}\afterpage{\restorepagecolor}
+$endif$
+$if(titlepage-background)$
+\tikz[remember picture,overlay] \node[inner sep=0pt] at (current page.center){\includegraphics[width=\paperwidth,height=\paperheight]{$titlepage-background$}};
+$endif$
+\newcommand{\colorRule}[3][black]{\textcolor[HTML]{#1}{\rule{#2}{#3}}}
+\begin{flushleft}
+\noindent
+\\[-1em]
+\color[HTML]{$if(titlepage-text-color)$$titlepage-text-color$$else$5F5F5F$endif$}
+\makebox[0pt][l]{\colorRule[$if(titlepage-rule-color)$$titlepage-rule-color$$else$435488$endif$]{1.3\textwidth}{$if(titlepage-rule-height)$$titlepage-rule-height$$else$4$endif$pt}}
+\par
+\noindent
+
+$if(titlepage-background)$
+% The titlepage with a background image has other text spacing and text size
+{
+  \setstretch{2}
+  \vfill
+  \vskip -8em
+  \noindent {\huge \textbf{\textsf{$title$}}}
+  $if(subtitle)$
+  \vskip 1em
+  {\Large \textsf{$subtitle$}}
+  $endif$
+  \vskip 2em
+  \noindent {\Large \textsf{$for(author)$$author$$sep$, $endfor$} \vskip 0.6em \textsf{$date$}}
+  \vfill
+}
+$else$
+{
+  \setstretch{1.4}
+  \vfill
+  \noindent {\huge \textbf{\textsf{$title$}}}
+  $if(subtitle)$
+  \vskip 1em
+  {\Large \textsf{$subtitle$}}
+  $endif$
+  \vskip 2em
+  \noindent {\Large \textsf{$for(author)$$author$$sep$, $endfor$}}
+  \vfill
+}
+$endif$
+
+$if(logo)$
+\noindent
+\includegraphics[width=$if(logo-width)$$logo-width$$else$35mm$endif$, left]{$logo$}
+$endif$
+
+$if(titlepage-background)$
+$else$
+\textsf{$date$}
+$endif$
+\end{flushleft}
+\end{titlepage}
+\restoregeometry
+$endif$
+$endif$
+
+%%
+%% end titlepage
+%%
+
+$if(has-frontmatter)$
+\frontmatter
+$endif$
+$if(title)$
+$if(beamer)$
+\frame{\titlepage}
+$endif$
+$if(abstract)$
+\begin{abstract}
+$abstract$
+\end{abstract}
+$endif$
+$endif$
+
+$if(first-chapter)$
+\setcounter{chapter}{$first-chapter$}
+\addtocounter{chapter}{-1}
+$endif$
+
+$for(include-before)$
+$include-before$
+
+$endfor$
+$if(toc)$
+$if(toc-title)$
+\renewcommand*\contentsname{$toc-title$}
+$endif$
+$if(beamer)$
+\begin{frame}[allowframebreaks]
+$if(toc-title)$
+  \frametitle{$toc-title$}
+$endif$
+  \tableofcontents[hideallsubsections]
+\end{frame}
+$if(toc-own-page)$
+\newpage
+$endif$
+$else$
+{
+$if(colorlinks)$
+\hypersetup{linkcolor=$if(toccolor)$$toccolor$$else$$endif$}
+$endif$
+\setcounter{tocdepth}{$toc-depth$}
+\tableofcontents
+$if(toc-own-page)$
+\newpage
+$endif$
+}
+$endif$
+$endif$
+$if(lot)$
+\listoftables
+$endif$
+$if(lof)$
+\listoffigures
+$endif$
+$if(linestretch)$
+\setstretch{$linestretch$}
+$endif$
+$if(has-frontmatter)$
+\mainmatter
+$endif$
+$body$
+
+$if(has-frontmatter)$
+\backmatter
+$endif$
+$if(natbib)$
+$if(bibliography)$
+$if(biblio-title)$
+$if(has-chapters)$
+\renewcommand\bibname{$biblio-title$}
+$else$
+\renewcommand\refname{$biblio-title$}
+$endif$
+$endif$
+$if(beamer)$
+\begin{frame}[allowframebreaks]{$biblio-title$}
+  \bibliographytrue
+$endif$
+  \bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$}
+$if(beamer)$
+\end{frame}
+$endif$
+
+$endif$
+$endif$
+$if(biblatex)$
+$if(beamer)$
+\begin{frame}[allowframebreaks]{$biblio-title$}
+  \bibliographytrue
+  \printbibliography[heading=none]
+\end{frame}
+$else$
+\printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$
+$endif$
+
+$endif$
+$for(include-after)$
+$include-after$
+
+$endfor$
+\end{document}
diff --git a/development/examples/example1/templates/my.md b/development/examples/example1/templates/my.md
new file mode 100644
index 0000000000000000000000000000000000000000..3d570dd61bd52c7186dfae1abc9b00cc0290e838
--- /dev/null
+++ b/development/examples/example1/templates/my.md
@@ -0,0 +1,37 @@
+---
+title: "Allgemeine Vertragsbedingungen zur Auftragsverarbeitung"
+author: 
+
+keywords: [Auftragsverarbeitung, DSGVO, shopcloud]
+
+subtitle: nach Art. 28 DSGVO durch die schukai GmbH, Eichenstraße 26, 82290 Landsberied im Rahmen der Nutzung der shopcloud
+subject: 
+
+date: 6. Juni 2022
+lang: de
+
+logo: "schukai-weiss-1000-210.png"
+logo-width: "6cm"
+toc-own-page: true
+table-use-row-colors: true
+
+titlepage: true
+titlepage-color: "C10000"
+titlepage-text-color: "FFFFFF"
+titlepage-rule-color: "FFFFFF"
+titlepage-rule-height: 2
+
+footer-text: Vertraulich
+
+
+
+
+
+
+
+...
+
+
+\newpage
+
+{{ .Documents }}
\ No newline at end of file
diff --git a/development/examples/example1/templates/schukai-weiss-1000-210.png b/development/examples/example1/templates/schukai-weiss-1000-210.png
new file mode 100644
index 0000000000000000000000000000000000000000..c6a76eaf936e00d416808e9318c2dec3a6bb8735
Binary files /dev/null and b/development/examples/example1/templates/schukai-weiss-1000-210.png differ
diff --git a/development/examples/example2/imgs/img1.png b/development/examples/example2/imgs/img1.png
new file mode 100644
index 0000000000000000000000000000000000000000..54a9c247e6038bfe0d3183e906c91d7a5952dbf1
Binary files /dev/null and b/development/examples/example2/imgs/img1.png differ
diff --git a/development/examples/example2/newdoc1.md b/development/examples/example2/newdoc1.md
index b03c81805c9ab886c4cc03df3b9cc66fcbb10ba7..6e99f3fd6d3917747792afb0483f57e3248c3de3 100644
--- a/development/examples/example2/newdoc1.md
+++ b/development/examples/example2/newdoc1.md
@@ -14,8 +14,31 @@ Author:
 Created: 06.07.2022
 Last Update: 06.07.2022
 
+
+
 ...
 
+
+
 ## {{ .Title }}
 
-Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+Lorem ipsum dolor sit amet, consectetur [read sub](sub1/doc1.md) adipiscing elit.
+
+--
+HEUTE: <kbd>Ctrl</kbd>+<kbd>ShifT</kbd><kbd>AUTO123$_öäüP</kbd>
+--
+
+<kbd>Leer</kbd> !!
+<kbd>Enter</kbd> !!
+<kbd>Space</kbd> !!
+
+| A | B | C |
+|---|---|---|
+| 1 | 2 | 3 |
+| 4 | 5 | 6 |
+| 4 | 5 | 6 |
+
+
+![](imgs/img1.png)
+
+
diff --git a/development/examples/example2/newdow2.md b/development/examples/example2/newdoc2.md
similarity index 72%
rename from development/examples/example2/newdow2.md
rename to development/examples/example2/newdoc2.md
index b03c81805c9ab886c4cc03df3b9cc66fcbb10ba7..b24c1f7759af2d3aedbf2e7ef118de09abb779e8 100644
--- a/development/examples/example2/newdow2.md
+++ b/development/examples/example2/newdoc2.md
@@ -16,6 +16,13 @@ Last Update: 06.07.2022
 
 ...
 
-## {{ .Title }}
 
+
+## {{ .Title }} 
 Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+➊ ➋ ➌ ➍ ➎ ➏ ➐ ➑ ➒ ➓ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴
+
+
+DOC 2
+
diff --git a/development/examples/example2/newdoc3.md b/development/examples/example2/newdoc3.md
index b03c81805c9ab886c4cc03df3b9cc66fcbb10ba7..9dd0727da321daca44479ccdd83dd28541c30342 100644
--- a/development/examples/example2/newdoc3.md
+++ b/development/examples/example2/newdoc3.md
@@ -18,4 +18,8 @@ Last Update: 06.07.2022
 
 ## {{ .Title }}
 
+
 Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+
+DOC 3
\ No newline at end of file
diff --git a/development/examples/example2/sub1/doc1.md b/development/examples/example2/sub1/doc1.md
new file mode 100644
index 0000000000000000000000000000000000000000..932ae24ae59ae2312b4248aff27462de45214698
--- /dev/null
+++ b/development/examples/example2/sub1/doc1.md
@@ -0,0 +1,5 @@
+
+
+
+
+### SUB 1
\ No newline at end of file
diff --git a/development/temp/config.go b/development/temp/config.go
index abacd27af9be0919fcebf8aee1c0f46e071a5d92..253813191496570ff54df8aedbe8bce6e6666b30 100644
--- a/development/temp/config.go
+++ b/development/temp/config.go
@@ -4,8 +4,6 @@ import (
 	"os"
 	"os/user"
 	"path"
-
-	"gopkg.in/yaml.v2"
 )
 
 type configPathsStruct struct {
@@ -23,7 +21,7 @@ var (
 
 // Configuration
 type Configuration struct {
-	Path string `yaml:"Path"`
+	Path string `yaml:"SourcePath"`
 
 	Locale struct {
 		DateFormat string `yaml:"DateFormat"`