aboutsummaryrefslogtreecommitdiffstats
path: root/config/doom
diff options
context:
space:
mode:
Diffstat (limited to 'config/doom')
-rw-r--r--config/doom/config.org230
-rw-r--r--config/doom/init.el21
-rw-r--r--config/doom/snippets/notmuch-message-mode/isar-guest30
-rw-r--r--config/doom/snippets/notmuch-message-mode/nbg-guest41
-rw-r--r--config/doom/snippets/notmuch-message-mode/nbg-membership105
5 files changed, 339 insertions, 88 deletions
diff --git a/config/doom/config.org b/config/doom/config.org
index 577f1f9..339dc73 100644
--- a/config/doom/config.org
+++ b/config/doom/config.org
@@ -28,11 +28,6 @@
(add-hook 'prog-mode-hook 'on/prettify-symbols)
#+end_src
-This determines the style of line numbers in effect. If set to `nil', line
-numbers are disabled. For relative line numbers, set this to `relative'.
-#+begin_src emacs-lisp
-;(setq display-line-numbers-type 'relative)
-#+end_src
** Frame title includes visited file
#+BEGIN_SRC emacs-lisp
;;http://emacs-fu.blogspot.fr/2011/01/setting-frame-title.html
@@ -41,15 +36,6 @@ numbers are disabled. For relative line numbers, set this to `relative'.
(abbreviate-file-name (buffer-file-name))
"%b"))))
#+END_SRC
-** Keybindings
-#+begin_src emacs-lisp
-(map! :leader
- :desc "M-x" "x" #'execute-extended-command
- )
-(after! evil
- (setq evil-default-state 'emacs)
- (set-evil-initial-state! '(prog-mode text-mode fundamental-mode conf-mode pass-view-mode) 'normal))
-#+end_src
** Package Manager
Doom manages packages separately. Keep that file separate
#+begin_src emacs-lisp :tangle "packages.el"
@@ -60,6 +46,35 @@ Doom manages packages separately. Keep that file separate
#+begin_src emacs-lisp
(setenv "SSH_AUTH_SOCK" (concat (getenv "XDG_RUNTIME_DIR")"/gnupg/S.gpg-agent.ssh"))
#+end_src
+** Auth mechanisms
+#+begin_src emacs-lisp :tangle "packages.el"
+(package! pass)
+(package! password-store)
+(package! password-store-otp)
+#+end_src
+
+#+begin_src emacs-lisp
+(use-package! pass
+ :init
+ (require 'auth-source)
+ (auth-source-pass-enable)
+ (defun on/fetch-password (&rest params)
+ (if-let* ((match (car (apply #'auth-source-search params)))
+ (secret (plist-get match :secret)))
+ (if (functionp secret)
+ (funcall secret)
+ secret)
+ (user-error "Password not found for %S" params))))
+#+end_src
+** Keybindings
+#+begin_src emacs-lisp
+;; (map! :leader
+;; :desc "M-x" "x" #'execute-extended-command
+;; )
+(after! evil
+ (setq evil-default-state 'emacs)
+ (set-evil-initial-state! '(prog-mode text-mode fundamental-mode conf-mode pass-view-mode) 'normal))
+#+end_src
** Avy
This allows me to jump to buffer positions using my home row ordering
#+begin_src emacs-lisp
@@ -71,7 +86,6 @@ This allows me to jump to buffer positions using my home row ordering
** Ace window
#+begin_src emacs-lisp
(after! ace-window
- (global-set-key (kbd "s-w") 'evil-window-map)
(setq aw-keys '(?r ?t ?i ?e ?a ?o ?n ?s)))
#+end_src
** Which-key
@@ -107,6 +121,20 @@ Because I always need help and it should come up quickly
#+begin_src emacs-lisp
(add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p)
#+end_src
+** AI queries
+#+begin_src emacs-lisp
+(use-package! ai-query
+ :load-path "~/dev/dotfiles/elisp/"
+ :commands (ai-query-request))
+#+end_src
+
+** Track Deliveries
+#+begin_src emacs-lisp
+(use-package! delivery-track
+ :load-path "~/dev/dotfiles/elisp/"
+ :commands (delivery-track-update-dhl))
+#+end_src
+
* Dictionary
#+begin_src emacs-lisp :tangle "packages.el"
(package! lexic)
@@ -126,6 +154,24 @@ Shamelessly copied from https://tecosaur.github.io/emacs-config/#dictionary
current-prefix-arg))
(lexic-search identifier nil nil t))
#+end_src
+** Shavian transliterate
+#+begin_src emacs-lisp
+(defun on/shavian-transliterate (start end)
+ "Convert text from START to END to Shavian in new buffer."
+ (interactive "r")
+ (let ((buffer (get-buffer-create "*shavian translit*")))
+ (with-current-buffer buffer
+ (erase-buffer))
+ (call-process-region
+ start end
+ (expand-file-name ".virtualenvs/shavian/bin/python" "~/")
+ nil buffer nil
+ (expand-file-name "dev/readlex/latin2shaw.py" "~/"))
+ (with-current-buffer buffer
+ (text-mode)
+ (display-buffer buffer))))
+
+#+end_src
* Orgmode
#+begin_src emacs-lisp
(after! org
@@ -139,6 +185,15 @@ Shamelessly copied from https://tecosaur.github.io/emacs-config/#dictionary
`("e" "Event" entry (file ,(expand-file-name
"caldav.org" org-directory))
"* %?\n%^T\n%i\n%a"))
+ (add-to-list 'org-capture-templates
+ `("m" "NBG-TM Contact" entry
+ (file+headline ,(expand-file-name "toastmasters/NBG-membership.org" org-directory) "Guest")
+ "* INTRS [[notmuch-search:%:reply-to][%:fromname]]
+:PROPERTIES:
+:EMAIL: %:reply-to
+:END:
+Invited: %^t
+"))
(setq org-roam-capture-templates '(("d" "default" plain "%i\n%?"
:target (file+head "%<%Y%m%d%H%M%S>-${slug}.org"
@@ -185,8 +240,10 @@ this new window.
(call-process "org_agenda_sync"
nil (list :file (expand-file-name "~/org/caldav.org")) nil
"--format" "org"))
- (setq cal-sync-url "https://oscar@cloud.oscarnajera.com/remote.php/dav/calendars/oscar"
- cal-sync-calendar-id "personal-1"
+ (setq cal-sync-connection
+ (cal-sync-calendar-create
+ "https://cloud.oscarnajera.com/remote.php/dav/calendars/oscar/personal-1/"
+ "oscar" "~/org/caldav.org")
org-icalendar-date-time-format ":%Y%m%dT%H%M%SZ"))
#+end_src
** References
@@ -247,6 +304,7 @@ this new window.
"http://feeds.feedburner.com/TroyHunt"
"http://kitchingroup.cheme.cmu.edu/blog/feed/index.xml"
"http://www.howardism.org/index.xml"
+ "https://www.reddit.com/r/Common_Lisp/.rss"
"https://ag91.github.io/rss.xml"
"https://architectelevator.com/feed.xml"
"https://bitcoinops.org/feed.xml"
@@ -273,7 +331,7 @@ this new window.
#+begin_src emacs-lisp :tangle "packages.el"
(package! notmuch :pin "c769658360e10a6d01a4134e680e2f498741bc5c")
(package! org-mime :pin "cc00afcf0291633324364c1c83bfe2833cfdc1bf")
-(package! ol-notmuch :pin "781c3518a537da2a8b5e8a4424f9441df463a147")
+(package! ol-notmuch :pin "2704345ac8c4558c7c787d2ea0a4777607789a62")
#+end_src
#+BEGIN_SRC emacs-lisp
(use-package! notmuch
@@ -310,7 +368,7 @@ this new window.
(:name "Isar-Speak" :query "(tag:Isar-Speak or tag:lists/isar-speak-officers) and tag:unread" :key "t")
(:name "flagged" :query "tag:flagged" :key "f")
(:name "sent" :query "tag:sent" :key "s")
- (:name "unread" :query "tag:unread" :key "u")
+ (:name "unread" :query "tag:unread and not tag:fail2ban and not tag:Checkm-Alerts" :key "u")
(:name "drafts" :query "tag:draft" :key "d")))
(setq notmuch-show-all-tags-list t
@@ -407,12 +465,9 @@ this new window.
"Read mbsync config to extract IMAPAccounts."
(with-temp-buffer
(insert-file-contents (expand-file-name "~/.mbsyncrc"))
- (let ((pick (thread-last
- (cl-loop while (search-forward-regexp (rx bol "IMAPAccount " (group (+ any)) eol) nil t)
- collect (match-string 1))
- (cons "all")
- (completing-read "Which mailbox"))))
- (if (string= pick "all") nil (list pick)))))
+ (cl-loop while (search-forward-regexp (rx bol "IMAPAccount " (group (+ any)) eol) nil t)
+ collect (match-string 1))))
+
(define-derived-mode mail-sync-log-mode comint-mode "mail-sync-log"
"Major mode for reading mail sync."
@@ -421,16 +476,21 @@ this new window.
(,(rx bol " [mv]") . font-lock-constant-face)
(,(rx bol " [rm]") . font-lock-keyword-face)))))
-(defun on/fetch-all-email ()
- "Start tagmail fetch on a subprocess."
- (interactive)
+(defun on/fetch-all-email (mailbox)
+ "Start tagmail fetch on a subprocess for MAILBOX."
+ (interactive (list (completing-read
+ "Which mailbox? "
+ (on/registered-mail-accounts)
+ nil nil nil nil "all")))
(with-current-buffer (get-buffer-create "*E-mail fetch*")
(pop-to-buffer (current-buffer))
(mail-sync-log-mode)
(make-process
:name "E-mail fetch"
:buffer (current-buffer)
- :command (cons "tagmail" (on/registered-mail-accounts))
+ :command (thread-last
+ (if (string= mailbox "all") nil (list mailbox))
+ (cons "tagmail"))
:filter #'comint-output-filter)))
#+END_SRC
** Sending email
@@ -449,6 +509,7 @@ this new window.
(string-split "@")))
(smtp-servers '("oscarnajera.com" "mail.oscarnajera.com"
"gmail.com" "smtp.googlemail.com"
+ "googlemail.com" "smtp.googlemail.com"
"byteplant.com" "smtp.byteplant.com"))
((&plist :host :user :port :secret)
(car
@@ -471,21 +532,27 @@ this new window.
(package! khardel)
#+end_src
#+begin_src emacs-lisp
-(use-package! khardel)
+(use-package! khardel
+ :config
+ (after! tree-sitter-langs
+ (add-to-list 'tree-sitter-major-mode-language-alist '(khardel-edit-mode . yaml)))
+ (add-hook 'khardel-edit-mode-hook
+ (lambda ()
+ (tree-sitter-mode)
+ (setq imenu-create-index-function #'on/imenu-nested-path-elements))))
#+end_src
* IRC
#+begin_src emacs-lisp
-(set-irc-server! "irc.libera.chat"
- `(:tls t
- :port 6697
- :nick "titan-c"
- :sasl-username ,(+pass-get-user "Social/freenode/titan-c")
- :sasl-password (lambda (&rest _) (+pass-get-secret "Social/freenode/titan-c"))
- :channels ("#emacs" "#guix")))
+(after! circe
+ (set-irc-server! "irc.libera.chat"
+ '(:tls t
+ :port 6697
+ :nick "titan-c"
+ :sasl-username "titan-c"
+ :sasl-password (lambda (&rest _) (on/fetch-password :user "titan-c" :host "freenode"))
+ :channels ("#emacs" "#guix"))))
#+end_src
-#+RESULTS:
-
* Ledger
Emacs mode for managing ledger text files
#+BEGIN_SRC emacs-lisp
@@ -574,13 +641,83 @@ Emacs mode for managing ledger text files
:load-path "~/dev/emacs-lisp/emacs-libyaml/")
(use-package! yaml)
-#+end_src
-** Databases
-#+begin_src emacs-lisp :tangle "packages.el"
-(package! emacsql-psql)
+(after! yaml-mode
+ ;; Inspired by this blog post to use tree sitter to create a imenu list.
+ ;; https://blog.meain.io/2022/navigating-config-files-using-tree-sitter/
+ (defun on/ts-elements ()
+ "Tree sitter matches for all entries in data buffer."
+ (let ((query (thread-last
+ (cond
+ ((derived-mode-p 'json-mode)
+ "(object (pair (string (string_content) @key) (_)) @item)")
+ ((derived-mode-p 'yaml-mode)
+ "(block_mapping_pair (flow_node) @key (_)) @item"))
+ (tsc-make-query tree-sitter-language)))
+ (root-node (tsc-root-node tree-sitter-tree)))
+ (tsc-query-matches query root-node #'tsc--buffer-substring-no-properties)))
+
+ (defun on/pos-items (ts-match)
+ "From a TS-MATCH get element key name and region in buffer."
+ (pcase-let ((`[(_ . ,item) (_ . ,key)] (cdr ts-match)))
+ (list
+ (tsc-node-text key)
+ (tsc-node-byte-range item)
+ ;; (destructuring-bind (s . e) (tsc-node-byte-range key)
+ ;; (cons (byte-to-position s) (byte-to-position e)))
+ )))
+
+ (defun on/nested-item-names (items)
+ "From named ITEMS figure out the nested hierarchy for names."
+ (let ((node-stack '(("" 0)))
+ result)
+ (dolist (item items (nreverse result))
+ (pcase-let ((`(,item-name (,item-start . ,item-end)) item)
+ (`((_ ,parent-end)) node-stack))
+ (when (< parent-end item-end)
+ (setq node-stack (seq-filter (lambda (y)
+ (<= item-end (cadr y)))
+ node-stack)))
+ (push (list item-name item-end) node-stack)
+ (push (list (nreverse (mapcar #'car node-stack))
+ item-start)
+ result)))))
+
+ (defun on/imenu-nested-path-elements ()
+ "On a yaml or json buffer get the element positions for imenu."
+ (thread-last
+ (seq-map #'on/pos-items (on/ts-elements))
+ (on/nested-item-names)
+ (seq-map (lambda (item)
+ (seq-let (name-chain start) item
+ (cons (string-join name-chain ".") (byte-to-position start)))))))
+
+ (remove-hook 'yaml-mode-hook 'yaml-set-imenu-generic-expression) ;; don't use default one
+ (add-hook 'yaml-mode-hook
+ (lambda ()
+ (setq imenu-create-index-function #'on/imenu-nested-path-elements)))
+
+ (ert-deftest on/tree-sitter-imenu ()
+ "Test the imenu generation."
+ (with-temp-buffer
+ (yaml-mode)
+ (tree-sitter-mode)
+ (insert "one: Ñaño
+skills:
+ run: 3
+ jump:
+ high: 7
+ low: 2
+
+")
+ (should
+ (equal '(("one" . 1) ("skills" . 13) ("skills.run" . 23) ("skills.jump" . 32) ("skills.jump.high" . 43) ("skills.jump.low" . 55))
+ (on/imenu-nested-path-elements)))
+ ))
+ )
#+end_src
+** Databases
#+begin_src emacs-lisp
(after! format-all
(define-format-all-formatter sqlformat
@@ -676,15 +813,12 @@ Emacs mode for managing ledger text files
(user "crazy")
(port (plist-get networks
(intern (completing-read "Pick network: " networks))))
- (secret (-some->
- (auth-source-search :host host)
- (car)
- (plist-get :secret))))
+ (secret (on/fetch-password :host host)))
(when (and btc-explorer-bitcoind
(json-rpc-live-p btc-explorer-bitcoind))
(json-rpc-close btc-explorer-bitcoind))
(setq btc-explorer-bitcoind
- (json-rpc-connect host port user (funcall secret))))))
+ (json-rpc-connect host port user secret)))))
(use-package! lnd
:load-path "~/dev/emacs-lisp/btc-explorer/"
diff --git a/config/doom/init.el b/config/doom/init.el
index cd9d65d..7394840 100644
--- a/config/doom/init.el
+++ b/config/doom/init.el
@@ -22,17 +22,18 @@
:completion
company ; the ultimate code completion backend
+ ;; (corfu +orderless) ; complete with cap(f), cape and a flying feather!
;; helm ; the *other* search engine for love and life
- ;;ido ; the other *other* search engine...
- ivy ; a search engine for love and life
- ;; vertico ; the search engine of the future
+ ;; ido ; the other *other* search engine...
+ ;; ivy ; a search engine for love and life
+ vertico ; the search engine of the future
:ui
;;deft ; notational velocity for Emacs
doom ; what makes DOOM look the way it does
;; doom-dashboard ; a nifty splash screen for Emacs
;;doom-quit ; DOOM quit-message prompts when you quit Emacs
- ;;(emoji +unicode) ; 🙂
+ (emoji +unicode) ; 🙂
hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
;;hydra
;;indent-guides ; highlighted indent columns
@@ -45,7 +46,7 @@
(popup +defaults) ; tame sudden yet inevitable temporary windows
;;tabs ; a tab bar for Emacs
;;treemacs ; a project drawer, like neotree but cooler
- ;;unicode ; extended unicode support for various languages
+ unicode ; extended unicode support for various languages
vc-gutter ; vcs diff in the fringe
vi-tilde-fringe ; fringe tildes to mark beyond EOB
window-select ; visually switch windows
@@ -98,7 +99,7 @@
lsp
magit ; a git porcelain for Emacs
;;make ; run make tasks from Emacs
- (pass +auth) ; password manager for nerds
+ ;; (pass +auth) ; password manager for nerds
pdf ; pdf enhancements
;;prodigy ; FIXME managing external services & code builders
;;rgb ; creating color strings
@@ -109,7 +110,7 @@
;;upload ; map local to remote projects via ssh/ftp
:os
- (:if IS-MAC macos) ; improve compatibility with macOS
+ (:if (featurep :system 'macos) macos) ; improve compatibility with macOS
;;tty ; improve the terminal Emacs experience
:lang
@@ -154,7 +155,7 @@
nix ; I hereby declare "nix geht mehr!"
;;ocaml ; an objective camel
(org +roam2 +hugo +present +gnuplot +pomodoro) ; organize your plain life in plain text
- ;;php ; perl's insecure younger brother
+ php ; perl's insecure younger brother
;;plantuml ; diagrams for confusing people more
;;purescript ; javascript, but functional
(python +lsp +ipython +pyright +tree-sitter) ; beautiful is better than ugly
@@ -172,8 +173,8 @@
;;solidity ; do you need a blockchain? No.
;;swift ; who asked for emoji variables?
;;terra ; Earth and Moon in alignment for performance.
- (web +lsp +tree-sitter) ; the tubes
- yaml ; JSON, but readable
+ (web +lsp +tree-sitter) ; the tubes
+ (yaml +lsp +tree-sitter) ; JSON, but readable
;;zig ; C, but simpler
:email
diff --git a/config/doom/snippets/notmuch-message-mode/isar-guest b/config/doom/snippets/notmuch-message-mode/isar-guest
deleted file mode 100644
index 84a82d2..0000000
--- a/config/doom/snippets/notmuch-message-mode/isar-guest
+++ /dev/null
@@ -1,30 +0,0 @@
-# -*- mode: snippet -*-
-# name: isar-guest
-# key: isar-guest
-# --
-Dear ${1:`(-> (message-fetch-field "to") (mail-extract-address-components) (car))`},
-
-Feel free to join us in our next meeting on ${2:MeetingDate}.
-
-Our next meeting takes place in hybrid setup in our venue at.
-
-Freiraum
-Saarstr. 5
-80797 Munich
-
-Or online
-http://us02web.zoom.us/j/84234647483
-
-Meeting starts at 19:00 CEST. If you come onsite, please plan
-your time accordingly to find the venue. We are already there 30min
-earlier to setup the room. Online: dial-in just in time.
-
-Looking forward to seeing you.
-
-Cheers,
-Oscar
-
-PS: Our club currently organizes joint meetings with the Munich Prostmasters
-club. In this way we obtain a high member participation during the meetings.
-Once membership growings to pre-COVID levels both clubs will return to run
-independently.
diff --git a/config/doom/snippets/notmuch-message-mode/nbg-guest b/config/doom/snippets/notmuch-message-mode/nbg-guest
new file mode 100644
index 0000000..b3131d6
--- /dev/null
+++ b/config/doom/snippets/notmuch-message-mode/nbg-guest
@@ -0,0 +1,41 @@
+# -*- mode: snippet -*-
+# name: nbg-guest
+# key: nbg-guest
+# --
+Dear ${1:`(-> (message-fetch-field "to") (mail-extract-address-components) (car))`},
+
+Glad to hear you are interested in our Toastmasters club. You can always attend our meetings as guest to see if this club is beneficial for you.
+
+Feel free to join us in our next meeting on Monday, ${2:MeetingDate} @ 19:00 CEST.
+
+We will meet at:
+
+DAI
+Gleißbühlstraße 9
+90402 Nuremberg
+
+If you like, I can also add you to our guest list so you always get an invite before the next meeting.
+
+Our meetings normally begin with a warm up section that includes an impromptu speech session where guests can also participate. Then we have two to four prepared speeches. Finally, there is the speech and meeting evaluations that give us feedback on what we can improve and more importantly, what was done well.
+
+There is no cost for coming as guest. To participate fully, give prepared speeches, and profit from Toastmasters learning materials, you need to become a member though. There is a one-time registration fee of 25€ and a monthly cost of 15€ that is paid in advance by you for a six month period, though when you join you only pay the remaining months until the next renewal period (these start in October and April).
+
+You'll find more information in our 2 page pdf under this link:
+
+https://drive.google.com/file/d/1IwSBHFqNUaNJKBF9wmhXtPjbC3r7mEel/view?usp=sharing
+
+Feel free to come back to me should you have any more questions.
+
+Kind regards
+Oscar
+VP Membership
+Nuremberg Toastmasters Club
+
+Club 00008040, Area 4, Division D, District 95
+Join us at 7pm every 1st & 3rd Monday of the month
+DAI, Gleißbühlstr. 9, 90402 Nuremberg
+
+www.nuremberg-toastmasters.de
+
+This message was sent to you because you have provided us with your e-mail address.
+If you no longer wish to receive emails from Nuremberg Toastmasters, please reply to this email with "unsubscribe".
diff --git a/config/doom/snippets/notmuch-message-mode/nbg-membership b/config/doom/snippets/notmuch-message-mode/nbg-membership
new file mode 100644
index 0000000..96c3b89
--- /dev/null
+++ b/config/doom/snippets/notmuch-message-mode/nbg-membership
@@ -0,0 +1,105 @@
+# -*- mode: snippet -*-
+# name: nbg-membership
+# key: nbg-membership
+# --
+Dear ${1:`(-> (message-fetch-field "to") (mail-extract-address-components) (car))`},
+
+${2:some context of how we met}
+
+The simple version to membership is:
+
+- Money:
+
+The club collects a monthly membership fee of 15 €. We pay it in 6
+months intervals, for the periods October-March and April-September at
+90 € each. When you join as a new member, you only pay for the months
+until the next period begin, in your case would you join in August, you
+would pay 30 €, for August-September.
+
+There is a one time registration fee of 25 €, to register you with
+Toastmasters International. That registration is life-long and world
+wide valid. Were you to join other clubs in other cities, or countries
+later on in life. You would only need to pay that club's corresponding
+fees, and skip the new member fee.
+
+- Bureaucracy:
+
+You need to fill the membership form, and send it back to me. I have
+pre-filled some fields regarding the club, and its fees. Don't worry
+about page 3: Payment Information. We don't take your money, you send us
+your membership fees via bank transfer to the club treasurer.
+
+The bank details are as follows:
+Bank Name: Raiffeisenbank im Nürnberger Land eG
+Account Holder Name: Nuremberg Toastmasters
+IBAN: DE35 7606 1482 0004 3987 26
+Please include your full name and "TM Membership" in the payment reference.
+
+Once that is cleared with the treasurer. You get 2 online accounts. One
+for Toastmaster International, where you keep track of your learning
+path and your public speaking manuals(called Pathways). And one for
+EasySpeak which is the system we use to organize each of the club
+meeting roles.
+
+If you want to join as a member at a later time(like September, October,
+etc) it is OK, mention it on the membership form, do the corresponding
+math to calculate your fee and pay.
+
+You don't have a membership contract with the club, no german 2-year
+contract. We don't charge your bank account for the membership fees. You
+have to send us the money every half year to remain a member. If you
+stop, your membership runs out. If you change cities and join other
+club, you just worry about their membership, ours will run out. You
+don't need to cancel anything with us.
+
+If you want to join more than one club, maybe for more practice ours.
+You will have to pay the fees of each club.
+
+- Where does the money go?
+
+Most of your membership fee goes directly to Toastmaster International,
+to give you access to the "franchise", and all the learning material on
+their website as your individual learning program (the manuals called
+pathways). You also need to be a registered member to participate at the
+Speech contests and conferences.
+
+A second chunk goes to pay the German VAT,(Umsatzsteuer) that the German
+Government forces Toastmasters International(TMI) to collect on the
+membership fees they request. It didn't use to be like that, because we
+are all simple volunteer organizations, and TMI is a US non-profit. But
+since last year it became a point of "discussion" among all german clubs
+and other concerned parties, and now became mandatory since July this
+year, even for the german toastmasters clubs that are e.V.
+
+The remaining money is to pay for club expenses, like the venue, those
+simple drinks and snacks offered at the end of the meeting and whatever
+else that we might need. The rest of the benefits are part of the club
+life and we are a volunteer organization.
+
+- Final considerations:
+
+I consider that joining a club(any kind) requires a life style change.
+You have to take time to go to the club, practice whatever it offers, at
+the club and by yourself and you have to deal with the people in the
+club. For that you should choose somewhere that is most compatible with
+your lifestyle.
+
+Toastmasters International is a global "franchise". In the Nürnberg area
+there are some other clubs.
+
+Noris Toastmasters Nuremberg www.noris-toastmasters.de
+Bamberg Toastmasters Bamberg www.bamberg-toastmasters.de
+Erlangen Toastmasters Erlangen www.erlangen-toastmasters.de
+Nürnberger Rhetoriker Nuremberg www.nuernberger-rhetoriker.de
+(German speaking club)
+
+If you haven't, you should give them a try. Maybe you like their venue,
+meeting schedule or people better. Or maybe not and you'll be happier
+with us, in which case we'll be happy to have you as a member.
+
+Feel free to contact me if you have any further questions.
+
+Best regards,
+Óscar
+VP Membership
+Nuremberg Toastmasters Club \ No newline at end of file